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))
60 gst_matroska_decompress_data (GstMatroskaTrackEncoding * enc,
61 gpointer * data_out, gsize * size_out,
62 GstMatroskaTrackCompressionAlgorithm algo)
64 guint8 *new_data = NULL;
66 guint8 *data = *data_out;
67 guint size = *size_out;
70 if (algo == GST_MATROSKA_TRACK_COMPRESSION_ALGORITHM_ZLIB) {
72 /* zlib encoded data */
78 zstream.zalloc = (alloc_func) 0;
79 zstream.zfree = (free_func) 0;
80 zstream.opaque = (voidpf) 0;
81 if (inflateInit (&zstream) != Z_OK) {
82 GST_WARNING ("zlib initialization failed.");
86 zstream.next_in = (Bytef *) data;
87 zstream.avail_in = orig_size;
89 new_data = g_malloc (new_size);
90 zstream.avail_out = new_size;
91 zstream.next_out = (Bytef *) new_data;
94 result = inflate (&zstream, Z_NO_FLUSH);
95 if (result != Z_OK && result != Z_STREAM_END) {
96 GST_WARNING ("zlib decompression failed.");
98 inflateEnd (&zstream);
102 new_data = g_realloc (new_data, new_size);
103 zstream.next_out = (Bytef *) (new_data + zstream.total_out);
104 zstream.avail_out += 4000;
105 } while (zstream.avail_in != 0 && result != Z_STREAM_END);
107 if (result != Z_STREAM_END) {
111 new_size = zstream.total_out;
112 inflateEnd (&zstream);
115 GST_WARNING ("zlib encoded tracks not supported.");
119 } else if (algo == GST_MATROSKA_TRACK_COMPRESSION_ALGORITHM_BZLIB) {
121 /* bzip2 encoded data */
126 bzstream.bzalloc = NULL;
127 bzstream.bzfree = NULL;
128 bzstream.opaque = NULL;
131 if (BZ2_bzDecompressInit (&bzstream, 0, 0) != BZ_OK) {
132 GST_WARNING ("bzip2 initialization failed.");
137 bzstream.next_in = (char *) data;
138 bzstream.avail_in = orig_size;
139 new_size = orig_size;
140 new_data = g_malloc (new_size);
141 bzstream.avail_out = new_size;
142 bzstream.next_out = (char *) new_data;
145 result = BZ2_bzDecompress (&bzstream);
146 if (result != BZ_OK && result != BZ_STREAM_END) {
147 GST_WARNING ("bzip2 decompression failed.");
149 BZ2_bzDecompressEnd (&bzstream);
153 new_data = g_realloc (new_data, new_size);
154 bzstream.next_out = (char *) (new_data + bzstream.total_out_lo32);
155 bzstream.avail_out += 4000;
156 } while (bzstream.avail_in != 0 && result != BZ_STREAM_END);
158 if (result != BZ_STREAM_END) {
162 new_size = bzstream.total_out_lo32;
163 BZ2_bzDecompressEnd (&bzstream);
166 GST_WARNING ("bzip2 encoded tracks not supported.");
170 } else if (algo == GST_MATROSKA_TRACK_COMPRESSION_ALGORITHM_LZO1X) {
171 /* lzo encoded data */
173 int orig_size, out_size;
178 new_data = g_malloc (new_size);
184 result = lzo1x_decode (new_data, &out_size, data, &orig_size);
188 new_data = g_realloc (new_data, new_size);
190 } while (orig_size > 0 && result == LZO_OUTPUT_FULL);
192 new_size -= out_size;
194 if (result != LZO_OUTPUT_FULL) {
195 GST_WARNING ("lzo decompression failed");
202 } else if (algo == GST_MATROSKA_TRACK_COMPRESSION_ALGORITHM_HEADERSTRIP) {
203 /* header stripped encoded data */
204 if (enc->comp_settings_length > 0) {
205 new_data = g_malloc (size + enc->comp_settings_length);
206 new_size = size + enc->comp_settings_length;
208 memcpy (new_data, enc->comp_settings, enc->comp_settings_length);
209 memcpy (new_data + enc->comp_settings_length, data, size);
212 GST_ERROR ("invalid compression algorithm %d", algo);
222 *data_out = new_data;
223 *size_out = new_size;
230 gst_matroska_decode_content_encodings (GArray * encodings)
234 if (encodings == NULL)
237 for (i = 0; i < encodings->len; i++) {
238 GstMatroskaTrackEncoding *enc =
239 &g_array_index (encodings, GstMatroskaTrackEncoding, i);
240 gpointer data = NULL;
243 if ((enc->scope & GST_MATROSKA_TRACK_ENCODING_SCOPE_NEXT_CONTENT_ENCODING)
247 /* Encryption not supported yet */
249 return GST_FLOW_ERROR;
251 if (i + 1 >= encodings->len)
252 return GST_FLOW_ERROR;
254 if (enc->comp_settings_length == 0)
257 data = enc->comp_settings;
258 size = enc->comp_settings_length;
260 if (!gst_matroska_decompress_data (enc, &data, &size, enc->comp_algo))
261 return GST_FLOW_ERROR;
263 g_free (enc->comp_settings);
265 enc->comp_settings = data;
266 enc->comp_settings_length = size;
273 gst_matroska_decode_data (GArray * encodings, gpointer * data_out,
274 gsize * size_out, GstMatroskaTrackEncodingScope scope, gboolean free)
281 g_return_val_if_fail (encodings != NULL, FALSE);
282 g_return_val_if_fail (data_out != NULL && *data_out != NULL, FALSE);
283 g_return_val_if_fail (size_out != NULL, FALSE);
288 for (i = 0; i < encodings->len; i++) {
289 GstMatroskaTrackEncoding *enc =
290 &g_array_index (encodings, GstMatroskaTrackEncoding, i);
291 gpointer new_data = NULL;
294 if ((enc->scope & scope) == 0)
297 /* Encryption not supported yet */
298 if (enc->type != 0) {
307 gst_matroska_decompress_data (enc, &new_data, &new_size,
313 if ((data == *data_out && free) || (data != *data_out))
321 if ((data == *data_out && free) || (data != *data_out))
335 gst_matroska_index_compare (GstMatroskaIndex * i1, GstMatroskaIndex * i2)
337 if (i1->time < i2->time)
339 else if (i1->time > i2->time)
341 else if (i1->block < i2->block)
343 else if (i1->block > i2->block)
350 gst_matroska_index_seek_find (GstMatroskaIndex * i1, GstClockTime * time,
353 if (i1->time < *time)
355 else if (i1->time > *time)
362 gst_matroska_read_common_do_index_seek (GstMatroskaReadCommon * common,
363 GstMatroskaTrackContext * track, gint64 seek_pos, GArray ** _index,
366 GstMatroskaIndex *entry = NULL;
369 if (!common->index || !common->index->len)
372 /* find entry just before or at the requested position */
373 if (track && track->index_table)
374 index = track->index_table;
376 index = common->index;
379 gst_util_array_binary_search (index->data, index->len,
380 sizeof (GstMatroskaIndex),
381 (GCompareDataFunc) gst_matroska_index_seek_find, GST_SEARCH_MODE_BEFORE,
385 entry = &g_array_index (index, GstMatroskaIndex, 0);
390 *_entry_index = entry - (GstMatroskaIndex *) index->data;
396 gst_matroska_read_common_encoding_cmp (GstMatroskaTrackEncoding * a,
397 GstMatroskaTrackEncoding * b)
399 if (b->order > a->order)
401 else if (b->order < a->order)
408 gst_matroska_read_common_encoding_order_unique (GArray * encodings, guint64
413 if (encodings == NULL || encodings->len == 0)
416 for (i = 0; i < encodings->len; i++)
417 if (g_array_index (encodings, GstMatroskaTrackEncoding, i).order == order)
423 /* takes ownership of taglist */
425 gst_matroska_read_common_found_global_tag (GstMatroskaReadCommon * common,
426 GstElement * el, GstTagList * taglist)
428 if (common->global_tags) {
429 /* nothing sent yet, add to cache */
430 gst_tag_list_insert (common->global_tags, taglist, GST_TAG_MERGE_APPEND);
431 gst_tag_list_free (taglist);
433 GstEvent *tag_event = gst_event_new_tag (taglist);
436 /* hm, already sent, no need to cache and wait anymore */
437 GST_DEBUG_OBJECT (common, "Sending late global tags %" GST_PTR_FORMAT,
440 for (i = 0; i < common->src->len; i++) {
441 GstMatroskaTrackContext *stream;
443 stream = g_ptr_array_index (common->src, i);
444 gst_pad_push_event (stream->pad, gst_event_ref (tag_event));
447 gst_event_unref (tag_event);
452 gst_matroska_read_common_get_length (GstMatroskaReadCommon * common)
456 if (!gst_pad_peer_query_duration (common->sinkpad, GST_FORMAT_BYTES,
458 GST_DEBUG_OBJECT (common, "no upstream length");
463 /* determine track to seek in */
464 GstMatroskaTrackContext *
465 gst_matroska_read_common_get_seek_track (GstMatroskaReadCommon * common,
466 GstMatroskaTrackContext * track)
470 if (track && track->type == GST_MATROSKA_TRACK_TYPE_VIDEO)
473 for (i = 0; i < common->src->len; i++) {
474 GstMatroskaTrackContext *stream;
476 stream = g_ptr_array_index (common->src, i);
477 if (stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO && stream->index_table)
484 /* skip unknown or alike element */
486 gst_matroska_read_common_parse_skip (GstMatroskaReadCommon * common,
487 GstEbmlRead * ebml, const gchar * parent_name, guint id)
489 if (id == GST_EBML_ID_VOID) {
490 GST_DEBUG_OBJECT (common, "Skipping EBML Void element");
491 } else if (id == GST_EBML_ID_CRC32) {
492 GST_DEBUG_OBJECT (common, "Skipping EBML CRC32 element");
494 GST_WARNING_OBJECT (common,
495 "Unknown %s subelement 0x%x - ignoring", parent_name, id);
498 return gst_ebml_read_skip (ebml);
502 gst_matroska_read_common_parse_attached_file (GstMatroskaReadCommon * common,
503 GstEbmlRead * ebml, GstTagList * taglist)
507 gchar *description = NULL;
508 gchar *filename = NULL;
509 gchar *mimetype = NULL;
513 DEBUG_ELEMENT_START (common, ebml, "AttachedFile");
515 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
516 DEBUG_ELEMENT_STOP (common, ebml, "AttachedFile", ret);
520 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
521 /* read all sub-entries */
523 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
527 case GST_MATROSKA_ID_FILEDESCRIPTION:
529 GST_WARNING_OBJECT (common, "FileDescription can only appear once");
533 ret = gst_ebml_read_utf8 (ebml, &id, &description);
534 GST_DEBUG_OBJECT (common, "FileDescription: %s",
535 GST_STR_NULL (description));
537 case GST_MATROSKA_ID_FILENAME:
539 GST_WARNING_OBJECT (common, "FileName can only appear once");
543 ret = gst_ebml_read_utf8 (ebml, &id, &filename);
545 GST_DEBUG_OBJECT (common, "FileName: %s", GST_STR_NULL (filename));
547 case GST_MATROSKA_ID_FILEMIMETYPE:
549 GST_WARNING_OBJECT (common, "FileMimeType can only appear once");
553 ret = gst_ebml_read_ascii (ebml, &id, &mimetype);
554 GST_DEBUG_OBJECT (common, "FileMimeType: %s", GST_STR_NULL (mimetype));
556 case GST_MATROSKA_ID_FILEDATA:
558 GST_WARNING_OBJECT (common, "FileData can only appear once");
562 ret = gst_ebml_read_binary (ebml, &id, &data, &datalen);
563 GST_DEBUG_OBJECT (common, "FileData of size %" G_GUINT64_FORMAT,
568 ret = gst_matroska_read_common_parse_skip (common, ebml,
571 case GST_MATROSKA_ID_FILEUID:
572 ret = gst_ebml_read_skip (ebml);
577 DEBUG_ELEMENT_STOP (common, ebml, "AttachedFile", ret);
579 if (filename && mimetype && data && datalen > 0) {
580 GstTagImageType image_type = GST_TAG_IMAGE_TYPE_NONE;
581 GstBuffer *tagbuffer = NULL;
582 GstSample *tagsample = NULL;
583 GstStructure *info = NULL;
584 GstCaps *caps = NULL;
585 gchar *filename_lc = g_utf8_strdown (filename, -1);
587 GST_DEBUG_OBJECT (common, "Creating tag for attachment with "
588 "filename '%s', mimetype '%s', description '%s', "
589 "size %" G_GUINT64_FORMAT, filename, mimetype,
590 GST_STR_NULL (description), datalen);
592 /* TODO: better heuristics for different image types */
593 if (strstr (filename_lc, "cover")) {
594 if (strstr (filename_lc, "back"))
595 image_type = GST_TAG_IMAGE_TYPE_BACK_COVER;
597 image_type = GST_TAG_IMAGE_TYPE_FRONT_COVER;
598 } else if (g_str_has_prefix (mimetype, "image/") ||
599 g_str_has_suffix (filename_lc, "png") ||
600 g_str_has_suffix (filename_lc, "jpg") ||
601 g_str_has_suffix (filename_lc, "jpeg") ||
602 g_str_has_suffix (filename_lc, "gif") ||
603 g_str_has_suffix (filename_lc, "bmp")) {
604 image_type = GST_TAG_IMAGE_TYPE_UNDEFINED;
606 g_free (filename_lc);
608 /* First try to create an image tag buffer from this */
609 if (image_type != GST_TAG_IMAGE_TYPE_NONE) {
611 gst_tag_image_data_to_image_sample (data, datalen, image_type);
614 image_type = GST_TAG_IMAGE_TYPE_NONE;
617 tagbuffer = gst_buffer_ref (gst_sample_get_buffer (tagsample));
618 caps = gst_caps_ref (gst_sample_get_caps (tagsample));
619 info = gst_structure_copy (gst_sample_get_info (tagsample));
620 gst_sample_unref (tagsample);
624 /* if this failed create an attachment buffer */
626 tagbuffer = gst_buffer_new_wrapped (g_memdup (data, datalen), datalen);
628 caps = gst_type_find_helper_for_buffer (NULL, tagbuffer, NULL);
630 caps = gst_caps_new_empty_simple (mimetype);
633 /* Set filename and description in the info */
635 info = gst_structure_new_empty ("GstTagImageInfo");
637 gst_structure_set (info, "filename", G_TYPE_STRING, filename, NULL);
639 gst_structure_set (info, "description", G_TYPE_STRING, description, NULL);
641 tagsample = gst_sample_new (tagbuffer, caps, NULL, info);
643 GST_DEBUG_OBJECT (common,
644 "Created attachment sample: %" GST_PTR_FORMAT, tagsample);
646 /* and append to the tag list */
647 if (image_type != GST_TAG_IMAGE_TYPE_NONE)
648 gst_tag_list_add (taglist, GST_TAG_MERGE_APPEND, GST_TAG_IMAGE, tagsample,
651 gst_tag_list_add (taglist, GST_TAG_MERGE_APPEND, GST_TAG_ATTACHMENT,
654 /* the list adds it own ref */
655 gst_buffer_unref (tagsample);
661 g_free (description);
667 gst_matroska_read_common_parse_attachments (GstMatroskaReadCommon * common,
668 GstElement * el, GstEbmlRead * ebml)
671 GstFlowReturn ret = GST_FLOW_OK;
674 DEBUG_ELEMENT_START (common, ebml, "Attachments");
676 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
677 DEBUG_ELEMENT_STOP (common, ebml, "Attachments", ret);
681 taglist = gst_tag_list_new_empty ();
683 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
684 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
688 case GST_MATROSKA_ID_ATTACHEDFILE:
689 ret = gst_matroska_read_common_parse_attached_file (common, ebml,
694 ret = gst_matroska_read_common_parse_skip (common, ebml,
699 DEBUG_ELEMENT_STOP (common, ebml, "Attachments", ret);
701 if (gst_structure_n_fields (GST_STRUCTURE (taglist)) > 0) {
702 GST_DEBUG_OBJECT (common, "Storing attachment tags");
703 gst_matroska_read_common_found_global_tag (common, el, taglist);
705 GST_DEBUG_OBJECT (common, "No valid attachments found");
706 gst_tag_list_free (taglist);
709 common->attachments_parsed = TRUE;
715 gst_matroska_read_common_parse_chapters (GstMatroskaReadCommon * common,
719 GstFlowReturn ret = GST_FLOW_OK;
721 GST_WARNING_OBJECT (common, "Parsing of chapters not implemented yet");
723 /* TODO: implement parsing of chapters */
725 DEBUG_ELEMENT_START (common, ebml, "Chapters");
727 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
728 DEBUG_ELEMENT_STOP (common, ebml, "Chapters", ret);
732 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
733 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
738 ret = gst_ebml_read_skip (ebml);
743 DEBUG_ELEMENT_STOP (common, ebml, "Chapters", ret);
748 gst_matroska_read_common_parse_header (GstMatroskaReadCommon * common,
756 /* this function is the first to be called */
762 ret = gst_ebml_peek_id (ebml, &id);
763 if (ret != GST_FLOW_OK)
766 GST_DEBUG_OBJECT (common, "id: %08x", id);
768 if (id != GST_EBML_ID_HEADER) {
769 GST_ERROR_OBJECT (common, "Failed to read header");
773 ret = gst_ebml_read_master (ebml, &id);
774 if (ret != GST_FLOW_OK)
777 while (gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
778 ret = gst_ebml_peek_id (ebml, &id);
779 if (ret != GST_FLOW_OK)
783 /* is our read version uptodate? */
784 case GST_EBML_ID_EBMLREADVERSION:{
787 ret = gst_ebml_read_uint (ebml, &id, &num);
788 if (ret != GST_FLOW_OK)
790 if (num != GST_EBML_VERSION) {
791 GST_ERROR_OBJECT (ebml, "Unsupported EBML version %" G_GUINT64_FORMAT,
793 return GST_FLOW_ERROR;
796 GST_DEBUG_OBJECT (ebml, "EbmlReadVersion: %" G_GUINT64_FORMAT, num);
800 /* we only handle 8 byte lengths at max */
801 case GST_EBML_ID_EBMLMAXSIZELENGTH:{
804 ret = gst_ebml_read_uint (ebml, &id, &num);
805 if (ret != GST_FLOW_OK)
807 if (num > sizeof (guint64)) {
808 GST_ERROR_OBJECT (ebml,
809 "Unsupported EBML maximum size %" G_GUINT64_FORMAT, num);
810 return GST_FLOW_ERROR;
812 GST_DEBUG_OBJECT (ebml, "EbmlMaxSizeLength: %" G_GUINT64_FORMAT, num);
816 /* we handle 4 byte IDs at max */
817 case GST_EBML_ID_EBMLMAXIDLENGTH:{
820 ret = gst_ebml_read_uint (ebml, &id, &num);
821 if (ret != GST_FLOW_OK)
823 if (num > sizeof (guint32)) {
824 GST_ERROR_OBJECT (ebml,
825 "Unsupported EBML maximum ID %" G_GUINT64_FORMAT, num);
826 return GST_FLOW_ERROR;
828 GST_DEBUG_OBJECT (ebml, "EbmlMaxIdLength: %" G_GUINT64_FORMAT, num);
832 case GST_EBML_ID_DOCTYPE:{
835 ret = gst_ebml_read_ascii (ebml, &id, &text);
836 if (ret != GST_FLOW_OK)
839 GST_DEBUG_OBJECT (ebml, "EbmlDocType: %s", GST_STR_NULL (text));
847 case GST_EBML_ID_DOCTYPEREADVERSION:{
850 ret = gst_ebml_read_uint (ebml, &id, &num);
851 if (ret != GST_FLOW_OK)
854 GST_DEBUG_OBJECT (ebml, "EbmlReadVersion: %" G_GUINT64_FORMAT, num);
859 ret = gst_matroska_read_common_parse_skip (common, ebml,
861 if (ret != GST_FLOW_OK)
865 /* we ignore these two, as they don't tell us anything we care about */
866 case GST_EBML_ID_EBMLVERSION:
867 case GST_EBML_ID_DOCTYPEVERSION:
868 ret = gst_ebml_read_skip (ebml);
869 if (ret != GST_FLOW_OK)
877 if ((doctype != NULL && !strcmp (doctype, GST_MATROSKA_DOCTYPE_MATROSKA)) ||
878 (doctype != NULL && !strcmp (doctype, GST_MATROSKA_DOCTYPE_WEBM)) ||
882 GST_INFO_OBJECT (common, "Input is %s version %d", doctype, version);
884 GST_WARNING_OBJECT (common, "Input is EBML without doctype, assuming "
885 "matroska (version %d)", version);
889 GST_ELEMENT_ERROR (common, STREAM, DEMUX, (NULL),
890 ("Demuxer version (2) is too old to read %s version %d",
891 GST_STR_NULL (doctype), version));
892 ret = GST_FLOW_ERROR;
896 GST_ELEMENT_ERROR (common, STREAM, WRONG_TYPE, (NULL),
897 ("Input is not a matroska stream (doctype=%s)", doctype));
898 ret = GST_FLOW_ERROR;
906 gst_matroska_read_common_parse_index_cuetrack (GstMatroskaReadCommon * common,
907 GstEbmlRead * ebml, guint * nentries)
911 GstMatroskaIndex idx;
913 idx.pos = (guint64) - 1;
915 idx.time = GST_CLOCK_TIME_NONE;
918 DEBUG_ELEMENT_START (common, ebml, "CueTrackPositions");
920 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
921 DEBUG_ELEMENT_STOP (common, ebml, "CueTrackPositions", ret);
925 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
926 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
931 case GST_MATROSKA_ID_CUETRACK:
935 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
940 GST_WARNING_OBJECT (common, "Invalid CueTrack 0");
944 GST_DEBUG_OBJECT (common, "CueTrack: %" G_GUINT64_FORMAT, num);
949 /* position in file */
950 case GST_MATROSKA_ID_CUECLUSTERPOSITION:
954 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
957 if (num > G_MAXINT64) {
958 GST_WARNING_OBJECT (common, "CueClusterPosition %" G_GUINT64_FORMAT
967 /* number of block in the cluster */
968 case GST_MATROSKA_ID_CUEBLOCKNUMBER:
972 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
976 GST_WARNING_OBJECT (common, "Invalid CueBlockNumber 0");
980 GST_DEBUG_OBJECT (common, "CueBlockNumber: %" G_GUINT64_FORMAT, num);
983 /* mild sanity check, disregard strange cases ... */
984 if (idx.block > G_MAXUINT16) {
985 GST_DEBUG_OBJECT (common, "... looks suspicious, ignoring");
992 ret = gst_matroska_read_common_parse_skip (common, ebml,
993 "CueTrackPositions", id);
996 case GST_MATROSKA_ID_CUECODECSTATE:
997 case GST_MATROSKA_ID_CUEREFERENCE:
998 ret = gst_ebml_read_skip (ebml);
1003 DEBUG_ELEMENT_STOP (common, ebml, "CueTrackPositions", ret);
1005 /* (e.g.) lavf typically creates entries without a block number,
1006 * which is bogus and leads to contradictory information */
1007 if (common->index->len) {
1008 GstMatroskaIndex *last_idx;
1010 last_idx = &g_array_index (common->index, GstMatroskaIndex,
1011 common->index->len - 1);
1012 if (last_idx->block == idx.block && last_idx->pos == idx.pos &&
1013 last_idx->track == idx.track && idx.time > last_idx->time) {
1014 GST_DEBUG_OBJECT (common, "Cue entry refers to same location, "
1015 "but has different time than previous entry; discarding");
1020 if ((ret == GST_FLOW_OK || ret == GST_FLOW_EOS)
1021 && idx.pos != (guint64) - 1 && idx.track > 0) {
1022 g_array_append_val (common->index, idx);
1024 } else if (ret == GST_FLOW_OK || ret == GST_FLOW_EOS) {
1025 GST_DEBUG_OBJECT (common, "CueTrackPositions without valid content");
1031 static GstFlowReturn
1032 gst_matroska_read_common_parse_index_pointentry (GstMatroskaReadCommon *
1033 common, GstEbmlRead * ebml)
1037 GstClockTime time = GST_CLOCK_TIME_NONE;
1040 DEBUG_ELEMENT_START (common, ebml, "CuePoint");
1042 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
1043 DEBUG_ELEMENT_STOP (common, ebml, "CuePoint", ret);
1047 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1048 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1052 /* one single index entry ('point') */
1053 case GST_MATROSKA_ID_CUETIME:
1055 if ((ret = gst_ebml_read_uint (ebml, &id, &time)) != GST_FLOW_OK)
1058 GST_DEBUG_OBJECT (common, "CueTime: %" G_GUINT64_FORMAT, time);
1059 time = time * common->time_scale;
1063 /* position in the file + track to which it belongs */
1064 case GST_MATROSKA_ID_CUETRACKPOSITIONS:
1067 gst_matroska_read_common_parse_index_cuetrack (common, ebml,
1068 &nentries)) != GST_FLOW_OK)
1074 ret = gst_matroska_read_common_parse_skip (common, ebml, "CuePoint",
1080 DEBUG_ELEMENT_STOP (common, ebml, "CuePoint", ret);
1083 if (time == GST_CLOCK_TIME_NONE) {
1084 GST_WARNING_OBJECT (common, "CuePoint without valid time");
1085 g_array_remove_range (common->index, common->index->len - nentries,
1090 for (i = common->index->len - nentries; i < common->index->len; i++) {
1091 GstMatroskaIndex *idx =
1092 &g_array_index (common->index, GstMatroskaIndex, i);
1095 GST_DEBUG_OBJECT (common, "Index entry: pos=%" G_GUINT64_FORMAT
1096 ", time=%" GST_TIME_FORMAT ", track=%u, block=%u", idx->pos,
1097 GST_TIME_ARGS (idx->time), (guint) idx->track, (guint) idx->block);
1101 GST_DEBUG_OBJECT (common, "Empty CuePoint");
1108 gst_matroska_read_common_stream_from_num (GstMatroskaReadCommon * common,
1113 g_assert (common->src->len == common->num_streams);
1114 for (n = 0; n < common->src->len; n++) {
1115 GstMatroskaTrackContext *context = g_ptr_array_index (common->src, n);
1117 if (context->num == track_num) {
1122 if (n == common->num_streams)
1123 GST_WARNING_OBJECT (common,
1124 "Failed to find corresponding pad for tracknum %d", track_num);
1130 gst_matroska_read_common_parse_index (GstMatroskaReadCommon * common,
1134 GstFlowReturn ret = GST_FLOW_OK;
1138 g_array_free (common->index, TRUE);
1140 g_array_sized_new (FALSE, FALSE, sizeof (GstMatroskaIndex), 128);
1142 DEBUG_ELEMENT_START (common, ebml, "Cues");
1144 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
1145 DEBUG_ELEMENT_STOP (common, ebml, "Cues", ret);
1149 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1150 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1154 /* one single index entry ('point') */
1155 case GST_MATROSKA_ID_POINTENTRY:
1156 ret = gst_matroska_read_common_parse_index_pointentry (common, ebml);
1160 ret = gst_matroska_read_common_parse_skip (common, ebml, "Cues", id);
1164 DEBUG_ELEMENT_STOP (common, ebml, "Cues", ret);
1166 /* Sort index by time, smallest time first, for easier searching */
1167 g_array_sort (common->index, (GCompareFunc) gst_matroska_index_compare);
1169 /* Now sort the track specific index entries into their own arrays */
1170 for (i = 0; i < common->index->len; i++) {
1171 GstMatroskaIndex *idx = &g_array_index (common->index, GstMatroskaIndex,
1174 GstMatroskaTrackContext *ctx;
1177 if (common->element_index) {
1180 if (idx->track != 0 &&
1182 gst_matroska_read_common_stream_from_num (common,
1183 idx->track)) != -1) {
1184 ctx = g_ptr_array_index (common->src, track_num);
1186 if (ctx->index_writer_id == -1)
1187 gst_index_get_writer_id (common->element_index,
1188 GST_OBJECT (ctx->pad), &ctx->index_writer_id);
1189 writer_id = ctx->index_writer_id;
1191 if (common->element_index_writer_id == -1)
1192 gst_index_get_writer_id (common->element_index, GST_OBJECT (common),
1193 &common->element_index_writer_id);
1194 writer_id = common->element_index_writer_id;
1197 GST_LOG_OBJECT (common, "adding association %" GST_TIME_FORMAT "-> %"
1198 G_GUINT64_FORMAT " for writer id %d", GST_TIME_ARGS (idx->time),
1199 idx->pos, writer_id);
1200 gst_index_add_association (common->element_index, writer_id,
1201 GST_ASSOCIATION_FLAG_KEY_UNIT, GST_FORMAT_TIME, idx->time,
1202 GST_FORMAT_BYTES, idx->pos + common->ebml_segment_start, NULL);
1206 if (idx->track == 0)
1209 track_num = gst_matroska_read_common_stream_from_num (common, idx->track);
1210 if (track_num == -1)
1213 ctx = g_ptr_array_index (common->src, track_num);
1215 if (ctx->index_table == NULL)
1217 g_array_sized_new (FALSE, FALSE, sizeof (GstMatroskaIndex), 128);
1219 g_array_append_vals (ctx->index_table, idx, 1);
1222 common->index_parsed = TRUE;
1224 /* sanity check; empty index normalizes to no index */
1225 if (common->index->len == 0) {
1226 g_array_free (common->index, TRUE);
1227 common->index = NULL;
1234 gst_matroska_read_common_parse_info (GstMatroskaReadCommon * common,
1235 GstElement * el, GstEbmlRead * ebml)
1237 GstFlowReturn ret = GST_FLOW_OK;
1238 gdouble dur_f = -1.0;
1241 DEBUG_ELEMENT_START (common, ebml, "SegmentInfo");
1243 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
1244 DEBUG_ELEMENT_STOP (common, ebml, "SegmentInfo", ret);
1248 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1249 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1253 /* cluster timecode */
1254 case GST_MATROSKA_ID_TIMECODESCALE:{
1257 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1261 GST_DEBUG_OBJECT (common, "TimeCodeScale: %" G_GUINT64_FORMAT, num);
1262 common->time_scale = num;
1266 case GST_MATROSKA_ID_DURATION:{
1267 if ((ret = gst_ebml_read_float (ebml, &id, &dur_f)) != GST_FLOW_OK)
1271 GST_WARNING_OBJECT (common, "Invalid duration %lf", dur_f);
1275 GST_DEBUG_OBJECT (common, "Duration: %lf", dur_f);
1279 case GST_MATROSKA_ID_WRITINGAPP:{
1282 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1285 GST_DEBUG_OBJECT (common, "WritingApp: %s", GST_STR_NULL (text));
1286 common->writing_app = text;
1290 case GST_MATROSKA_ID_MUXINGAPP:{
1293 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1296 GST_DEBUG_OBJECT (common, "MuxingApp: %s", GST_STR_NULL (text));
1297 common->muxing_app = text;
1301 case GST_MATROSKA_ID_DATEUTC:{
1304 if ((ret = gst_ebml_read_date (ebml, &id, &time)) != GST_FLOW_OK)
1307 GST_DEBUG_OBJECT (common, "DateUTC: %" G_GINT64_FORMAT, time);
1308 common->created = time;
1312 case GST_MATROSKA_ID_TITLE:{
1314 GstTagList *taglist;
1316 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1319 GST_DEBUG_OBJECT (common, "Title: %s", GST_STR_NULL (text));
1320 taglist = gst_tag_list_new (GST_TAG_TITLE, text, NULL);
1321 gst_matroska_read_common_found_global_tag (common, el, taglist);
1327 ret = gst_matroska_read_common_parse_skip (common, ebml,
1332 case GST_MATROSKA_ID_SEGMENTUID:
1333 case GST_MATROSKA_ID_SEGMENTFILENAME:
1334 case GST_MATROSKA_ID_PREVUID:
1335 case GST_MATROSKA_ID_PREVFILENAME:
1336 case GST_MATROSKA_ID_NEXTUID:
1337 case GST_MATROSKA_ID_NEXTFILENAME:
1338 case GST_MATROSKA_ID_SEGMENTFAMILY:
1339 case GST_MATROSKA_ID_CHAPTERTRANSLATE:
1340 ret = gst_ebml_read_skip (ebml);
1348 dur_u = gst_gdouble_to_guint64 (dur_f *
1349 gst_guint64_to_gdouble (common->time_scale));
1350 if (GST_CLOCK_TIME_IS_VALID (dur_u) && dur_u <= G_MAXINT64)
1351 common->segment.duration = dur_u;
1354 DEBUG_ELEMENT_STOP (common, ebml, "SegmentInfo", ret);
1356 common->segmentinfo_parsed = TRUE;
1361 static GstFlowReturn
1362 gst_matroska_read_common_parse_metadata_id_simple_tag (GstMatroskaReadCommon *
1363 common, GstEbmlRead * ebml, GstTagList ** p_taglist)
1365 /* FIXME: check if there are more useful mappings */
1368 const gchar *matroska_tagname;
1369 const gchar *gstreamer_tagname;
1373 GST_MATROSKA_TAG_ID_TITLE, GST_TAG_TITLE}, {
1374 GST_MATROSKA_TAG_ID_ARTIST, GST_TAG_ARTIST}, {
1375 GST_MATROSKA_TAG_ID_AUTHOR, GST_TAG_ARTIST}, {
1376 GST_MATROSKA_TAG_ID_ALBUM, GST_TAG_ALBUM}, {
1377 GST_MATROSKA_TAG_ID_COMMENTS, GST_TAG_COMMENT}, {
1378 GST_MATROSKA_TAG_ID_BITSPS, GST_TAG_BITRATE}, {
1379 GST_MATROSKA_TAG_ID_BPS, GST_TAG_BITRATE}, {
1380 GST_MATROSKA_TAG_ID_ENCODER, GST_TAG_ENCODER}, {
1381 GST_MATROSKA_TAG_ID_DATE, GST_TAG_DATE}, {
1382 GST_MATROSKA_TAG_ID_ISRC, GST_TAG_ISRC}, {
1383 GST_MATROSKA_TAG_ID_COPYRIGHT, GST_TAG_COPYRIGHT}, {
1384 GST_MATROSKA_TAG_ID_BPM, GST_TAG_BEATS_PER_MINUTE}, {
1385 GST_MATROSKA_TAG_ID_TERMS_OF_USE, GST_TAG_LICENSE}, {
1386 GST_MATROSKA_TAG_ID_COMPOSER, GST_TAG_COMPOSER}, {
1387 GST_MATROSKA_TAG_ID_LEAD_PERFORMER, GST_TAG_PERFORMER}, {
1388 GST_MATROSKA_TAG_ID_GENRE, GST_TAG_GENRE}
1392 gchar *value = NULL;
1395 DEBUG_ELEMENT_START (common, ebml, "SimpleTag");
1397 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
1398 DEBUG_ELEMENT_STOP (common, ebml, "SimpleTag", ret);
1402 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1403 /* read all sub-entries */
1405 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1409 case GST_MATROSKA_ID_TAGNAME:
1412 ret = gst_ebml_read_ascii (ebml, &id, &tag);
1413 GST_DEBUG_OBJECT (common, "TagName: %s", GST_STR_NULL (tag));
1416 case GST_MATROSKA_ID_TAGSTRING:
1419 ret = gst_ebml_read_utf8 (ebml, &id, &value);
1420 GST_DEBUG_OBJECT (common, "TagString: %s", GST_STR_NULL (value));
1424 ret = gst_matroska_read_common_parse_skip (common, ebml, "SimpleTag",
1429 case GST_MATROSKA_ID_TAGLANGUAGE:
1430 case GST_MATROSKA_ID_TAGDEFAULT:
1431 case GST_MATROSKA_ID_TAGBINARY:
1432 ret = gst_ebml_read_skip (ebml);
1437 DEBUG_ELEMENT_STOP (common, ebml, "SimpleTag", ret);
1442 for (i = 0; i < G_N_ELEMENTS (tag_conv); i++) {
1443 const gchar *tagname_gst = tag_conv[i].gstreamer_tagname;
1445 const gchar *tagname_mkv = tag_conv[i].matroska_tagname;
1447 if (strcmp (tagname_mkv, tag) == 0) {
1448 GValue dest = { 0, };
1449 GType dest_type = gst_tag_get_type (tagname_gst);
1451 /* Ensure that any date string is complete */
1452 if (dest_type == GST_TYPE_DATE) {
1453 guint year = 1901, month = 1, day = 1;
1455 /* Dates can be yyyy-MM-dd, yyyy-MM or yyyy, but we need
1457 if (sscanf (value, "%04u-%02u-%02u", &year, &month, &day) != 0) {
1459 value = g_strdup_printf ("%04u-%02u-%02u", year, month, day);
1463 g_value_init (&dest, dest_type);
1464 if (gst_value_deserialize (&dest, value)) {
1465 gst_tag_list_add_values (*p_taglist, GST_TAG_MERGE_APPEND,
1466 tagname_gst, &dest, NULL);
1468 GST_WARNING_OBJECT (common, "Can't transform tag '%s' with "
1469 "value '%s' to target type '%s'", tag, value,
1470 g_type_name (dest_type));
1472 g_value_unset (&dest);
1484 static GstFlowReturn
1485 gst_matroska_read_common_parse_metadata_id_tag (GstMatroskaReadCommon * common,
1486 GstEbmlRead * ebml, GstTagList ** p_taglist)
1491 DEBUG_ELEMENT_START (common, ebml, "Tag");
1493 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
1494 DEBUG_ELEMENT_STOP (common, ebml, "Tag", ret);
1498 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1499 /* read all sub-entries */
1501 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1505 case GST_MATROSKA_ID_SIMPLETAG:
1506 ret = gst_matroska_read_common_parse_metadata_id_simple_tag (common,
1511 ret = gst_matroska_read_common_parse_skip (common, ebml, "Tag", id);
1516 DEBUG_ELEMENT_STOP (common, ebml, "Tag", ret);
1522 gst_matroska_read_common_parse_metadata (GstMatroskaReadCommon * common,
1523 GstElement * el, GstEbmlRead * ebml)
1525 GstTagList *taglist;
1526 GstFlowReturn ret = GST_FLOW_OK;
1531 curpos = gst_ebml_read_get_pos (ebml);
1533 /* Make sure we don't parse a tags element twice and
1534 * post it's tags twice */
1535 curpos = gst_ebml_read_get_pos (ebml);
1536 for (l = common->tags_parsed; l; l = l->next) {
1537 guint64 *pos = l->data;
1539 if (*pos == curpos) {
1540 GST_DEBUG_OBJECT (common, "Skipping already parsed Tags at offset %"
1541 G_GUINT64_FORMAT, curpos);
1546 common->tags_parsed =
1547 g_list_prepend (common->tags_parsed, g_slice_new (guint64));
1548 *((guint64 *) common->tags_parsed->data) = curpos;
1551 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
1552 DEBUG_ELEMENT_STOP (common, ebml, "Tags", ret);
1556 taglist = gst_tag_list_new_empty ();
1558 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1559 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1563 case GST_MATROSKA_ID_TAG:
1564 ret = gst_matroska_read_common_parse_metadata_id_tag (common, ebml,
1569 ret = gst_matroska_read_common_parse_skip (common, ebml, "Tags", id);
1571 /* FIXME: Use to limit the tags to specific pads */
1572 case GST_MATROSKA_ID_TARGETS:
1573 ret = gst_ebml_read_skip (ebml);
1578 DEBUG_ELEMENT_STOP (common, ebml, "Tags", ret);
1580 gst_matroska_read_common_found_global_tag (common, el, taglist);
1585 static GstFlowReturn
1586 gst_matroska_read_common_peek_adapter (GstMatroskaReadCommon * common, guint
1587 peek, const guint8 ** data)
1589 /* Caller needs to gst_adapter_unmap. */
1590 *data = gst_adapter_map (common->adapter, peek);
1592 return GST_FLOW_EOS;
1598 * Calls pull_range for (offset,size) without advancing our offset
1601 gst_matroska_read_common_peek_bytes (GstMatroskaReadCommon * common, guint64
1602 offset, guint size, GstBuffer ** p_buf, guint8 ** bytes)
1606 /* Caching here actually makes much less difference than one would expect.
1607 * We do it mainly to avoid pulling buffers of 1 byte all the time */
1608 if (common->cached_buffer) {
1609 guint64 cache_offset = GST_BUFFER_OFFSET (common->cached_buffer);
1610 gsize cache_size = gst_buffer_get_size (common->cached_buffer);
1612 if (cache_offset <= common->offset &&
1613 (common->offset + size) <= (cache_offset + cache_size)) {
1615 *p_buf = gst_buffer_copy_region (common->cached_buffer,
1616 GST_BUFFER_COPY_ALL, common->offset - cache_offset, size);
1618 if (!common->cached_data)
1619 common->cached_data = gst_buffer_map (common->cached_buffer,
1620 NULL, NULL, GST_MAP_READ);
1621 *bytes = common->cached_data + common->offset - cache_offset;
1625 /* not enough data in the cache, free cache and get a new one */
1626 if (common->cached_data) {
1627 gst_buffer_unmap (common->cached_buffer, common->cached_data, -1);
1628 common->cached_data = NULL;
1630 gst_buffer_unref (common->cached_buffer);
1631 common->cached_buffer = NULL;
1634 /* refill the cache */
1635 ret = gst_pad_pull_range (common->sinkpad, common->offset,
1636 MAX (size, 64 * 1024), &common->cached_buffer);
1637 if (ret != GST_FLOW_OK) {
1638 common->cached_buffer = NULL;
1642 if (gst_buffer_get_size (common->cached_buffer) >= size) {
1644 *p_buf = gst_buffer_copy_region (common->cached_buffer,
1645 GST_BUFFER_COPY_ALL, 0, size);
1647 common->cached_data = gst_buffer_map (common->cached_buffer,
1648 NULL, NULL, GST_MAP_READ);
1649 *bytes = common->cached_data;
1654 /* Not possible to get enough data, try a last time with
1655 * requesting exactly the size we need */
1656 gst_buffer_unref (common->cached_buffer);
1657 common->cached_buffer = NULL;
1660 gst_pad_pull_range (common->sinkpad, common->offset, size,
1661 &common->cached_buffer);
1662 if (ret != GST_FLOW_OK) {
1663 GST_DEBUG_OBJECT (common, "pull_range returned %d", ret);
1671 if (gst_buffer_get_size (common->cached_buffer) < size) {
1672 GST_WARNING_OBJECT (common, "Dropping short buffer at offset %"
1673 G_GUINT64_FORMAT ": wanted %u bytes, got %u bytes", common->offset,
1674 size, gst_buffer_get_size (common->cached_buffer));
1676 gst_buffer_unref (common->cached_buffer);
1677 common->cached_buffer = NULL;
1682 return GST_FLOW_EOS;
1686 *p_buf = gst_buffer_copy_region (common->cached_buffer,
1687 GST_BUFFER_COPY_ALL, 0, size);
1689 common->cached_data = gst_buffer_map (common->cached_buffer,
1690 NULL, NULL, GST_MAP_READ);
1691 *bytes = common->cached_data;
1697 static GstFlowReturn
1698 gst_matroska_read_common_peek_pull (GstMatroskaReadCommon * common, guint peek,
1701 return gst_matroska_read_common_peek_bytes (common, common->offset, peek,
1706 gst_matroska_read_common_peek_id_length_pull (GstMatroskaReadCommon * common,
1707 GstElement * el, guint32 * _id, guint64 * _length, guint * _needed)
1709 return gst_ebml_peek_id_length (_id, _length, _needed,
1710 (GstPeekData) gst_matroska_read_common_peek_pull, (gpointer) common, el,
1715 gst_matroska_read_common_peek_id_length_push (GstMatroskaReadCommon * common,
1716 GstElement * el, guint32 * _id, guint64 * _length, guint * _needed)
1720 ret = gst_ebml_peek_id_length (_id, _length, _needed,
1721 (GstPeekData) gst_matroska_read_common_peek_adapter, (gpointer) common,
1722 el, common->offset);
1724 gst_adapter_unmap (common->adapter);
1729 static GstFlowReturn
1730 gst_matroska_read_common_read_track_encoding (GstMatroskaReadCommon * common,
1731 GstEbmlRead * ebml, GstMatroskaTrackContext * context)
1733 GstMatroskaTrackEncoding enc = { 0, };
1737 DEBUG_ELEMENT_START (common, ebml, "ContentEncoding");
1738 /* Set default values */
1740 /* All other default values are 0 */
1742 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
1743 DEBUG_ELEMENT_STOP (common, ebml, "ContentEncoding", ret);
1747 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1748 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1752 case GST_MATROSKA_ID_CONTENTENCODINGORDER:{
1755 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1758 if (!gst_matroska_read_common_encoding_order_unique (context->encodings,
1760 GST_ERROR_OBJECT (common, "ContentEncodingOrder %" G_GUINT64_FORMAT
1761 "is not unique for track %d", num, context->num);
1762 ret = GST_FLOW_ERROR;
1766 GST_DEBUG_OBJECT (common, "ContentEncodingOrder: %" G_GUINT64_FORMAT,
1771 case GST_MATROSKA_ID_CONTENTENCODINGSCOPE:{
1774 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1777 if (num > 7 && num == 0) {
1778 GST_ERROR_OBJECT (common, "Invalid ContentEncodingScope %"
1779 G_GUINT64_FORMAT, num);
1780 ret = GST_FLOW_ERROR;
1784 GST_DEBUG_OBJECT (common, "ContentEncodingScope: %" G_GUINT64_FORMAT,
1790 case GST_MATROSKA_ID_CONTENTENCODINGTYPE:{
1793 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1797 GST_ERROR_OBJECT (common, "Invalid ContentEncodingType %"
1798 G_GUINT64_FORMAT, num);
1799 ret = GST_FLOW_ERROR;
1801 } else if (num != 0) {
1802 GST_ERROR_OBJECT (common, "Encrypted tracks are not supported yet");
1803 ret = GST_FLOW_ERROR;
1806 GST_DEBUG_OBJECT (common, "ContentEncodingType: %" G_GUINT64_FORMAT,
1811 case GST_MATROSKA_ID_CONTENTCOMPRESSION:{
1813 DEBUG_ELEMENT_START (common, ebml, "ContentCompression");
1815 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
1818 while (ret == GST_FLOW_OK &&
1819 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1820 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1824 case GST_MATROSKA_ID_CONTENTCOMPALGO:{
1827 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK) {
1831 GST_ERROR_OBJECT (common, "Invalid ContentCompAlgo %"
1832 G_GUINT64_FORMAT, num);
1833 ret = GST_FLOW_ERROR;
1836 GST_DEBUG_OBJECT (common, "ContentCompAlgo: %" G_GUINT64_FORMAT,
1838 enc.comp_algo = num;
1842 case GST_MATROSKA_ID_CONTENTCOMPSETTINGS:{
1847 gst_ebml_read_binary (ebml, &id, &data,
1848 &size)) != GST_FLOW_OK) {
1851 enc.comp_settings = data;
1852 enc.comp_settings_length = size;
1853 GST_DEBUG_OBJECT (common,
1854 "ContentCompSettings of size %" G_GUINT64_FORMAT, size);
1858 GST_WARNING_OBJECT (common,
1859 "Unknown ContentCompression subelement 0x%x - ignoring", id);
1860 ret = gst_ebml_read_skip (ebml);
1864 DEBUG_ELEMENT_STOP (common, ebml, "ContentCompression", ret);
1868 case GST_MATROSKA_ID_CONTENTENCRYPTION:
1869 GST_ERROR_OBJECT (common, "Encrypted tracks not yet supported");
1870 gst_ebml_read_skip (ebml);
1871 ret = GST_FLOW_ERROR;
1874 GST_WARNING_OBJECT (common,
1875 "Unknown ContentEncoding subelement 0x%x - ignoring", id);
1876 ret = gst_ebml_read_skip (ebml);
1881 DEBUG_ELEMENT_STOP (common, ebml, "ContentEncoding", ret);
1882 if (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)
1885 /* TODO: Check if the combination of values is valid */
1887 g_array_append_val (context->encodings, enc);
1893 gst_matroska_read_common_read_track_encodings (GstMatroskaReadCommon * common,
1894 GstEbmlRead * ebml, GstMatroskaTrackContext * context)
1899 DEBUG_ELEMENT_START (common, ebml, "ContentEncodings");
1901 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
1902 DEBUG_ELEMENT_STOP (common, ebml, "ContentEncodings", ret);
1906 context->encodings =
1907 g_array_sized_new (FALSE, FALSE, sizeof (GstMatroskaTrackEncoding), 1);
1909 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1910 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1914 case GST_MATROSKA_ID_CONTENTENCODING:
1915 ret = gst_matroska_read_common_read_track_encoding (common, ebml,
1919 GST_WARNING_OBJECT (common,
1920 "Unknown ContentEncodings subelement 0x%x - ignoring", id);
1921 ret = gst_ebml_read_skip (ebml);
1926 DEBUG_ELEMENT_STOP (common, ebml, "ContentEncodings", ret);
1927 if (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)
1930 /* Sort encodings according to their order */
1931 g_array_sort (context->encodings,
1932 (GCompareFunc) gst_matroska_read_common_encoding_cmp);
1934 return gst_matroska_decode_content_encodings (context->encodings);
1937 /* call with object lock held */
1939 gst_matroska_read_common_reset_streams (GstMatroskaReadCommon * common,
1940 GstClockTime time, gboolean full)
1944 GST_DEBUG_OBJECT (common, "resetting stream state");
1946 g_assert (common->src->len == common->num_streams);
1947 for (i = 0; i < common->src->len; i++) {
1948 GstMatroskaTrackContext *context = g_ptr_array_index (common->src, i);
1949 context->pos = time;
1950 context->set_discont = TRUE;
1951 context->eos = FALSE;
1952 context->from_time = GST_CLOCK_TIME_NONE;
1954 context->last_flow = GST_FLOW_OK;
1955 if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
1956 GstMatroskaTrackVideoContext *videocontext =
1957 (GstMatroskaTrackVideoContext *) context;
1958 /* demux object lock held by caller */
1959 videocontext->earliest_time = GST_CLOCK_TIME_NONE;
1965 gst_matroska_read_common_tracknumber_unique (GstMatroskaReadCommon * common,
1970 g_assert (common->src->len == common->num_streams);
1971 for (i = 0; i < common->src->len; i++) {
1972 GstMatroskaTrackContext *context = g_ptr_array_index (common->src, i);
1974 if (context->num == num)