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>
7 * matroska-read-common.c: shared by matroska file/stream demuxer and parser
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.
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.
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., 59 Temple Place - Suite 330,
22 * Boston, MA 02111-1307, USA.
40 #include <gst/tag/tag.h>
41 #include <gst/base/gsttypefindhelper.h>
45 #include "ebml-read.h"
46 #include "matroska-read-common.h"
48 GST_DEBUG_CATEGORY (matroskareadcommon_debug);
49 #define GST_CAT_DEFAULT matroskareadcommon_debug
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))
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))
59 #define GST_MATROSKA_TOC_UID_CHAPTER "chapter"
60 #define GST_MATROSKA_TOC_UID_EDITION "edition"
61 #define GST_MATROSKA_TOC_UID_EMPTY "empty"
64 gst_matroska_decompress_data (GstMatroskaTrackEncoding * enc,
65 gpointer * data_out, gsize * size_out,
66 GstMatroskaTrackCompressionAlgorithm algo)
68 guint8 *new_data = NULL;
70 guint8 *data = *data_out;
71 guint size = *size_out;
74 if (algo == GST_MATROSKA_TRACK_COMPRESSION_ALGORITHM_ZLIB) {
76 /* zlib encoded data */
82 zstream.zalloc = (alloc_func) 0;
83 zstream.zfree = (free_func) 0;
84 zstream.opaque = (voidpf) 0;
85 if (inflateInit (&zstream) != Z_OK) {
86 GST_WARNING ("zlib initialization failed.");
90 zstream.next_in = (Bytef *) data;
91 zstream.avail_in = orig_size;
93 new_data = g_malloc (new_size);
94 zstream.avail_out = new_size;
95 zstream.next_out = (Bytef *) new_data;
98 result = inflate (&zstream, Z_NO_FLUSH);
99 if (result != Z_OK && result != Z_STREAM_END) {
100 GST_WARNING ("zlib decompression failed.");
102 inflateEnd (&zstream);
106 new_data = g_realloc (new_data, new_size);
107 zstream.next_out = (Bytef *) (new_data + zstream.total_out);
108 zstream.avail_out += 4000;
109 } while (zstream.avail_in != 0 && result != Z_STREAM_END);
111 if (result != Z_STREAM_END) {
115 new_size = zstream.total_out;
116 inflateEnd (&zstream);
119 GST_WARNING ("zlib encoded tracks not supported.");
123 } else if (algo == GST_MATROSKA_TRACK_COMPRESSION_ALGORITHM_BZLIB) {
125 /* bzip2 encoded data */
130 bzstream.bzalloc = NULL;
131 bzstream.bzfree = NULL;
132 bzstream.opaque = NULL;
135 if (BZ2_bzDecompressInit (&bzstream, 0, 0) != BZ_OK) {
136 GST_WARNING ("bzip2 initialization failed.");
141 bzstream.next_in = (char *) data;
142 bzstream.avail_in = orig_size;
143 new_size = orig_size;
144 new_data = g_malloc (new_size);
145 bzstream.avail_out = new_size;
146 bzstream.next_out = (char *) new_data;
149 result = BZ2_bzDecompress (&bzstream);
150 if (result != BZ_OK && result != BZ_STREAM_END) {
151 GST_WARNING ("bzip2 decompression failed.");
153 BZ2_bzDecompressEnd (&bzstream);
157 new_data = g_realloc (new_data, new_size);
158 bzstream.next_out = (char *) (new_data + bzstream.total_out_lo32);
159 bzstream.avail_out += 4000;
160 } while (bzstream.avail_in != 0 && result != BZ_STREAM_END);
162 if (result != BZ_STREAM_END) {
166 new_size = bzstream.total_out_lo32;
167 BZ2_bzDecompressEnd (&bzstream);
170 GST_WARNING ("bzip2 encoded tracks not supported.");
174 } else if (algo == GST_MATROSKA_TRACK_COMPRESSION_ALGORITHM_LZO1X) {
175 /* lzo encoded data */
177 int orig_size, out_size;
182 new_data = g_malloc (new_size);
188 result = lzo1x_decode (new_data, &out_size, data, &orig_size);
192 new_data = g_realloc (new_data, new_size);
194 } while (orig_size > 0 && result == LZO_OUTPUT_FULL);
196 new_size -= out_size;
198 if (result != LZO_OUTPUT_FULL) {
199 GST_WARNING ("lzo decompression failed");
206 } else if (algo == GST_MATROSKA_TRACK_COMPRESSION_ALGORITHM_HEADERSTRIP) {
207 /* header stripped encoded data */
208 if (enc->comp_settings_length > 0) {
209 new_data = g_malloc (size + enc->comp_settings_length);
210 new_size = size + enc->comp_settings_length;
212 memcpy (new_data, enc->comp_settings, enc->comp_settings_length);
213 memcpy (new_data + enc->comp_settings_length, data, size);
216 GST_ERROR ("invalid compression algorithm %d", algo);
226 *data_out = new_data;
227 *size_out = new_size;
234 gst_matroska_decode_content_encodings (GArray * encodings)
238 if (encodings == NULL)
241 for (i = 0; i < encodings->len; i++) {
242 GstMatroskaTrackEncoding *enc =
243 &g_array_index (encodings, GstMatroskaTrackEncoding, i);
244 gpointer data = NULL;
247 if ((enc->scope & GST_MATROSKA_TRACK_ENCODING_SCOPE_NEXT_CONTENT_ENCODING)
251 /* Encryption not supported yet */
253 return GST_FLOW_ERROR;
255 if (i + 1 >= encodings->len)
256 return GST_FLOW_ERROR;
258 if (enc->comp_settings_length == 0)
261 data = enc->comp_settings;
262 size = enc->comp_settings_length;
264 if (!gst_matroska_decompress_data (enc, &data, &size, enc->comp_algo))
265 return GST_FLOW_ERROR;
267 g_free (enc->comp_settings);
269 enc->comp_settings = data;
270 enc->comp_settings_length = size;
277 gst_matroska_decode_data (GArray * encodings, gpointer * data_out,
278 gsize * size_out, GstMatroskaTrackEncodingScope scope, gboolean free)
285 g_return_val_if_fail (encodings != NULL, FALSE);
286 g_return_val_if_fail (data_out != NULL && *data_out != NULL, FALSE);
287 g_return_val_if_fail (size_out != NULL, FALSE);
292 for (i = 0; i < encodings->len; i++) {
293 GstMatroskaTrackEncoding *enc =
294 &g_array_index (encodings, GstMatroskaTrackEncoding, i);
295 gpointer new_data = NULL;
298 if ((enc->scope & scope) == 0)
301 /* Encryption not supported yet */
302 if (enc->type != 0) {
311 gst_matroska_decompress_data (enc, &new_data, &new_size,
317 if ((data == *data_out && free) || (data != *data_out))
325 if ((data == *data_out && free) || (data != *data_out))
339 gst_matroska_index_compare (GstMatroskaIndex * i1, GstMatroskaIndex * i2)
341 if (i1->time < i2->time)
343 else if (i1->time > i2->time)
345 else if (i1->block < i2->block)
347 else if (i1->block > i2->block)
354 gst_matroska_index_seek_find (GstMatroskaIndex * i1, GstClockTime * time,
357 if (i1->time < *time)
359 else if (i1->time > *time)
366 gst_matroska_read_common_do_index_seek (GstMatroskaReadCommon * common,
367 GstMatroskaTrackContext * track, gint64 seek_pos, GArray ** _index,
370 GstMatroskaIndex *entry = NULL;
373 if (!common->index || !common->index->len)
376 /* find entry just before or at the requested position */
377 if (track && track->index_table)
378 index = track->index_table;
380 index = common->index;
383 gst_util_array_binary_search (index->data, index->len,
384 sizeof (GstMatroskaIndex),
385 (GCompareDataFunc) gst_matroska_index_seek_find, GST_SEARCH_MODE_BEFORE,
389 entry = &g_array_index (index, GstMatroskaIndex, 0);
394 *_entry_index = entry - (GstMatroskaIndex *) index->data;
400 gst_matroska_read_common_encoding_cmp (GstMatroskaTrackEncoding * a,
401 GstMatroskaTrackEncoding * b)
403 if (b->order > a->order)
405 else if (b->order < a->order)
412 gst_matroska_read_common_encoding_order_unique (GArray * encodings, guint64
417 if (encodings == NULL || encodings->len == 0)
420 for (i = 0; i < encodings->len; i++)
421 if (g_array_index (encodings, GstMatroskaTrackEncoding, i).order == order)
427 /* takes ownership of taglist */
429 gst_matroska_read_common_found_global_tag (GstMatroskaReadCommon * common,
430 GstElement * el, GstTagList * taglist)
432 if (common->global_tags) {
433 /* nothing sent yet, add to cache */
434 gst_tag_list_insert (common->global_tags, taglist, GST_TAG_MERGE_APPEND);
435 gst_tag_list_free (taglist);
437 GstEvent *tag_event = gst_event_new_tag (taglist);
440 /* hm, already sent, no need to cache and wait anymore */
441 GST_DEBUG_OBJECT (common, "Sending late global tags %" GST_PTR_FORMAT,
444 for (i = 0; i < common->src->len; i++) {
445 GstMatroskaTrackContext *stream;
447 stream = g_ptr_array_index (common->src, i);
448 gst_pad_push_event (stream->pad, gst_event_ref (tag_event));
451 gst_event_unref (tag_event);
456 gst_matroska_read_common_get_length (GstMatroskaReadCommon * common)
460 if (!gst_pad_peer_query_duration (common->sinkpad, GST_FORMAT_BYTES,
462 GST_DEBUG_OBJECT (common, "no upstream length");
467 /* determine track to seek in */
468 GstMatroskaTrackContext *
469 gst_matroska_read_common_get_seek_track (GstMatroskaReadCommon * common,
470 GstMatroskaTrackContext * track)
474 if (track && track->type == GST_MATROSKA_TRACK_TYPE_VIDEO)
477 for (i = 0; i < common->src->len; i++) {
478 GstMatroskaTrackContext *stream;
480 stream = g_ptr_array_index (common->src, i);
481 if (stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO && stream->index_table)
488 /* skip unknown or alike element */
490 gst_matroska_read_common_parse_skip (GstMatroskaReadCommon * common,
491 GstEbmlRead * ebml, const gchar * parent_name, guint id)
493 if (id == GST_EBML_ID_VOID) {
494 GST_DEBUG_OBJECT (common, "Skipping EBML Void element");
495 } else if (id == GST_EBML_ID_CRC32) {
496 GST_DEBUG_OBJECT (common, "Skipping EBML CRC32 element");
498 GST_WARNING_OBJECT (common,
499 "Unknown %s subelement 0x%x - ignoring", parent_name, id);
502 return gst_ebml_read_skip (ebml);
506 gst_matroska_read_common_parse_attached_file (GstMatroskaReadCommon * common,
507 GstEbmlRead * ebml, GstTagList * taglist)
511 gchar *description = NULL;
512 gchar *filename = NULL;
513 gchar *mimetype = NULL;
517 DEBUG_ELEMENT_START (common, ebml, "AttachedFile");
519 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
520 DEBUG_ELEMENT_STOP (common, ebml, "AttachedFile", ret);
524 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
525 /* read all sub-entries */
527 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
531 case GST_MATROSKA_ID_FILEDESCRIPTION:
533 GST_WARNING_OBJECT (common, "FileDescription can only appear once");
537 ret = gst_ebml_read_utf8 (ebml, &id, &description);
538 GST_DEBUG_OBJECT (common, "FileDescription: %s",
539 GST_STR_NULL (description));
541 case GST_MATROSKA_ID_FILENAME:
543 GST_WARNING_OBJECT (common, "FileName can only appear once");
547 ret = gst_ebml_read_utf8 (ebml, &id, &filename);
549 GST_DEBUG_OBJECT (common, "FileName: %s", GST_STR_NULL (filename));
551 case GST_MATROSKA_ID_FILEMIMETYPE:
553 GST_WARNING_OBJECT (common, "FileMimeType can only appear once");
557 ret = gst_ebml_read_ascii (ebml, &id, &mimetype);
558 GST_DEBUG_OBJECT (common, "FileMimeType: %s", GST_STR_NULL (mimetype));
560 case GST_MATROSKA_ID_FILEDATA:
562 GST_WARNING_OBJECT (common, "FileData can only appear once");
566 ret = gst_ebml_read_binary (ebml, &id, &data, &datalen);
567 GST_DEBUG_OBJECT (common, "FileData of size %" G_GUINT64_FORMAT,
572 ret = gst_matroska_read_common_parse_skip (common, ebml,
575 case GST_MATROSKA_ID_FILEUID:
576 ret = gst_ebml_read_skip (ebml);
581 DEBUG_ELEMENT_STOP (common, ebml, "AttachedFile", ret);
583 if (filename && mimetype && data && datalen > 0) {
584 GstTagImageType image_type = GST_TAG_IMAGE_TYPE_NONE;
585 GstBuffer *tagbuffer = NULL;
586 GstSample *tagsample = NULL;
587 GstStructure *info = NULL;
588 GstCaps *caps = NULL;
589 gchar *filename_lc = g_utf8_strdown (filename, -1);
591 GST_DEBUG_OBJECT (common, "Creating tag for attachment with "
592 "filename '%s', mimetype '%s', description '%s', "
593 "size %" G_GUINT64_FORMAT, filename, mimetype,
594 GST_STR_NULL (description), datalen);
596 /* TODO: better heuristics for different image types */
597 if (strstr (filename_lc, "cover")) {
598 if (strstr (filename_lc, "back"))
599 image_type = GST_TAG_IMAGE_TYPE_BACK_COVER;
601 image_type = GST_TAG_IMAGE_TYPE_FRONT_COVER;
602 } else if (g_str_has_prefix (mimetype, "image/") ||
603 g_str_has_suffix (filename_lc, "png") ||
604 g_str_has_suffix (filename_lc, "jpg") ||
605 g_str_has_suffix (filename_lc, "jpeg") ||
606 g_str_has_suffix (filename_lc, "gif") ||
607 g_str_has_suffix (filename_lc, "bmp")) {
608 image_type = GST_TAG_IMAGE_TYPE_UNDEFINED;
610 g_free (filename_lc);
612 /* First try to create an image tag buffer from this */
613 if (image_type != GST_TAG_IMAGE_TYPE_NONE) {
615 gst_tag_image_data_to_image_sample (data, datalen, image_type);
618 image_type = GST_TAG_IMAGE_TYPE_NONE;
621 tagbuffer = gst_buffer_ref (gst_sample_get_buffer (tagsample));
622 caps = gst_caps_ref (gst_sample_get_caps (tagsample));
623 info = gst_structure_copy (gst_sample_get_info (tagsample));
624 gst_sample_unref (tagsample);
628 /* if this failed create an attachment buffer */
630 tagbuffer = gst_buffer_new_wrapped (g_memdup (data, datalen), datalen);
632 caps = gst_type_find_helper_for_buffer (NULL, tagbuffer, NULL);
634 caps = gst_caps_new_empty_simple (mimetype);
637 /* Set filename and description in the info */
639 info = gst_structure_new_empty ("GstTagImageInfo");
641 gst_structure_set (info, "filename", G_TYPE_STRING, filename, NULL);
643 gst_structure_set (info, "description", G_TYPE_STRING, description, NULL);
645 tagsample = gst_sample_new (tagbuffer, caps, NULL, info);
647 GST_DEBUG_OBJECT (common,
648 "Created attachment sample: %" GST_PTR_FORMAT, tagsample);
650 /* and append to the tag list */
651 if (image_type != GST_TAG_IMAGE_TYPE_NONE)
652 gst_tag_list_add (taglist, GST_TAG_MERGE_APPEND, GST_TAG_IMAGE, tagsample,
655 gst_tag_list_add (taglist, GST_TAG_MERGE_APPEND, GST_TAG_ATTACHMENT,
658 /* the list adds it own ref */
659 gst_sample_unref (tagsample);
665 g_free (description);
671 gst_matroska_read_common_parse_attachments (GstMatroskaReadCommon * common,
672 GstElement * el, GstEbmlRead * ebml)
675 GstFlowReturn ret = GST_FLOW_OK;
678 DEBUG_ELEMENT_START (common, ebml, "Attachments");
680 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
681 DEBUG_ELEMENT_STOP (common, ebml, "Attachments", ret);
685 taglist = gst_tag_list_new_empty ();
687 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
688 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
692 case GST_MATROSKA_ID_ATTACHEDFILE:
693 ret = gst_matroska_read_common_parse_attached_file (common, ebml,
698 ret = gst_matroska_read_common_parse_skip (common, ebml,
703 DEBUG_ELEMENT_STOP (common, ebml, "Attachments", ret);
705 if (gst_structure_n_fields (GST_STRUCTURE (taglist)) > 0) {
706 GST_DEBUG_OBJECT (common, "Storing attachment tags");
707 gst_matroska_read_common_found_global_tag (common, el, taglist);
709 GST_DEBUG_OBJECT (common, "No valid attachments found");
710 gst_tag_list_free (taglist);
713 common->attachments_parsed = TRUE;
719 gst_matroska_read_common_parse_toc_tag (GstTocEntry * entry,
720 GArray * edition_targets, GArray * chapter_targtes, GstTagList * tags)
730 GST_TOC_ENTRY_TYPE_EDITION) ? edition_targets : chapter_targtes;
732 for (i = 0; i < targets->len; ++i) {
733 tgt = g_array_index (targets, guint64, i);
736 gst_tag_list_insert (entry->tags, tags, GST_TAG_MERGE_APPEND);
738 uid = g_strdup_printf ("%" G_GUINT64_FORMAT, tgt);
739 if (g_strcmp0 (entry->uid, uid) == 0)
740 gst_tag_list_insert (entry->tags, tags, GST_TAG_MERGE_APPEND);
745 cur = entry->subentries;
746 while (cur != NULL) {
747 gst_matroska_read_common_parse_toc_tag (cur->data, edition_targets,
748 chapter_targtes, tags);
754 gst_matroska_read_common_parse_metadata_targets (GstMatroskaReadCommon * common,
755 GstEbmlRead * ebml, GArray * edition_targets, GArray * chapter_targets)
757 GstFlowReturn ret = GST_FLOW_OK;
761 DEBUG_ELEMENT_START (common, ebml, "TagTargets");
763 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
764 DEBUG_ELEMENT_STOP (common, ebml, "TagTargets", ret);
768 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
769 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
773 case GST_MATROSKA_ID_TARGETCHAPTERUID:
774 if ((ret = gst_ebml_read_uint (ebml, &id, &uid)) == GST_FLOW_OK)
775 g_array_append_val (chapter_targets, uid);
778 case GST_MATROSKA_ID_TARGETEDITIONUID:
779 if ((ret = gst_ebml_read_uint (ebml, &id, &uid)) == GST_FLOW_OK)
780 g_array_append_val (edition_targets, uid);
785 gst_matroska_read_common_parse_skip (common, ebml, "TagTargets",
791 DEBUG_ELEMENT_STOP (common, ebml, "TagTargets", ret);
797 gst_matroska_read_common_postprocess_toc_entries (GList * toc_entries,
798 guint64 max, const gchar * parent_uid)
800 GstTocEntry *cur_info, *prev_info, *next_info;
801 GList *cur_list, *prev_list, *next_list;
804 gint64 cur_start, prev_start, stop;
806 cur_list = toc_entries;
807 while (cur_list != NULL) {
809 cur_info = cur_list->data;
811 iter_digit = g_strdup_printf ("%d", i);
813 switch (cur_info->type) {
814 case GST_TOC_ENTRY_TYPE_EDITION:
815 /* in Matroska terms edition has duration of full track */
816 gst_toc_entry_set_start_stop (cur_info, 0, max);
818 if (cur_info->uid == NULL)
820 g_strconcat (parent_uid, "/", GST_MATROSKA_TOC_UID_EDITION,
823 gst_matroska_read_common_postprocess_toc_entries (cur_info->subentries,
827 case GST_TOC_ENTRY_TYPE_CHAPTER:
828 prev_list = cur_list->prev;
829 next_list = cur_list->next;
831 if (prev_list != NULL)
832 prev_info = prev_list->data;
836 if (next_list != NULL)
837 next_info = next_list->data;
841 if (cur_info->uid == NULL)
843 g_strconcat (parent_uid, "/", GST_MATROSKA_TOC_UID_CHAPTER,
846 /* updated stop time in previous chapter and it's subchapters */
847 if (prev_info != NULL) {
848 gst_toc_entry_get_start_stop (prev_info, &prev_start, &stop);
849 gst_toc_entry_get_start_stop (cur_info, &cur_start, &stop);
852 gst_toc_entry_set_start_stop (prev_info, prev_start, stop);
854 gst_matroska_read_common_postprocess_toc_entries
855 (prev_info->subentries, cur_start, prev_info->uid);
858 /* updated stop time in current chapter and it's subchapters */
859 if (next_info == NULL) {
860 gst_toc_entry_get_start_stop (cur_info, &cur_start, &stop);
864 gst_toc_entry_set_start_stop (cur_info, cur_start, stop);
867 gst_matroska_read_common_postprocess_toc_entries
868 (cur_info->subentries, stop, cur_info->uid);
872 cur_list = cur_list->next;
878 gst_matroska_read_common_parse_chapter_titles (GstMatroskaReadCommon * common,
879 GstEbmlRead * ebml, GstTagList * titles)
883 GstFlowReturn ret = GST_FLOW_OK;
885 DEBUG_ELEMENT_START (common, ebml, "ChaptersTitles");
888 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
889 DEBUG_ELEMENT_STOP (common, ebml, "ChaptersTitles", ret);
893 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
894 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
898 case GST_MATROSKA_ID_CHAPSTRING:
899 ret = gst_ebml_read_utf8 (ebml, &id, &title);
904 gst_matroska_read_common_parse_skip (common, ebml, "ChaptersTitles",
910 DEBUG_ELEMENT_STOP (common, ebml, "ChaptersTitles", ret);
912 if (title != NULL && ret == GST_FLOW_OK)
913 gst_tag_list_add (titles, GST_TAG_MERGE_APPEND, GST_TAG_TITLE, title, NULL);
920 gst_matroska_read_common_parse_chapter_element (GstMatroskaReadCommon * common,
921 GstEbmlRead * ebml, GstTocEntry * toc_entry)
924 guint64 start_time = -1, stop_time = -1;
925 guint64 is_hidden = 0, is_enabled = 1, uid = 0;
926 GstFlowReturn ret = GST_FLOW_OK;
927 GstTocEntry *chapter_info;
930 DEBUG_ELEMENT_START (common, ebml, "ChaptersElement");
932 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
933 DEBUG_ELEMENT_STOP (common, ebml, "ChaptersElement", ret);
937 titles = gst_tag_list_new_empty ();
938 chapter_info = gst_toc_entry_new (GST_TOC_ENTRY_TYPE_CHAPTER,
939 GST_MATROSKA_TOC_UID_EMPTY);
941 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
942 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
946 case GST_MATROSKA_ID_CHAPTERUID:
947 ret = gst_ebml_read_uint (ebml, &id, &uid);
950 case GST_MATROSKA_ID_CHAPTERTIMESTART:
951 ret = gst_ebml_read_uint (ebml, &id, &start_time);
954 case GST_MATROSKA_ID_CHAPTERTIMESTOP:
955 ret = gst_ebml_read_uint (ebml, &id, &stop_time);
958 case GST_MATROSKA_ID_CHAPTERATOM:
960 gst_matroska_read_common_parse_chapter_element (common, ebml,
964 case GST_MATROSKA_ID_CHAPTERDISPLAY:
966 gst_matroska_read_common_parse_chapter_titles (common, ebml,
970 case GST_MATROSKA_ID_CHAPTERFLAGHIDDEN:
971 ret = gst_ebml_read_uint (ebml, &id, &is_hidden);
974 case GST_MATROSKA_ID_CHAPTERFLAGENABLED:
975 ret = gst_ebml_read_uint (ebml, &id, &is_enabled);
980 gst_matroska_read_common_parse_skip (common, ebml,
981 "ChaptersElement", id);
986 gst_toc_entry_set_start_stop (chapter_info, start_time, stop_time);
988 DEBUG_ELEMENT_STOP (common, ebml, "ChaptersElement", ret);
990 g_free (chapter_info->uid);
993 chapter_info->uid = g_strdup_printf ("%" G_GUINT64_FORMAT, uid);
995 chapter_info->uid = NULL;
997 /* start time is mandatory and has no default value,
998 * so we should skip chapters without it */
999 if (is_hidden == 0 && is_enabled > 0 &&
1000 start_time != -1 && ret == GST_FLOW_OK) {
1001 if (!gst_tag_list_is_empty (titles))
1002 gst_tag_list_insert (chapter_info->tags, titles, GST_TAG_MERGE_APPEND);
1004 toc_entry->subentries = g_list_append (toc_entry->subentries, chapter_info);
1006 gst_toc_entry_free (chapter_info);
1008 gst_tag_list_free (titles);
1012 static GstFlowReturn
1013 gst_matroska_read_common_parse_chapter_edition (GstMatroskaReadCommon * common,
1014 GstEbmlRead * ebml, GstToc * toc)
1017 guint64 is_hidden = 0, uid = 0;
1018 GstFlowReturn ret = GST_FLOW_OK;
1019 GstTocEntry *edition_info;
1021 DEBUG_ELEMENT_START (common, ebml, "ChaptersEdition");
1023 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
1024 DEBUG_ELEMENT_STOP (common, ebml, "ChaptersEdition", ret);
1028 edition_info = gst_toc_entry_new (GST_TOC_ENTRY_TYPE_EDITION,
1029 GST_MATROSKA_TOC_UID_EMPTY);
1031 gst_toc_entry_set_start_stop (edition_info, -1, -1);
1033 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1034 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1038 case GST_MATROSKA_ID_EDITIONUID:
1039 ret = gst_ebml_read_uint (ebml, &id, &uid);
1042 case GST_MATROSKA_ID_CHAPTERATOM:
1044 gst_matroska_read_common_parse_chapter_element (common, ebml,
1048 case GST_MATROSKA_ID_EDITIONFLAGHIDDEN:
1049 ret = gst_ebml_read_uint (ebml, &id, &is_hidden);
1054 gst_matroska_read_common_parse_skip (common, ebml,
1055 "ChaptersEdition", id);
1060 DEBUG_ELEMENT_STOP (common, ebml, "ChaptersEdition", ret);
1062 g_free (edition_info->uid);
1065 edition_info->uid = g_strdup_printf ("%" G_GUINT64_FORMAT, uid);
1067 edition_info->uid = NULL;
1069 if (is_hidden == 0 && edition_info->subentries != NULL && ret == GST_FLOW_OK)
1070 toc->entries = g_list_prepend (toc->entries, edition_info);
1072 GST_DEBUG_OBJECT (common,
1073 "Skipping empty or hidden edition in the chapters TOC");
1074 gst_toc_entry_free (edition_info);
1081 gst_matroska_read_common_parse_chapters (GstMatroskaReadCommon * common,
1085 GstFlowReturn ret = GST_FLOW_OK;
1088 DEBUG_ELEMENT_START (common, ebml, "Chapters");
1090 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
1091 DEBUG_ELEMENT_STOP (common, ebml, "Chapters", ret);
1095 toc = gst_toc_new ();
1097 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1098 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1102 case GST_MATROSKA_ID_EDITIONENTRY:
1104 gst_matroska_read_common_parse_chapter_edition (common, ebml, toc);
1109 gst_matroska_read_common_parse_skip (common, ebml, "Chapters", id);
1114 if (toc->entries != NULL) {
1115 toc->entries = g_list_reverse (toc->entries);
1116 gst_matroska_read_common_postprocess_toc_entries (toc->entries,
1117 common->segment.duration, "");
1123 common->chapters_parsed = TRUE;
1125 DEBUG_ELEMENT_STOP (common, ebml, "Chapters", ret);
1130 gst_matroska_read_common_parse_header (GstMatroskaReadCommon * common,
1138 /* this function is the first to be called */
1144 ret = gst_ebml_peek_id (ebml, &id);
1145 if (ret != GST_FLOW_OK)
1148 GST_DEBUG_OBJECT (common, "id: %08x", id);
1150 if (id != GST_EBML_ID_HEADER) {
1151 GST_ERROR_OBJECT (common, "Failed to read header");
1155 ret = gst_ebml_read_master (ebml, &id);
1156 if (ret != GST_FLOW_OK)
1159 while (gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1160 ret = gst_ebml_peek_id (ebml, &id);
1161 if (ret != GST_FLOW_OK)
1165 /* is our read version uptodate? */
1166 case GST_EBML_ID_EBMLREADVERSION:{
1169 ret = gst_ebml_read_uint (ebml, &id, &num);
1170 if (ret != GST_FLOW_OK)
1172 if (num != GST_EBML_VERSION) {
1173 GST_ERROR_OBJECT (ebml, "Unsupported EBML version %" G_GUINT64_FORMAT,
1175 return GST_FLOW_ERROR;
1178 GST_DEBUG_OBJECT (ebml, "EbmlReadVersion: %" G_GUINT64_FORMAT, num);
1182 /* we only handle 8 byte lengths at max */
1183 case GST_EBML_ID_EBMLMAXSIZELENGTH:{
1186 ret = gst_ebml_read_uint (ebml, &id, &num);
1187 if (ret != GST_FLOW_OK)
1189 if (num > sizeof (guint64)) {
1190 GST_ERROR_OBJECT (ebml,
1191 "Unsupported EBML maximum size %" G_GUINT64_FORMAT, num);
1192 return GST_FLOW_ERROR;
1194 GST_DEBUG_OBJECT (ebml, "EbmlMaxSizeLength: %" G_GUINT64_FORMAT, num);
1198 /* we handle 4 byte IDs at max */
1199 case GST_EBML_ID_EBMLMAXIDLENGTH:{
1202 ret = gst_ebml_read_uint (ebml, &id, &num);
1203 if (ret != GST_FLOW_OK)
1205 if (num > sizeof (guint32)) {
1206 GST_ERROR_OBJECT (ebml,
1207 "Unsupported EBML maximum ID %" G_GUINT64_FORMAT, num);
1208 return GST_FLOW_ERROR;
1210 GST_DEBUG_OBJECT (ebml, "EbmlMaxIdLength: %" G_GUINT64_FORMAT, num);
1214 case GST_EBML_ID_DOCTYPE:{
1217 ret = gst_ebml_read_ascii (ebml, &id, &text);
1218 if (ret != GST_FLOW_OK)
1221 GST_DEBUG_OBJECT (ebml, "EbmlDocType: %s", GST_STR_NULL (text));
1229 case GST_EBML_ID_DOCTYPEREADVERSION:{
1232 ret = gst_ebml_read_uint (ebml, &id, &num);
1233 if (ret != GST_FLOW_OK)
1236 GST_DEBUG_OBJECT (ebml, "EbmlReadVersion: %" G_GUINT64_FORMAT, num);
1241 ret = gst_matroska_read_common_parse_skip (common, ebml,
1243 if (ret != GST_FLOW_OK)
1247 /* we ignore these two, as they don't tell us anything we care about */
1248 case GST_EBML_ID_EBMLVERSION:
1249 case GST_EBML_ID_DOCTYPEVERSION:
1250 ret = gst_ebml_read_skip (ebml);
1251 if (ret != GST_FLOW_OK)
1259 if ((doctype != NULL && !strcmp (doctype, GST_MATROSKA_DOCTYPE_MATROSKA)) ||
1260 (doctype != NULL && !strcmp (doctype, GST_MATROSKA_DOCTYPE_WEBM)) ||
1261 (doctype == NULL)) {
1264 GST_INFO_OBJECT (common, "Input is %s version %d", doctype, version);
1266 GST_WARNING_OBJECT (common, "Input is EBML without doctype, assuming "
1267 "matroska (version %d)", version);
1271 GST_ELEMENT_ERROR (common, STREAM, DEMUX, (NULL),
1272 ("Demuxer version (2) is too old to read %s version %d",
1273 GST_STR_NULL (doctype), version));
1274 ret = GST_FLOW_ERROR;
1278 GST_ELEMENT_ERROR (common, STREAM, WRONG_TYPE, (NULL),
1279 ("Input is not a matroska stream (doctype=%s)", doctype));
1280 ret = GST_FLOW_ERROR;
1287 static GstFlowReturn
1288 gst_matroska_read_common_parse_index_cuetrack (GstMatroskaReadCommon * common,
1289 GstEbmlRead * ebml, guint * nentries)
1293 GstMatroskaIndex idx;
1295 idx.pos = (guint64) - 1;
1297 idx.time = GST_CLOCK_TIME_NONE;
1300 DEBUG_ELEMENT_START (common, ebml, "CueTrackPositions");
1302 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
1303 DEBUG_ELEMENT_STOP (common, ebml, "CueTrackPositions", ret);
1307 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1308 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1313 case GST_MATROSKA_ID_CUETRACK:
1317 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1322 GST_WARNING_OBJECT (common, "Invalid CueTrack 0");
1326 GST_DEBUG_OBJECT (common, "CueTrack: %" G_GUINT64_FORMAT, num);
1331 /* position in file */
1332 case GST_MATROSKA_ID_CUECLUSTERPOSITION:
1336 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1339 if (num > G_MAXINT64) {
1340 GST_WARNING_OBJECT (common, "CueClusterPosition %" G_GUINT64_FORMAT
1349 /* number of block in the cluster */
1350 case GST_MATROSKA_ID_CUEBLOCKNUMBER:
1354 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1358 GST_WARNING_OBJECT (common, "Invalid CueBlockNumber 0");
1362 GST_DEBUG_OBJECT (common, "CueBlockNumber: %" G_GUINT64_FORMAT, num);
1365 /* mild sanity check, disregard strange cases ... */
1366 if (idx.block > G_MAXUINT16) {
1367 GST_DEBUG_OBJECT (common, "... looks suspicious, ignoring");
1374 ret = gst_matroska_read_common_parse_skip (common, ebml,
1375 "CueTrackPositions", id);
1378 case GST_MATROSKA_ID_CUECODECSTATE:
1379 case GST_MATROSKA_ID_CUEREFERENCE:
1380 ret = gst_ebml_read_skip (ebml);
1385 DEBUG_ELEMENT_STOP (common, ebml, "CueTrackPositions", ret);
1387 /* (e.g.) lavf typically creates entries without a block number,
1388 * which is bogus and leads to contradictory information */
1389 if (common->index->len) {
1390 GstMatroskaIndex *last_idx;
1392 last_idx = &g_array_index (common->index, GstMatroskaIndex,
1393 common->index->len - 1);
1394 if (last_idx->block == idx.block && last_idx->pos == idx.pos &&
1395 last_idx->track == idx.track && idx.time > last_idx->time) {
1396 GST_DEBUG_OBJECT (common, "Cue entry refers to same location, "
1397 "but has different time than previous entry; discarding");
1402 if ((ret == GST_FLOW_OK || ret == GST_FLOW_EOS)
1403 && idx.pos != (guint64) - 1 && idx.track > 0) {
1404 g_array_append_val (common->index, idx);
1406 } else if (ret == GST_FLOW_OK || ret == GST_FLOW_EOS) {
1407 GST_DEBUG_OBJECT (common, "CueTrackPositions without valid content");
1413 static GstFlowReturn
1414 gst_matroska_read_common_parse_index_pointentry (GstMatroskaReadCommon *
1415 common, GstEbmlRead * ebml)
1419 GstClockTime time = GST_CLOCK_TIME_NONE;
1422 DEBUG_ELEMENT_START (common, ebml, "CuePoint");
1424 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
1425 DEBUG_ELEMENT_STOP (common, ebml, "CuePoint", ret);
1429 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1430 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1434 /* one single index entry ('point') */
1435 case GST_MATROSKA_ID_CUETIME:
1437 if ((ret = gst_ebml_read_uint (ebml, &id, &time)) != GST_FLOW_OK)
1440 GST_DEBUG_OBJECT (common, "CueTime: %" G_GUINT64_FORMAT, time);
1441 time = time * common->time_scale;
1445 /* position in the file + track to which it belongs */
1446 case GST_MATROSKA_ID_CUETRACKPOSITIONS:
1449 gst_matroska_read_common_parse_index_cuetrack (common, ebml,
1450 &nentries)) != GST_FLOW_OK)
1456 ret = gst_matroska_read_common_parse_skip (common, ebml, "CuePoint",
1462 DEBUG_ELEMENT_STOP (common, ebml, "CuePoint", ret);
1465 if (time == GST_CLOCK_TIME_NONE) {
1466 GST_WARNING_OBJECT (common, "CuePoint without valid time");
1467 g_array_remove_range (common->index, common->index->len - nentries,
1472 for (i = common->index->len - nentries; i < common->index->len; i++) {
1473 GstMatroskaIndex *idx =
1474 &g_array_index (common->index, GstMatroskaIndex, i);
1477 GST_DEBUG_OBJECT (common, "Index entry: pos=%" G_GUINT64_FORMAT
1478 ", time=%" GST_TIME_FORMAT ", track=%u, block=%u", idx->pos,
1479 GST_TIME_ARGS (idx->time), (guint) idx->track, (guint) idx->block);
1483 GST_DEBUG_OBJECT (common, "Empty CuePoint");
1490 gst_matroska_read_common_stream_from_num (GstMatroskaReadCommon * common,
1495 g_assert (common->src->len == common->num_streams);
1496 for (n = 0; n < common->src->len; n++) {
1497 GstMatroskaTrackContext *context = g_ptr_array_index (common->src, n);
1499 if (context->num == track_num) {
1504 if (n == common->num_streams)
1505 GST_WARNING_OBJECT (common,
1506 "Failed to find corresponding pad for tracknum %d", track_num);
1512 gst_matroska_read_common_parse_index (GstMatroskaReadCommon * common,
1516 GstFlowReturn ret = GST_FLOW_OK;
1520 g_array_free (common->index, TRUE);
1522 g_array_sized_new (FALSE, FALSE, sizeof (GstMatroskaIndex), 128);
1524 DEBUG_ELEMENT_START (common, ebml, "Cues");
1526 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
1527 DEBUG_ELEMENT_STOP (common, ebml, "Cues", ret);
1531 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1532 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1536 /* one single index entry ('point') */
1537 case GST_MATROSKA_ID_POINTENTRY:
1538 ret = gst_matroska_read_common_parse_index_pointentry (common, ebml);
1542 ret = gst_matroska_read_common_parse_skip (common, ebml, "Cues", id);
1546 DEBUG_ELEMENT_STOP (common, ebml, "Cues", ret);
1548 /* Sort index by time, smallest time first, for easier searching */
1549 g_array_sort (common->index, (GCompareFunc) gst_matroska_index_compare);
1551 /* Now sort the track specific index entries into their own arrays */
1552 for (i = 0; i < common->index->len; i++) {
1553 GstMatroskaIndex *idx = &g_array_index (common->index, GstMatroskaIndex,
1556 GstMatroskaTrackContext *ctx;
1559 if (common->element_index) {
1562 if (idx->track != 0 &&
1564 gst_matroska_read_common_stream_from_num (common,
1565 idx->track)) != -1) {
1566 ctx = g_ptr_array_index (common->src, track_num);
1568 if (ctx->index_writer_id == -1)
1569 gst_index_get_writer_id (common->element_index,
1570 GST_OBJECT (ctx->pad), &ctx->index_writer_id);
1571 writer_id = ctx->index_writer_id;
1573 if (common->element_index_writer_id == -1)
1574 gst_index_get_writer_id (common->element_index, GST_OBJECT (common),
1575 &common->element_index_writer_id);
1576 writer_id = common->element_index_writer_id;
1579 GST_LOG_OBJECT (common, "adding association %" GST_TIME_FORMAT "-> %"
1580 G_GUINT64_FORMAT " for writer id %d", GST_TIME_ARGS (idx->time),
1581 idx->pos, writer_id);
1582 gst_index_add_association (common->element_index, writer_id,
1583 GST_ASSOCIATION_FLAG_KEY_UNIT, GST_FORMAT_TIME, idx->time,
1584 GST_FORMAT_BYTES, idx->pos + common->ebml_segment_start, NULL);
1588 if (idx->track == 0)
1591 track_num = gst_matroska_read_common_stream_from_num (common, idx->track);
1592 if (track_num == -1)
1595 ctx = g_ptr_array_index (common->src, track_num);
1597 if (ctx->index_table == NULL)
1599 g_array_sized_new (FALSE, FALSE, sizeof (GstMatroskaIndex), 128);
1601 g_array_append_vals (ctx->index_table, idx, 1);
1604 common->index_parsed = TRUE;
1606 /* sanity check; empty index normalizes to no index */
1607 if (common->index->len == 0) {
1608 g_array_free (common->index, TRUE);
1609 common->index = NULL;
1616 gst_matroska_read_common_parse_info (GstMatroskaReadCommon * common,
1617 GstElement * el, GstEbmlRead * ebml)
1619 GstFlowReturn ret = GST_FLOW_OK;
1620 gdouble dur_f = -1.0;
1623 DEBUG_ELEMENT_START (common, ebml, "SegmentInfo");
1625 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
1626 DEBUG_ELEMENT_STOP (common, ebml, "SegmentInfo", ret);
1630 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1631 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1635 /* cluster timecode */
1636 case GST_MATROSKA_ID_TIMECODESCALE:{
1639 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1643 GST_DEBUG_OBJECT (common, "TimeCodeScale: %" G_GUINT64_FORMAT, num);
1644 common->time_scale = num;
1648 case GST_MATROSKA_ID_DURATION:{
1649 if ((ret = gst_ebml_read_float (ebml, &id, &dur_f)) != GST_FLOW_OK)
1653 GST_WARNING_OBJECT (common, "Invalid duration %lf", dur_f);
1657 GST_DEBUG_OBJECT (common, "Duration: %lf", dur_f);
1661 case GST_MATROSKA_ID_WRITINGAPP:{
1664 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1667 GST_DEBUG_OBJECT (common, "WritingApp: %s", GST_STR_NULL (text));
1668 common->writing_app = text;
1672 case GST_MATROSKA_ID_MUXINGAPP:{
1675 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1678 GST_DEBUG_OBJECT (common, "MuxingApp: %s", GST_STR_NULL (text));
1679 common->muxing_app = text;
1683 case GST_MATROSKA_ID_DATEUTC:{
1686 if ((ret = gst_ebml_read_date (ebml, &id, &time)) != GST_FLOW_OK)
1689 GST_DEBUG_OBJECT (common, "DateUTC: %" G_GINT64_FORMAT, time);
1690 common->created = time;
1694 case GST_MATROSKA_ID_TITLE:{
1696 GstTagList *taglist;
1698 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1701 GST_DEBUG_OBJECT (common, "Title: %s", GST_STR_NULL (text));
1702 taglist = gst_tag_list_new (GST_TAG_TITLE, text, NULL);
1703 gst_matroska_read_common_found_global_tag (common, el, taglist);
1709 ret = gst_matroska_read_common_parse_skip (common, ebml,
1714 case GST_MATROSKA_ID_SEGMENTUID:
1715 case GST_MATROSKA_ID_SEGMENTFILENAME:
1716 case GST_MATROSKA_ID_PREVUID:
1717 case GST_MATROSKA_ID_PREVFILENAME:
1718 case GST_MATROSKA_ID_NEXTUID:
1719 case GST_MATROSKA_ID_NEXTFILENAME:
1720 case GST_MATROSKA_ID_SEGMENTFAMILY:
1721 case GST_MATROSKA_ID_CHAPTERTRANSLATE:
1722 ret = gst_ebml_read_skip (ebml);
1730 dur_u = gst_gdouble_to_guint64 (dur_f *
1731 gst_guint64_to_gdouble (common->time_scale));
1732 if (GST_CLOCK_TIME_IS_VALID (dur_u) && dur_u <= G_MAXINT64)
1733 common->segment.duration = dur_u;
1736 DEBUG_ELEMENT_STOP (common, ebml, "SegmentInfo", ret);
1738 common->segmentinfo_parsed = TRUE;
1743 static GstFlowReturn
1744 gst_matroska_read_common_parse_metadata_id_simple_tag (GstMatroskaReadCommon *
1745 common, GstEbmlRead * ebml, GstTagList ** p_taglist)
1747 /* FIXME: check if there are more useful mappings */
1750 const gchar *matroska_tagname;
1751 const gchar *gstreamer_tagname;
1755 GST_MATROSKA_TAG_ID_TITLE, GST_TAG_TITLE}, {
1756 GST_MATROSKA_TAG_ID_ARTIST, GST_TAG_ARTIST}, {
1757 GST_MATROSKA_TAG_ID_AUTHOR, GST_TAG_ARTIST}, {
1758 GST_MATROSKA_TAG_ID_ALBUM, GST_TAG_ALBUM}, {
1759 GST_MATROSKA_TAG_ID_COMMENTS, GST_TAG_COMMENT}, {
1760 GST_MATROSKA_TAG_ID_BITSPS, GST_TAG_BITRATE}, {
1761 GST_MATROSKA_TAG_ID_BPS, GST_TAG_BITRATE}, {
1762 GST_MATROSKA_TAG_ID_ENCODER, GST_TAG_ENCODER}, {
1763 GST_MATROSKA_TAG_ID_DATE, GST_TAG_DATE}, {
1764 GST_MATROSKA_TAG_ID_ISRC, GST_TAG_ISRC}, {
1765 GST_MATROSKA_TAG_ID_COPYRIGHT, GST_TAG_COPYRIGHT}, {
1766 GST_MATROSKA_TAG_ID_BPM, GST_TAG_BEATS_PER_MINUTE}, {
1767 GST_MATROSKA_TAG_ID_TERMS_OF_USE, GST_TAG_LICENSE}, {
1768 GST_MATROSKA_TAG_ID_COMPOSER, GST_TAG_COMPOSER}, {
1769 GST_MATROSKA_TAG_ID_LEAD_PERFORMER, GST_TAG_PERFORMER}, {
1770 GST_MATROSKA_TAG_ID_GENRE, GST_TAG_GENRE}
1774 gchar *value = NULL;
1777 DEBUG_ELEMENT_START (common, ebml, "SimpleTag");
1779 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
1780 DEBUG_ELEMENT_STOP (common, ebml, "SimpleTag", ret);
1784 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1785 /* read all sub-entries */
1787 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1791 case GST_MATROSKA_ID_TAGNAME:
1794 ret = gst_ebml_read_ascii (ebml, &id, &tag);
1795 GST_DEBUG_OBJECT (common, "TagName: %s", GST_STR_NULL (tag));
1798 case GST_MATROSKA_ID_TAGSTRING:
1801 ret = gst_ebml_read_utf8 (ebml, &id, &value);
1802 GST_DEBUG_OBJECT (common, "TagString: %s", GST_STR_NULL (value));
1806 ret = gst_matroska_read_common_parse_skip (common, ebml, "SimpleTag",
1811 case GST_MATROSKA_ID_TAGLANGUAGE:
1812 case GST_MATROSKA_ID_TAGDEFAULT:
1813 case GST_MATROSKA_ID_TAGBINARY:
1814 ret = gst_ebml_read_skip (ebml);
1819 DEBUG_ELEMENT_STOP (common, ebml, "SimpleTag", ret);
1824 for (i = 0; i < G_N_ELEMENTS (tag_conv); i++) {
1825 const gchar *tagname_gst = tag_conv[i].gstreamer_tagname;
1827 const gchar *tagname_mkv = tag_conv[i].matroska_tagname;
1829 if (strcmp (tagname_mkv, tag) == 0) {
1830 GValue dest = { 0, };
1831 GType dest_type = gst_tag_get_type (tagname_gst);
1833 /* Ensure that any date string is complete */
1834 if (dest_type == G_TYPE_DATE) {
1835 guint year = 1901, month = 1, day = 1;
1837 /* Dates can be yyyy-MM-dd, yyyy-MM or yyyy, but we need
1839 if (sscanf (value, "%04u-%02u-%02u", &year, &month, &day) != 0) {
1841 value = g_strdup_printf ("%04u-%02u-%02u", year, month, day);
1845 g_value_init (&dest, dest_type);
1846 if (gst_value_deserialize (&dest, value)) {
1847 gst_tag_list_add_values (*p_taglist, GST_TAG_MERGE_APPEND,
1848 tagname_gst, &dest, NULL);
1850 GST_WARNING_OBJECT (common, "Can't transform tag '%s' with "
1851 "value '%s' to target type '%s'", tag, value,
1852 g_type_name (dest_type));
1854 g_value_unset (&dest);
1866 static GstFlowReturn
1867 gst_matroska_read_common_parse_metadata_id_tag (GstMatroskaReadCommon * common,
1868 GstEbmlRead * ebml, GstTagList ** p_taglist)
1872 GArray *chapter_targets, *edition_targets;
1873 GstTagList *taglist;
1876 DEBUG_ELEMENT_START (common, ebml, "Tag");
1878 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
1879 DEBUG_ELEMENT_STOP (common, ebml, "Tag", ret);
1883 edition_targets = g_array_new (FALSE, FALSE, sizeof (guint64));
1884 chapter_targets = g_array_new (FALSE, FALSE, sizeof (guint64));
1885 taglist = gst_tag_list_new_empty ();
1887 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1888 /* read all sub-entries */
1890 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1894 case GST_MATROSKA_ID_SIMPLETAG:
1895 ret = gst_matroska_read_common_parse_metadata_id_simple_tag (common,
1899 case GST_MATROSKA_ID_TARGETS:
1901 gst_matroska_read_common_parse_metadata_targets (common, ebml,
1902 edition_targets, chapter_targets);
1906 ret = gst_matroska_read_common_parse_skip (common, ebml, "Tag", id);
1911 DEBUG_ELEMENT_STOP (common, ebml, "Tag", ret);
1913 /* if tag is chapter/edition specific - try to find that entry */
1914 if (G_UNLIKELY (chapter_targets->len > 0 || edition_targets->len > 0)) {
1915 if (common->toc == NULL)
1916 GST_WARNING_OBJECT (common,
1917 "Found chapter/edition specific tag, but TOC doesn't present");
1919 cur = common->toc->entries;
1920 while (cur != NULL) {
1921 gst_matroska_read_common_parse_toc_tag (cur->data, edition_targets,
1922 chapter_targets, taglist);
1925 common->toc_updated = TRUE;
1928 gst_tag_list_insert (*p_taglist, taglist, GST_TAG_MERGE_APPEND);
1930 gst_tag_list_free (taglist);
1931 g_array_unref (chapter_targets);
1932 g_array_unref (edition_targets);
1938 gst_matroska_read_common_parse_metadata (GstMatroskaReadCommon * common,
1939 GstElement * el, GstEbmlRead * ebml)
1941 GstTagList *taglist;
1942 GstFlowReturn ret = GST_FLOW_OK;
1947 curpos = gst_ebml_read_get_pos (ebml);
1949 /* Make sure we don't parse a tags element twice and
1950 * post it's tags twice */
1951 curpos = gst_ebml_read_get_pos (ebml);
1952 for (l = common->tags_parsed; l; l = l->next) {
1953 guint64 *pos = l->data;
1955 if (*pos == curpos) {
1956 GST_DEBUG_OBJECT (common, "Skipping already parsed Tags at offset %"
1957 G_GUINT64_FORMAT, curpos);
1962 common->tags_parsed =
1963 g_list_prepend (common->tags_parsed, g_slice_new (guint64));
1964 *((guint64 *) common->tags_parsed->data) = curpos;
1967 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
1968 DEBUG_ELEMENT_STOP (common, ebml, "Tags", ret);
1972 taglist = gst_tag_list_new_empty ();
1973 common->toc_updated = FALSE;
1975 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1976 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1980 case GST_MATROSKA_ID_TAG:
1981 ret = gst_matroska_read_common_parse_metadata_id_tag (common, ebml,
1986 ret = gst_matroska_read_common_parse_skip (common, ebml, "Tags", id);
1988 /* FIXME: Use to limit the tags to specific pads */
1992 DEBUG_ELEMENT_STOP (common, ebml, "Tags", ret);
1994 if (G_LIKELY (!gst_tag_list_is_empty (taglist)))
1995 gst_matroska_read_common_found_global_tag (common, el, taglist);
1997 gst_tag_list_free (taglist);
2002 static GstFlowReturn
2003 gst_matroska_read_common_peek_adapter (GstMatroskaReadCommon * common, guint
2004 peek, const guint8 ** data)
2006 /* Caller needs to gst_adapter_unmap. */
2007 *data = gst_adapter_map (common->adapter, peek);
2009 return GST_FLOW_EOS;
2015 * Calls pull_range for (offset,size) without advancing our offset
2018 gst_matroska_read_common_peek_bytes (GstMatroskaReadCommon * common, guint64
2019 offset, guint size, GstBuffer ** p_buf, guint8 ** bytes)
2023 /* Caching here actually makes much less difference than one would expect.
2024 * We do it mainly to avoid pulling buffers of 1 byte all the time */
2025 if (common->cached_buffer) {
2026 guint64 cache_offset = GST_BUFFER_OFFSET (common->cached_buffer);
2027 gsize cache_size = gst_buffer_get_size (common->cached_buffer);
2029 if (cache_offset <= common->offset &&
2030 (common->offset + size) <= (cache_offset + cache_size)) {
2032 *p_buf = gst_buffer_copy_region (common->cached_buffer,
2033 GST_BUFFER_COPY_ALL, common->offset - cache_offset, size);
2035 if (!common->cached_data) {
2036 gst_buffer_map (common->cached_buffer, &common->cached_map,
2038 common->cached_data = common->cached_map.data;
2040 *bytes = common->cached_data + common->offset - cache_offset;
2044 /* not enough data in the cache, free cache and get a new one */
2045 if (common->cached_data) {
2046 gst_buffer_unmap (common->cached_buffer, &common->cached_map);
2047 common->cached_data = NULL;
2049 gst_buffer_unref (common->cached_buffer);
2050 common->cached_buffer = NULL;
2053 /* refill the cache */
2054 ret = gst_pad_pull_range (common->sinkpad, common->offset,
2055 MAX (size, 64 * 1024), &common->cached_buffer);
2056 if (ret != GST_FLOW_OK) {
2057 common->cached_buffer = NULL;
2061 if (gst_buffer_get_size (common->cached_buffer) >= size) {
2063 *p_buf = gst_buffer_copy_region (common->cached_buffer,
2064 GST_BUFFER_COPY_ALL, 0, size);
2066 gst_buffer_map (common->cached_buffer, &common->cached_map, GST_MAP_READ);
2067 common->cached_data = common->cached_map.data;
2068 *bytes = common->cached_data;
2073 /* Not possible to get enough data, try a last time with
2074 * requesting exactly the size we need */
2075 gst_buffer_unref (common->cached_buffer);
2076 common->cached_buffer = NULL;
2079 gst_pad_pull_range (common->sinkpad, common->offset, size,
2080 &common->cached_buffer);
2081 if (ret != GST_FLOW_OK) {
2082 GST_DEBUG_OBJECT (common, "pull_range returned %d", ret);
2090 if (gst_buffer_get_size (common->cached_buffer) < size) {
2091 GST_WARNING_OBJECT (common, "Dropping short buffer at offset %"
2092 G_GUINT64_FORMAT ": wanted %u bytes, got %" G_GSIZE_FORMAT " bytes",
2093 common->offset, size, gst_buffer_get_size (common->cached_buffer));
2095 gst_buffer_unref (common->cached_buffer);
2096 common->cached_buffer = NULL;
2101 return GST_FLOW_EOS;
2105 *p_buf = gst_buffer_copy_region (common->cached_buffer,
2106 GST_BUFFER_COPY_ALL, 0, size);
2108 gst_buffer_map (common->cached_buffer, &common->cached_map, GST_MAP_READ);
2109 common->cached_data = common->cached_map.data;
2110 *bytes = common->cached_data;
2116 static GstFlowReturn
2117 gst_matroska_read_common_peek_pull (GstMatroskaReadCommon * common, guint peek,
2120 return gst_matroska_read_common_peek_bytes (common, common->offset, peek,
2125 gst_matroska_read_common_peek_id_length_pull (GstMatroskaReadCommon * common,
2126 GstElement * el, guint32 * _id, guint64 * _length, guint * _needed)
2128 return gst_ebml_peek_id_length (_id, _length, _needed,
2129 (GstPeekData) gst_matroska_read_common_peek_pull, (gpointer) common, el,
2134 gst_matroska_read_common_peek_id_length_push (GstMatroskaReadCommon * common,
2135 GstElement * el, guint32 * _id, guint64 * _length, guint * _needed)
2139 ret = gst_ebml_peek_id_length (_id, _length, _needed,
2140 (GstPeekData) gst_matroska_read_common_peek_adapter, (gpointer) common,
2141 el, common->offset);
2143 gst_adapter_unmap (common->adapter);
2148 static GstFlowReturn
2149 gst_matroska_read_common_read_track_encoding (GstMatroskaReadCommon * common,
2150 GstEbmlRead * ebml, GstMatroskaTrackContext * context)
2152 GstMatroskaTrackEncoding enc = { 0, };
2156 DEBUG_ELEMENT_START (common, ebml, "ContentEncoding");
2157 /* Set default values */
2159 /* All other default values are 0 */
2161 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2162 DEBUG_ELEMENT_STOP (common, ebml, "ContentEncoding", ret);
2166 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
2167 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
2171 case GST_MATROSKA_ID_CONTENTENCODINGORDER:{
2174 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
2177 if (!gst_matroska_read_common_encoding_order_unique (context->encodings,
2179 GST_ERROR_OBJECT (common, "ContentEncodingOrder %" G_GUINT64_FORMAT
2180 "is not unique for track %d", num, context->num);
2181 ret = GST_FLOW_ERROR;
2185 GST_DEBUG_OBJECT (common, "ContentEncodingOrder: %" G_GUINT64_FORMAT,
2190 case GST_MATROSKA_ID_CONTENTENCODINGSCOPE:{
2193 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
2196 if (num > 7 && num == 0) {
2197 GST_ERROR_OBJECT (common, "Invalid ContentEncodingScope %"
2198 G_GUINT64_FORMAT, num);
2199 ret = GST_FLOW_ERROR;
2203 GST_DEBUG_OBJECT (common, "ContentEncodingScope: %" G_GUINT64_FORMAT,
2209 case GST_MATROSKA_ID_CONTENTENCODINGTYPE:{
2212 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
2216 GST_ERROR_OBJECT (common, "Invalid ContentEncodingType %"
2217 G_GUINT64_FORMAT, num);
2218 ret = GST_FLOW_ERROR;
2220 } else if (num != 0) {
2221 GST_ERROR_OBJECT (common, "Encrypted tracks are not supported yet");
2222 ret = GST_FLOW_ERROR;
2225 GST_DEBUG_OBJECT (common, "ContentEncodingType: %" G_GUINT64_FORMAT,
2230 case GST_MATROSKA_ID_CONTENTCOMPRESSION:{
2232 DEBUG_ELEMENT_START (common, ebml, "ContentCompression");
2234 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
2237 while (ret == GST_FLOW_OK &&
2238 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
2239 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
2243 case GST_MATROSKA_ID_CONTENTCOMPALGO:{
2246 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK) {
2250 GST_ERROR_OBJECT (common, "Invalid ContentCompAlgo %"
2251 G_GUINT64_FORMAT, num);
2252 ret = GST_FLOW_ERROR;
2255 GST_DEBUG_OBJECT (common, "ContentCompAlgo: %" G_GUINT64_FORMAT,
2257 enc.comp_algo = num;
2261 case GST_MATROSKA_ID_CONTENTCOMPSETTINGS:{
2266 gst_ebml_read_binary (ebml, &id, &data,
2267 &size)) != GST_FLOW_OK) {
2270 enc.comp_settings = data;
2271 enc.comp_settings_length = size;
2272 GST_DEBUG_OBJECT (common,
2273 "ContentCompSettings of size %" G_GUINT64_FORMAT, size);
2277 GST_WARNING_OBJECT (common,
2278 "Unknown ContentCompression subelement 0x%x - ignoring", id);
2279 ret = gst_ebml_read_skip (ebml);
2283 DEBUG_ELEMENT_STOP (common, ebml, "ContentCompression", ret);
2287 case GST_MATROSKA_ID_CONTENTENCRYPTION:
2288 GST_ERROR_OBJECT (common, "Encrypted tracks not yet supported");
2289 gst_ebml_read_skip (ebml);
2290 ret = GST_FLOW_ERROR;
2293 GST_WARNING_OBJECT (common,
2294 "Unknown ContentEncoding subelement 0x%x - ignoring", id);
2295 ret = gst_ebml_read_skip (ebml);
2300 DEBUG_ELEMENT_STOP (common, ebml, "ContentEncoding", ret);
2301 if (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)
2304 /* TODO: Check if the combination of values is valid */
2306 g_array_append_val (context->encodings, enc);
2312 gst_matroska_read_common_read_track_encodings (GstMatroskaReadCommon * common,
2313 GstEbmlRead * ebml, GstMatroskaTrackContext * context)
2318 DEBUG_ELEMENT_START (common, ebml, "ContentEncodings");
2320 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2321 DEBUG_ELEMENT_STOP (common, ebml, "ContentEncodings", ret);
2325 context->encodings =
2326 g_array_sized_new (FALSE, FALSE, sizeof (GstMatroskaTrackEncoding), 1);
2328 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
2329 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
2333 case GST_MATROSKA_ID_CONTENTENCODING:
2334 ret = gst_matroska_read_common_read_track_encoding (common, ebml,
2338 GST_WARNING_OBJECT (common,
2339 "Unknown ContentEncodings subelement 0x%x - ignoring", id);
2340 ret = gst_ebml_read_skip (ebml);
2345 DEBUG_ELEMENT_STOP (common, ebml, "ContentEncodings", ret);
2346 if (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)
2349 /* Sort encodings according to their order */
2350 g_array_sort (context->encodings,
2351 (GCompareFunc) gst_matroska_read_common_encoding_cmp);
2353 return gst_matroska_decode_content_encodings (context->encodings);
2356 /* call with object lock held */
2358 gst_matroska_read_common_reset_streams (GstMatroskaReadCommon * common,
2359 GstClockTime time, gboolean full)
2363 GST_DEBUG_OBJECT (common, "resetting stream state");
2365 g_assert (common->src->len == common->num_streams);
2366 for (i = 0; i < common->src->len; i++) {
2367 GstMatroskaTrackContext *context = g_ptr_array_index (common->src, i);
2368 context->pos = time;
2369 context->set_discont = TRUE;
2370 context->eos = FALSE;
2371 context->from_time = GST_CLOCK_TIME_NONE;
2373 context->last_flow = GST_FLOW_OK;
2374 if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
2375 GstMatroskaTrackVideoContext *videocontext =
2376 (GstMatroskaTrackVideoContext *) context;
2377 /* demux object lock held by caller */
2378 videocontext->earliest_time = GST_CLOCK_TIME_NONE;
2384 gst_matroska_read_common_tracknumber_unique (GstMatroskaReadCommon * common,
2389 g_assert (common->src->len == common->num_streams);
2390 for (i = 0; i < common->src->len; i++) {
2391 GstMatroskaTrackContext *context = g_ptr_array_index (common->src, i);
2393 if (context->num == num)