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., 51 Franklin St, Fifth Floor,
22 * Boston, MA 02110-1301, USA.
40 #include <gst/tag/tag.h>
41 #include <gst/base/gsttypefindhelper.h>
42 #include <gst/base/gstbytewriter.h>
46 #include "ebml-read.h"
47 #include "matroska-read-common.h"
48 #include "matroska-ids.h"
50 GST_DEBUG_CATEGORY (matroskareadcommon_debug);
51 #define GST_CAT_DEFAULT matroskareadcommon_debug
53 #define DEBUG_ELEMENT_START(common, ebml, element) \
54 GST_DEBUG_OBJECT (common->sinkpad, "Parsing " element " element at offset %" \
55 G_GUINT64_FORMAT, gst_ebml_read_get_pos (ebml))
57 #define DEBUG_ELEMENT_STOP(common, ebml, element, ret) \
58 GST_DEBUG_OBJECT (common->sinkpad, "Parsing " element " element " \
59 " finished with '%s'", gst_flow_get_name (ret))
61 #define GST_MATROSKA_TOC_UID_CHAPTER "chapter"
62 #define GST_MATROSKA_TOC_UID_EDITION "edition"
63 #define GST_MATROSKA_TOC_UID_EMPTY "empty"
68 guint64 target_type_value;
75 gst_matroska_decompress_data (GstMatroskaTrackEncoding * enc,
76 gpointer * data_out, gsize * size_out,
77 GstMatroskaTrackCompressionAlgorithm algo)
79 guint8 *new_data = NULL;
81 guint8 *data = *data_out;
82 guint size = *size_out;
85 if (algo == GST_MATROSKA_TRACK_COMPRESSION_ALGORITHM_ZLIB) {
87 /* zlib encoded data */
93 zstream.zalloc = (alloc_func) 0;
94 zstream.zfree = (free_func) 0;
95 zstream.opaque = (voidpf) 0;
96 if (inflateInit (&zstream) != Z_OK) {
97 GST_WARNING ("zlib initialization failed.");
101 zstream.next_in = (Bytef *) data;
102 zstream.avail_in = orig_size;
103 new_size = orig_size;
104 new_data = g_malloc (new_size);
105 zstream.avail_out = new_size;
106 zstream.next_out = (Bytef *) new_data;
109 result = inflate (&zstream, Z_NO_FLUSH);
110 if (result == Z_STREAM_END) {
112 } else if (result != Z_OK) {
113 GST_WARNING ("inflate() returned %d", result);
118 new_data = g_realloc (new_data, new_size);
119 zstream.next_out = (Bytef *) (new_data + zstream.total_out);
120 zstream.avail_out += 4096;
121 } while (zstream.avail_in > 0);
123 if (result != Z_STREAM_END) {
127 new_size = zstream.total_out;
129 inflateEnd (&zstream);
132 GST_WARNING ("zlib encoded tracks not supported.");
136 } else if (algo == GST_MATROSKA_TRACK_COMPRESSION_ALGORITHM_BZLIB) {
138 /* bzip2 encoded data */
143 bzstream.bzalloc = NULL;
144 bzstream.bzfree = NULL;
145 bzstream.opaque = NULL;
148 if (BZ2_bzDecompressInit (&bzstream, 0, 0) != BZ_OK) {
149 GST_WARNING ("bzip2 initialization failed.");
154 bzstream.next_in = (char *) data;
155 bzstream.avail_in = orig_size;
156 new_size = orig_size;
157 new_data = g_malloc (new_size);
158 bzstream.avail_out = new_size;
159 bzstream.next_out = (char *) new_data;
162 result = BZ2_bzDecompress (&bzstream);
163 if (result == BZ_STREAM_END) {
165 } else if (result != BZ_OK) {
166 GST_WARNING ("BZ2_bzDecompress() returned %d", result);
171 new_data = g_realloc (new_data, new_size);
172 bzstream.next_out = (char *) (new_data + bzstream.total_out_lo32);
173 bzstream.avail_out += 4096;
174 } while (bzstream.avail_in > 0);
176 if (result != BZ_STREAM_END) {
180 new_size = bzstream.total_out_lo32;
182 BZ2_bzDecompressEnd (&bzstream);
185 GST_WARNING ("bzip2 encoded tracks not supported.");
189 } else if (algo == GST_MATROSKA_TRACK_COMPRESSION_ALGORITHM_LZO1X) {
190 /* lzo encoded data */
192 int orig_size, out_size;
197 new_data = g_malloc (new_size);
203 result = lzo1x_decode (new_data, &out_size, data, &orig_size);
207 new_data = g_realloc (new_data, new_size);
209 } while (orig_size > 0 && result == LZO_OUTPUT_FULL);
211 new_size -= out_size;
213 if (result != LZO_OUTPUT_FULL) {
214 GST_WARNING ("lzo decompression failed");
221 } else if (algo == GST_MATROSKA_TRACK_COMPRESSION_ALGORITHM_HEADERSTRIP) {
222 /* header stripped encoded data */
223 if (enc->comp_settings_length > 0) {
224 new_data = g_malloc (size + enc->comp_settings_length);
225 new_size = size + enc->comp_settings_length;
227 memcpy (new_data, enc->comp_settings, enc->comp_settings_length);
228 memcpy (new_data + enc->comp_settings_length, data, size);
231 GST_ERROR ("invalid compression algorithm %d", algo);
241 *data_out = new_data;
242 *size_out = new_size;
249 gst_matroska_decode_content_encodings (GArray * encodings)
253 if (encodings == NULL)
256 for (i = 0; i < encodings->len; i++) {
257 GstMatroskaTrackEncoding *enc =
258 &g_array_index (encodings, GstMatroskaTrackEncoding, i);
259 gpointer data = NULL;
262 if ((enc->scope & GST_MATROSKA_TRACK_ENCODING_SCOPE_NEXT_CONTENT_ENCODING)
266 /* Other than ENCODING_COMPRESSION not handled here */
267 if (enc->type != GST_MATROSKA_ENCODING_COMPRESSION)
270 if (i + 1 >= encodings->len)
271 return GST_FLOW_ERROR;
273 if (enc->comp_settings_length == 0)
276 data = enc->comp_settings;
277 size = enc->comp_settings_length;
279 if (!gst_matroska_decompress_data (enc, &data, &size, enc->comp_algo))
280 return GST_FLOW_ERROR;
282 g_free (enc->comp_settings);
284 enc->comp_settings = data;
285 enc->comp_settings_length = size;
292 gst_matroska_decode_data (GArray * encodings, gpointer * data_out,
293 gsize * size_out, GstMatroskaTrackEncodingScope scope, gboolean free)
300 g_return_val_if_fail (encodings != NULL, FALSE);
301 g_return_val_if_fail (data_out != NULL && *data_out != NULL, FALSE);
302 g_return_val_if_fail (size_out != NULL, FALSE);
307 for (i = 0; i < encodings->len; i++) {
308 GstMatroskaTrackEncoding *enc =
309 &g_array_index (encodings, GstMatroskaTrackEncoding, i);
310 gpointer new_data = NULL;
313 if ((enc->scope & scope) == 0)
316 /* Encryption not handled here */
317 if (enc->type != GST_MATROSKA_ENCODING_COMPRESSION) {
326 gst_matroska_decompress_data (enc, &new_data, &new_size,
332 if ((data == *data_out && free) || (data != *data_out))
340 if ((data == *data_out && free) || (data != *data_out))
353 /* This function parses the protection info of Block/SimpleBlock and extracts the
354 * IV and partitioning format (subsample) information.
355 * Set those parsed information into protection info structure @info_protect which
356 * will be added in protection metadata of the Gstbuffer.
357 * The subsamples format follows the same pssh box format in Common Encryption spec:
358 * subsample number + clear subsample size (16bit bigendian) | encrypted subsample size (32bit bigendian) | ...
359 * @encrypted is an output argument: TRUE if the current Block/SimpleBlock is encrypted else FALSE
362 gst_matroska_parse_protection_meta (gpointer * data_out, gsize * size_out,
363 GstStructure * info_protect, gboolean * encrypted)
371 GstByteReader reader;
373 g_return_val_if_fail (data_out != NULL && *data_out != NULL, FALSE);
374 g_return_val_if_fail (size_out != NULL, FALSE);
375 g_return_val_if_fail (info_protect != NULL, FALSE);
376 g_return_val_if_fail (encrypted != NULL, FALSE);
380 gst_byte_reader_init (&reader, data, *size_out);
383 * 4.7 Signal Byte Format
390 * If set, another signal byte will follow this byte. Reserved for future expansion (currently MUST be set to 0).
392 * Bits reserved for future use. MUST be set to 0 and MUST be ignored.
394 * If set, the Block MUST contain an IV immediately followed by an encrypted frame. If not set, the Block MUST NOT include an IV and the frame MUST be unencrypted. The unencrypted frame MUST immediately follow the Signal Byte.
395 * Partitioned bit (P)
396 * Used to indicate that the sample has subsample partitions. If set, the IV will be followed by a num_partitions byte, and num_partitions * 32-bit partition offsets. This bit can only be set if the E bit is also set.
398 if (!gst_byte_reader_get_uint8 (&reader, &signal_byte)) {
399 GST_ERROR ("Error reading the signal byte");
403 /* Unencrypted buffer */
404 if (!(signal_byte & GST_MATROSKA_BLOCK_ENCRYPTED)) {
408 /* Encrypted buffer */
410 /* Create IV buffer */
411 if (!gst_byte_reader_dup_data (&reader, sizeof (guint64), &data_iv)) {
412 GST_ERROR ("Error reading the IV data");
415 buf_iv = gst_buffer_new_wrapped ((gpointer) data_iv, sizeof (guint64));
416 gst_structure_set (info_protect, "iv", GST_TYPE_BUFFER, buf_iv, NULL);
417 gst_buffer_unref (buf_iv);
419 /* Partitioned in subsample */
420 if (signal_byte & GST_MATROSKA_BLOCK_PARTITIONED) {
424 guint32 encrypted_bytes = 0;
425 guint16 clear_bytes = 0;
426 GstBuffer *buf_sub_sample;
428 GstByteWriter writer;
430 /* Read the number of partitions (1 byte) */
431 if (!gst_byte_reader_get_uint8 (&reader, &nb_part)) {
432 GST_ERROR ("Error reading the partition number");
437 GST_ERROR ("Partitioned, but the subsample number equal to zero");
441 nb_subsample = (nb_part + 2) >> 1;
443 gst_structure_set (info_protect, "subsample_count", G_TYPE_UINT,
448 * 4.6 Subsample Encrypted Block Format
450 * The Subsample Encrypted Block format extends the Full-sample format by setting a "partitioned" (P) bit in the Signal Byte.
451 * If this bit is set, the EncryptedBlock header shall include an
452 * 8-bit integer indicating the number of sample partitions (dividers between clear/encrypted sections),
453 * and a series of 32-bit integers in big-endian encoding indicating the byte offsets of such partitions.
456 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
457 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
459 * +-+-+-+-+-+-+-+-+ IV |
461 * | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
462 * | | num_partition | Partition 0 offset -> |
463 * |-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-|
464 * | -> Partition 0 offset | ... |
465 * |-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-|
466 * | ... | Partition n-1 offset -> |
467 * |-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-|
468 * | -> Partition n-1 offset | |
469 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
470 * | Clear/encrypted sample data |
473 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
475 * 4.6.1 SAMPLE PARTITIONS
477 * The samples shall be partitioned into alternating clear and encrypted sections,
478 * always starting with a clear section.
479 * Generally for n clear/encrypted sections there shall be n-1 partition offsets.
480 * However, if it is required that the first section be encrypted, then the first partition shall be at byte offset 0
481 * (indicating a zero-size clear section), and there shall be n partition offsets.
482 * Please refer to the "Sample Encryption" description of the "Common Encryption"
483 * section of the VP Codec ISO Media File Format Binding Specification for more
484 * detail on how subsample encryption is implemented.
487 g_malloc (nb_subsample * (sizeof (guint16) + sizeof (guint32)));
489 gst_byte_writer_init_with_data (&writer, subsamples,
490 nb_subsample * (sizeof (guint16) + sizeof (guint32)), FALSE);
492 for (i = 0; i <= nb_part; i++) {
493 offset_prev = offset;
495 offset = gst_byte_reader_get_remaining (&reader);
497 if (!gst_byte_reader_get_uint32_be (&reader, &offset)) {
498 GST_ERROR ("Error reading the partition offset");
503 if (offset < offset_prev) {
504 GST_ERROR ("Partition offsets should not decrease");
509 if ((offset - offset_prev) & 0xFFFF0000) {
511 ("The Clear Partition exceed 64KB in encrypted subsample format");
514 /* We set the Clear partition size in 16 bits, in order to
515 * follow the same format of the box PSSH in CENC spec */
516 clear_bytes = offset - offset_prev;
520 encrypted_bytes = offset - offset_prev;
523 if ((i % 2 == 1) || (i == nb_part)) {
524 if (clear_bytes == 0 && encrypted_bytes == 0) {
525 GST_ERROR ("Found 2 partitions with the same offsets.");
528 if (!gst_byte_writer_put_uint16_be (&writer, clear_bytes)) {
529 GST_ERROR ("Error writing the number of clear bytes");
532 if (!gst_byte_writer_put_uint32_be (&writer, encrypted_bytes)) {
533 GST_ERROR ("Error writing the number of encrypted bytes");
540 gst_buffer_new_wrapped (subsamples,
541 nb_subsample * (sizeof (guint16) + sizeof (guint32)));
542 gst_structure_set (info_protect, "subsamples", GST_TYPE_BUFFER,
543 buf_sub_sample, NULL);
544 gst_buffer_unref (buf_sub_sample);
546 gst_structure_set (info_protect, "subsample_count", G_TYPE_UINT, 0, NULL);
549 gst_byte_reader_get_data (&reader, 0, (const guint8 **) data_out);
550 *size_out = gst_byte_reader_get_remaining (&reader);
559 gst_matroska_index_compare (GstMatroskaIndex * i1, GstMatroskaIndex * i2)
561 if (i1->time < i2->time)
563 else if (i1->time > i2->time)
565 else if (i1->block < i2->block)
567 else if (i1->block > i2->block)
574 gst_matroska_index_seek_find (GstMatroskaIndex * i1, GstClockTime * time,
577 if (i1->time < *time)
579 else if (i1->time > *time)
586 gst_matroska_read_common_do_index_seek (GstMatroskaReadCommon * common,
587 GstMatroskaTrackContext * track, gint64 seek_pos, GArray ** _index,
588 gint * _entry_index, GstSearchMode snap_dir)
590 GstMatroskaIndex *entry = NULL;
593 /* find entry just before or at the requested position */
594 if (track && track->index_table)
595 index = track->index_table;
597 index = common->index;
599 if (!index || !index->len)
603 gst_util_array_binary_search (index->data, index->len,
604 sizeof (GstMatroskaIndex),
605 (GCompareDataFunc) gst_matroska_index_seek_find, snap_dir, &seek_pos,
609 if (snap_dir == GST_SEARCH_MODE_AFTER) {
610 /* Can only happen with a reverse seek past the end */
611 entry = &g_array_index (index, GstMatroskaIndex, index->len - 1);
613 /* Can only happen with a forward seek before the start */
614 entry = &g_array_index (index, GstMatroskaIndex, 0);
621 *_entry_index = entry - (GstMatroskaIndex *) index->data;
627 gst_matroska_read_common_encoding_cmp (GstMatroskaTrackEncoding * a,
628 GstMatroskaTrackEncoding * b)
630 if (b->order > a->order)
632 else if (b->order < a->order)
639 gst_matroska_read_common_encoding_order_unique (GArray * encodings, guint64
644 if (encodings == NULL || encodings->len == 0)
647 for (i = 0; i < encodings->len; i++)
648 if (g_array_index (encodings, GstMatroskaTrackEncoding, i).order == order)
654 /* takes ownership of taglist */
656 gst_matroska_read_common_found_global_tag (GstMatroskaReadCommon * common,
657 GstElement * el, GstTagList * taglist)
659 if (common->global_tags) {
660 gst_tag_list_insert (common->global_tags, taglist, GST_TAG_MERGE_APPEND);
661 gst_tag_list_unref (taglist);
663 common->global_tags = taglist;
665 common->global_tags_changed = TRUE;
669 gst_matroska_read_common_get_length (GstMatroskaReadCommon * common)
673 if (!gst_pad_peer_query_duration (common->sinkpad, GST_FORMAT_BYTES,
675 GST_DEBUG_OBJECT (common->sinkpad, "no upstream length");
680 /* determine track to seek in */
681 GstMatroskaTrackContext *
682 gst_matroska_read_common_get_seek_track (GstMatroskaReadCommon * common,
683 GstMatroskaTrackContext * track)
687 if (track && track->type == GST_MATROSKA_TRACK_TYPE_VIDEO)
690 for (i = 0; i < common->src->len; i++) {
691 GstMatroskaTrackContext *stream;
693 stream = g_ptr_array_index (common->src, i);
694 if (stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO && stream->index_table)
701 /* skip unknown or alike element */
703 gst_matroska_read_common_parse_skip (GstMatroskaReadCommon * common,
704 GstEbmlRead * ebml, const gchar * parent_name, guint id)
706 if (id == GST_EBML_ID_VOID) {
707 GST_DEBUG_OBJECT (common->sinkpad, "Skipping EBML Void element");
708 } else if (id == GST_EBML_ID_CRC32) {
709 GST_DEBUG_OBJECT (common->sinkpad, "Skipping EBML CRC32 element");
711 GST_WARNING_OBJECT (common->sinkpad,
712 "Unknown %s subelement 0x%x - ignoring", parent_name, id);
715 return gst_ebml_read_skip (ebml);
719 gst_matroska_read_common_parse_attached_file (GstMatroskaReadCommon * common,
720 GstEbmlRead * ebml, GstTagList * taglist)
724 gchar *description = NULL;
725 gchar *filename = NULL;
726 gchar *mimetype = NULL;
730 DEBUG_ELEMENT_START (common, ebml, "AttachedFile");
732 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
733 DEBUG_ELEMENT_STOP (common, ebml, "AttachedFile", ret);
737 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
738 /* read all sub-entries */
740 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
744 case GST_MATROSKA_ID_FILEDESCRIPTION:
746 GST_WARNING_OBJECT (common->sinkpad,
747 "FileDescription can only appear once");
751 ret = gst_ebml_read_utf8 (ebml, &id, &description);
752 GST_DEBUG_OBJECT (common->sinkpad, "FileDescription: %s",
753 GST_STR_NULL (description));
755 case GST_MATROSKA_ID_FILENAME:
757 GST_WARNING_OBJECT (common->sinkpad, "FileName can only appear once");
761 ret = gst_ebml_read_utf8 (ebml, &id, &filename);
763 GST_DEBUG_OBJECT (common->sinkpad, "FileName: %s",
764 GST_STR_NULL (filename));
766 case GST_MATROSKA_ID_FILEMIMETYPE:
768 GST_WARNING_OBJECT (common->sinkpad,
769 "FileMimeType can only appear once");
773 ret = gst_ebml_read_ascii (ebml, &id, &mimetype);
774 GST_DEBUG_OBJECT (common->sinkpad, "FileMimeType: %s",
775 GST_STR_NULL (mimetype));
777 case GST_MATROSKA_ID_FILEDATA:
779 GST_WARNING_OBJECT (common->sinkpad, "FileData can only appear once");
783 ret = gst_ebml_read_binary (ebml, &id, &data, &datalen);
784 GST_DEBUG_OBJECT (common->sinkpad,
785 "FileData of size %" G_GUINT64_FORMAT, datalen);
789 ret = gst_matroska_read_common_parse_skip (common, ebml,
792 case GST_MATROSKA_ID_FILEUID:
793 ret = gst_ebml_read_skip (ebml);
798 DEBUG_ELEMENT_STOP (common, ebml, "AttachedFile", ret);
800 if (filename && mimetype && data && datalen > 0) {
801 GstTagImageType image_type = GST_TAG_IMAGE_TYPE_NONE;
802 GstBuffer *tagbuffer = NULL;
803 GstSample *tagsample = NULL;
804 GstStructure *info = NULL;
805 GstCaps *caps = NULL;
806 gchar *filename_lc = g_utf8_strdown (filename, -1);
808 GST_DEBUG_OBJECT (common->sinkpad, "Creating tag for attachment with "
809 "filename '%s', mimetype '%s', description '%s', "
810 "size %" G_GUINT64_FORMAT, filename, mimetype,
811 GST_STR_NULL (description), datalen);
813 /* TODO: better heuristics for different image types */
814 if (strstr (filename_lc, "cover")) {
815 if (strstr (filename_lc, "back"))
816 image_type = GST_TAG_IMAGE_TYPE_BACK_COVER;
818 image_type = GST_TAG_IMAGE_TYPE_FRONT_COVER;
819 } else if (g_str_has_prefix (mimetype, "image/") ||
820 g_str_has_suffix (filename_lc, "png") ||
821 g_str_has_suffix (filename_lc, "jpg") ||
822 g_str_has_suffix (filename_lc, "jpeg") ||
823 g_str_has_suffix (filename_lc, "gif") ||
824 g_str_has_suffix (filename_lc, "bmp")) {
825 image_type = GST_TAG_IMAGE_TYPE_UNDEFINED;
827 g_free (filename_lc);
829 /* First try to create an image tag buffer from this */
830 if (image_type != GST_TAG_IMAGE_TYPE_NONE) {
832 gst_tag_image_data_to_image_sample (data, datalen, image_type);
835 image_type = GST_TAG_IMAGE_TYPE_NONE;
837 tagbuffer = gst_buffer_ref (gst_sample_get_buffer (tagsample));
838 caps = gst_caps_ref (gst_sample_get_caps (tagsample));
839 info = gst_structure_copy (gst_sample_get_info (tagsample));
840 gst_sample_unref (tagsample);
844 /* if this failed create an attachment buffer */
846 tagbuffer = gst_buffer_new_wrapped (g_memdup (data, datalen), datalen);
848 caps = gst_type_find_helper_for_buffer (NULL, tagbuffer, NULL);
850 caps = gst_caps_new_empty_simple (mimetype);
853 /* Set filename and description in the info */
855 info = gst_structure_new_empty ("GstTagImageInfo");
857 gst_structure_set (info, "filename", G_TYPE_STRING, filename, NULL);
859 gst_structure_set (info, "description", G_TYPE_STRING, description, NULL);
861 tagsample = gst_sample_new (tagbuffer, caps, NULL, info);
863 gst_buffer_unref (tagbuffer);
864 gst_caps_unref (caps);
866 GST_DEBUG_OBJECT (common->sinkpad,
867 "Created attachment sample: %" GST_PTR_FORMAT, tagsample);
869 /* and append to the tag list */
870 if (image_type != GST_TAG_IMAGE_TYPE_NONE)
871 gst_tag_list_add (taglist, GST_TAG_MERGE_APPEND, GST_TAG_IMAGE, tagsample,
874 gst_tag_list_add (taglist, GST_TAG_MERGE_APPEND, GST_TAG_ATTACHMENT,
877 /* the list adds it own ref */
878 gst_sample_unref (tagsample);
884 g_free (description);
890 gst_matroska_read_common_parse_attachments (GstMatroskaReadCommon * common,
891 GstElement * el, GstEbmlRead * ebml)
894 GstFlowReturn ret = GST_FLOW_OK;
897 DEBUG_ELEMENT_START (common, ebml, "Attachments");
899 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
900 DEBUG_ELEMENT_STOP (common, ebml, "Attachments", ret);
904 taglist = gst_tag_list_new_empty ();
905 gst_tag_list_set_scope (taglist, GST_TAG_SCOPE_GLOBAL);
907 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
908 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
912 case GST_MATROSKA_ID_ATTACHEDFILE:
913 ret = gst_matroska_read_common_parse_attached_file (common, ebml,
918 ret = gst_matroska_read_common_parse_skip (common, ebml,
923 DEBUG_ELEMENT_STOP (common, ebml, "Attachments", ret);
925 if (gst_tag_list_n_tags (taglist) > 0) {
926 GST_DEBUG_OBJECT (common->sinkpad, "Storing attachment tags");
927 gst_matroska_read_common_found_global_tag (common, el, taglist);
929 GST_DEBUG_OBJECT (common->sinkpad, "No valid attachments found");
930 gst_tag_list_unref (taglist);
933 common->attachments_parsed = TRUE;
939 gst_matroska_read_common_parse_toc_tag (GstTocEntry * entry,
940 GstTocEntry * internal_entry, GArray * edition_targets,
941 GArray * chapter_targets, GstTagList * tags)
947 GList *cur, *internal_cur;
951 (gst_toc_entry_get_entry_type (entry) ==
952 GST_TOC_ENTRY_TYPE_EDITION) ? edition_targets : chapter_targets;
954 etags = gst_tag_list_new_empty ();
956 for (i = 0; i < targets->len; ++i) {
957 tgt = g_array_index (targets, guint64, i);
960 gst_tag_list_insert (etags, tags, GST_TAG_MERGE_APPEND);
962 uid = g_strdup_printf ("%" G_GUINT64_FORMAT, tgt);
963 if (g_strcmp0 (gst_toc_entry_get_uid (internal_entry), uid) == 0)
964 gst_tag_list_insert (etags, tags, GST_TAG_MERGE_APPEND);
969 gst_toc_entry_merge_tags (entry, etags, GST_TAG_MERGE_APPEND);
970 gst_tag_list_unref (etags);
972 cur = gst_toc_entry_get_sub_entries (entry);
973 internal_cur = gst_toc_entry_get_sub_entries (internal_entry);
974 while (cur != NULL && internal_cur != NULL) {
975 gst_matroska_read_common_parse_toc_tag (cur->data, internal_cur->data,
976 edition_targets, chapter_targets, tags);
978 internal_cur = internal_cur->next;
983 gst_matroska_read_common_parse_metadata_targets (GstMatroskaReadCommon * common,
984 GstEbmlRead * ebml, GArray * edition_targets, GArray * chapter_targets,
985 GArray * track_targets, guint64 * target_type_value, gchar ** target_type)
987 GstFlowReturn ret = GST_FLOW_OK;
993 DEBUG_ELEMENT_START (common, ebml, "TagTargets");
995 *target_type_value = 50;
998 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
999 DEBUG_ELEMENT_STOP (common, ebml, "TagTargets", ret);
1003 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1004 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1008 case GST_MATROSKA_ID_TARGETCHAPTERUID:
1009 if ((ret = gst_ebml_read_uint (ebml, &id, &uid)) == GST_FLOW_OK)
1010 g_array_append_val (chapter_targets, uid);
1013 case GST_MATROSKA_ID_TARGETEDITIONUID:
1014 if ((ret = gst_ebml_read_uint (ebml, &id, &uid)) == GST_FLOW_OK)
1015 g_array_append_val (edition_targets, uid);
1018 case GST_MATROSKA_ID_TARGETTRACKUID:
1019 if ((ret = gst_ebml_read_uint (ebml, &id, &uid)) == GST_FLOW_OK)
1020 g_array_append_val (track_targets, uid);
1023 case GST_MATROSKA_ID_TARGETTYPEVALUE:
1024 if ((ret = gst_ebml_read_uint (ebml, &id, &tmp)) == GST_FLOW_OK)
1025 *target_type_value = tmp;
1028 case GST_MATROSKA_ID_TARGETTYPE:
1029 if ((ret = gst_ebml_read_ascii (ebml, &id, &str)) == GST_FLOW_OK) {
1030 g_free (*target_type);
1037 gst_matroska_read_common_parse_skip (common, ebml, "TagTargets",
1043 DEBUG_ELEMENT_STOP (common, ebml, "TagTargets", ret);
1049 gst_matroska_read_common_postprocess_toc_entries (GList * toc_entries,
1050 guint64 max, const gchar * parent_uid)
1052 GstTocEntry *cur_info, *prev_info, *next_info;
1053 GList *cur_list, *prev_list, *next_list;
1054 gint64 cur_start, prev_start, stop;
1056 cur_list = toc_entries;
1057 while (cur_list != NULL) {
1058 cur_info = cur_list->data;
1060 switch (gst_toc_entry_get_entry_type (cur_info)) {
1061 case GST_TOC_ENTRY_TYPE_ANGLE:
1062 case GST_TOC_ENTRY_TYPE_VERSION:
1063 case GST_TOC_ENTRY_TYPE_EDITION:
1064 /* in Matroska terms edition has duration of full track */
1065 gst_toc_entry_set_start_stop_times (cur_info, 0, max);
1067 gst_matroska_read_common_postprocess_toc_entries
1068 (gst_toc_entry_get_sub_entries (cur_info), max,
1069 gst_toc_entry_get_uid (cur_info));
1072 case GST_TOC_ENTRY_TYPE_TITLE:
1073 case GST_TOC_ENTRY_TYPE_TRACK:
1074 case GST_TOC_ENTRY_TYPE_CHAPTER:
1075 prev_list = cur_list->prev;
1076 next_list = cur_list->next;
1078 if (prev_list != NULL)
1079 prev_info = prev_list->data;
1083 if (next_list != NULL)
1084 next_info = next_list->data;
1088 /* updated stop time in previous chapter and it's subchapters */
1089 if (prev_info != NULL) {
1090 gst_toc_entry_get_start_stop_times (prev_info, &prev_start, &stop);
1091 gst_toc_entry_get_start_stop_times (cur_info, &cur_start, &stop);
1094 gst_toc_entry_set_start_stop_times (prev_info, prev_start, stop);
1096 gst_matroska_read_common_postprocess_toc_entries
1097 (gst_toc_entry_get_sub_entries (prev_info), cur_start,
1098 gst_toc_entry_get_uid (prev_info));
1101 /* updated stop time in current chapter and it's subchapters */
1102 if (next_info == NULL) {
1103 gst_toc_entry_get_start_stop_times (cur_info, &cur_start, &stop);
1107 gst_toc_entry_set_start_stop_times (cur_info, cur_start, stop);
1110 gst_matroska_read_common_postprocess_toc_entries
1111 (gst_toc_entry_get_sub_entries (cur_info), stop,
1112 gst_toc_entry_get_uid (cur_info));
1115 case GST_TOC_ENTRY_TYPE_INVALID:
1118 cur_list = cur_list->next;
1122 static GstFlowReturn
1123 gst_matroska_read_common_parse_chapter_titles (GstMatroskaReadCommon * common,
1124 GstEbmlRead * ebml, GstTagList * titles)
1127 gchar *title = NULL;
1128 GstFlowReturn ret = GST_FLOW_OK;
1130 DEBUG_ELEMENT_START (common, ebml, "ChaptersTitles");
1133 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
1134 DEBUG_ELEMENT_STOP (common, ebml, "ChaptersTitles", ret);
1138 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1139 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1143 case GST_MATROSKA_ID_CHAPSTRING:
1144 ret = gst_ebml_read_utf8 (ebml, &id, &title);
1149 gst_matroska_read_common_parse_skip (common, ebml, "ChaptersTitles",
1155 DEBUG_ELEMENT_STOP (common, ebml, "ChaptersTitles", ret);
1157 if (title != NULL && ret == GST_FLOW_OK)
1158 gst_tag_list_add (titles, GST_TAG_MERGE_APPEND, GST_TAG_TITLE, title, NULL);
1164 static GstFlowReturn
1165 gst_matroska_read_common_parse_chapter_element (GstMatroskaReadCommon * common,
1166 GstEbmlRead * ebml, GList ** subentries, GList ** internal_subentries)
1169 guint64 start_time = -1, stop_time = -1;
1170 guint64 is_hidden = 0, is_enabled = 1, uid = 0;
1171 GstFlowReturn ret = GST_FLOW_OK;
1172 GstTocEntry *chapter_info, *internal_chapter_info;
1174 gchar *uid_str, *string_uid = NULL;
1175 GList *subsubentries = NULL, *internal_subsubentries = NULL, *l, *il;
1177 DEBUG_ELEMENT_START (common, ebml, "ChaptersElement");
1179 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
1180 DEBUG_ELEMENT_STOP (common, ebml, "ChaptersElement", ret);
1184 tags = gst_tag_list_new_empty ();
1186 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1187 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1191 case GST_MATROSKA_ID_CHAPTERUID:
1192 ret = gst_ebml_read_uint (ebml, &id, &uid);
1195 case GST_MATROSKA_ID_CHAPTERSTRINGUID:
1196 ret = gst_ebml_read_utf8 (ebml, &id, &string_uid);
1199 case GST_MATROSKA_ID_CHAPTERTIMESTART:
1200 ret = gst_ebml_read_uint (ebml, &id, &start_time);
1203 case GST_MATROSKA_ID_CHAPTERTIMESTOP:
1204 ret = gst_ebml_read_uint (ebml, &id, &stop_time);
1207 case GST_MATROSKA_ID_CHAPTERATOM:
1208 ret = gst_matroska_read_common_parse_chapter_element (common, ebml,
1209 &subsubentries, &internal_subsubentries);
1212 case GST_MATROSKA_ID_CHAPTERDISPLAY:
1214 gst_matroska_read_common_parse_chapter_titles (common, ebml, tags);
1217 case GST_MATROSKA_ID_CHAPTERFLAGHIDDEN:
1218 ret = gst_ebml_read_uint (ebml, &id, &is_hidden);
1221 case GST_MATROSKA_ID_CHAPTERFLAGENABLED:
1222 ret = gst_ebml_read_uint (ebml, &id, &is_enabled);
1227 gst_matroska_read_common_parse_skip (common, ebml,
1228 "ChaptersElement", id);
1234 uid = (((guint64) g_random_int ()) << 32) | g_random_int ();
1235 uid_str = g_strdup_printf ("%" G_GUINT64_FORMAT, uid);
1236 if (string_uid != NULL) {
1237 /* init toc with provided String UID */
1238 chapter_info = gst_toc_entry_new (GST_TOC_ENTRY_TYPE_CHAPTER, string_uid);
1239 g_free (string_uid);
1241 /* No String UID provided => use the internal UID instead */
1242 chapter_info = gst_toc_entry_new (GST_TOC_ENTRY_TYPE_CHAPTER, uid_str);
1244 /* init internal toc with internal UID */
1245 internal_chapter_info = gst_toc_entry_new (GST_TOC_ENTRY_TYPE_CHAPTER,
1249 gst_toc_entry_set_tags (chapter_info, tags);
1250 gst_toc_entry_set_start_stop_times (chapter_info, start_time, stop_time);
1252 for (l = subsubentries, il = internal_subsubentries;
1253 l && il; l = l->next, il = il->next) {
1254 gst_toc_entry_append_sub_entry (chapter_info, l->data);
1255 gst_toc_entry_append_sub_entry (internal_chapter_info, il->data);
1257 g_list_free (subsubentries);
1258 g_list_free (internal_subsubentries);
1260 DEBUG_ELEMENT_STOP (common, ebml, "ChaptersElement", ret);
1262 /* start time is mandatory and has no default value,
1263 * so we should skip chapters without it */
1264 if (is_hidden == 0 && is_enabled > 0 &&
1265 start_time != -1 && ret == GST_FLOW_OK) {
1266 *subentries = g_list_append (*subentries, chapter_info);
1267 *internal_subentries = g_list_append (*internal_subentries,
1268 internal_chapter_info);
1270 gst_toc_entry_unref (chapter_info);
1271 gst_toc_entry_unref (internal_chapter_info);
1277 static GstFlowReturn
1278 gst_matroska_read_common_parse_chapter_edition (GstMatroskaReadCommon * common,
1279 GstEbmlRead * ebml, GstToc * toc, GstToc * internal_toc)
1282 guint64 is_hidden = 0, uid = 0;
1283 GstFlowReturn ret = GST_FLOW_OK;
1284 GstTocEntry *edition_info, *internal_edition_info;
1285 GList *subentries = NULL, *internal_subentries = NULL, *l, *il;
1288 DEBUG_ELEMENT_START (common, ebml, "ChaptersEdition");
1290 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
1291 DEBUG_ELEMENT_STOP (common, ebml, "ChaptersEdition", ret);
1295 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1296 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1300 case GST_MATROSKA_ID_EDITIONUID:
1301 ret = gst_ebml_read_uint (ebml, &id, &uid);
1304 case GST_MATROSKA_ID_CHAPTERATOM:
1305 ret = gst_matroska_read_common_parse_chapter_element (common, ebml,
1306 &subentries, &internal_subentries);
1309 case GST_MATROSKA_ID_EDITIONFLAGHIDDEN:
1310 ret = gst_ebml_read_uint (ebml, &id, &is_hidden);
1315 gst_matroska_read_common_parse_skip (common, ebml,
1316 "ChaptersEdition", id);
1321 DEBUG_ELEMENT_STOP (common, ebml, "ChaptersEdition", ret);
1324 uid = (((guint64) g_random_int ()) << 32) | g_random_int ();
1325 uid_str = g_strdup_printf ("%" G_GUINT64_FORMAT, uid);
1326 edition_info = gst_toc_entry_new (GST_TOC_ENTRY_TYPE_EDITION, uid_str);
1327 gst_toc_entry_set_start_stop_times (edition_info, -1, -1);
1328 internal_edition_info = gst_toc_entry_new (GST_TOC_ENTRY_TYPE_EDITION,
1332 for (l = subentries, il = internal_subentries; l && il;
1333 l = l->next, il = il->next) {
1334 gst_toc_entry_append_sub_entry (edition_info, l->data);
1335 gst_toc_entry_append_sub_entry (internal_edition_info, il->data);
1337 g_list_free (subentries);
1338 g_list_free (internal_subentries);
1340 if (is_hidden == 0 && subentries != NULL && ret == GST_FLOW_OK) {
1341 gst_toc_append_entry (toc, edition_info);
1342 gst_toc_append_entry (internal_toc, internal_edition_info);
1344 GST_DEBUG_OBJECT (common->sinkpad,
1345 "Skipping empty or hidden edition in the chapters TOC");
1346 gst_toc_entry_unref (edition_info);
1347 gst_toc_entry_unref (internal_edition_info);
1354 gst_matroska_read_common_parse_chapters (GstMatroskaReadCommon * common,
1358 GstFlowReturn ret = GST_FLOW_OK;
1359 GstToc *toc, *internal_toc;
1361 DEBUG_ELEMENT_START (common, ebml, "Chapters");
1363 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
1364 DEBUG_ELEMENT_STOP (common, ebml, "Chapters", ret);
1368 /* FIXME: create CURRENT toc as well */
1369 toc = gst_toc_new (GST_TOC_SCOPE_GLOBAL);
1370 internal_toc = gst_toc_new (GST_TOC_SCOPE_GLOBAL);
1372 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1373 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1377 case GST_MATROSKA_ID_EDITIONENTRY:
1378 ret = gst_matroska_read_common_parse_chapter_edition (common, ebml,
1384 gst_matroska_read_common_parse_skip (common, ebml, "Chapters", id);
1389 if (gst_toc_get_entries (toc) != NULL) {
1390 gst_matroska_read_common_postprocess_toc_entries (gst_toc_get_entries (toc),
1391 common->segment.duration, "");
1392 /* no need to postprocess internal_toc as we don't need to keep track
1393 * of start / end and tags (only UIDs) */
1396 common->internal_toc = internal_toc;
1398 gst_toc_unref (toc);
1399 gst_toc_unref (internal_toc);
1402 common->chapters_parsed = TRUE;
1404 DEBUG_ELEMENT_STOP (common, ebml, "Chapters", ret);
1409 gst_matroska_read_common_parse_header (GstMatroskaReadCommon * common,
1417 /* this function is the first to be called */
1423 ret = gst_ebml_peek_id (ebml, &id);
1424 if (ret != GST_FLOW_OK)
1427 GST_DEBUG_OBJECT (common->sinkpad, "id: %08x", id);
1429 if (id != GST_EBML_ID_HEADER) {
1430 GST_ERROR_OBJECT (common->sinkpad, "Failed to read header");
1434 ret = gst_ebml_read_master (ebml, &id);
1435 if (ret != GST_FLOW_OK)
1438 while (gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1439 ret = gst_ebml_peek_id (ebml, &id);
1440 if (ret != GST_FLOW_OK)
1444 /* is our read version uptodate? */
1445 case GST_EBML_ID_EBMLREADVERSION:{
1448 ret = gst_ebml_read_uint (ebml, &id, &num);
1449 if (ret != GST_FLOW_OK)
1451 if (num != GST_EBML_VERSION) {
1452 GST_ERROR_OBJECT (common->sinkpad,
1453 "Unsupported EBML version %" G_GUINT64_FORMAT, num);
1457 GST_DEBUG_OBJECT (common->sinkpad,
1458 "EbmlReadVersion: %" G_GUINT64_FORMAT, num);
1462 /* we only handle 8 byte lengths at max */
1463 case GST_EBML_ID_EBMLMAXSIZELENGTH:{
1466 ret = gst_ebml_read_uint (ebml, &id, &num);
1467 if (ret != GST_FLOW_OK)
1469 if (num > sizeof (guint64)) {
1470 GST_ERROR_OBJECT (common->sinkpad,
1471 "Unsupported EBML maximum size %" G_GUINT64_FORMAT, num);
1472 return GST_FLOW_ERROR;
1474 GST_DEBUG_OBJECT (common->sinkpad,
1475 "EbmlMaxSizeLength: %" G_GUINT64_FORMAT, num);
1479 /* we handle 4 byte IDs at max */
1480 case GST_EBML_ID_EBMLMAXIDLENGTH:{
1483 ret = gst_ebml_read_uint (ebml, &id, &num);
1484 if (ret != GST_FLOW_OK)
1486 if (num > sizeof (guint32)) {
1487 GST_ERROR_OBJECT (common->sinkpad,
1488 "Unsupported EBML maximum ID %" G_GUINT64_FORMAT, num);
1489 return GST_FLOW_ERROR;
1491 GST_DEBUG_OBJECT (common->sinkpad,
1492 "EbmlMaxIdLength: %" G_GUINT64_FORMAT, num);
1496 case GST_EBML_ID_DOCTYPE:{
1499 ret = gst_ebml_read_ascii (ebml, &id, &text);
1500 if (ret != GST_FLOW_OK)
1503 GST_DEBUG_OBJECT (common->sinkpad, "EbmlDocType: %s",
1504 GST_STR_NULL (text));
1511 case GST_EBML_ID_DOCTYPEREADVERSION:{
1514 ret = gst_ebml_read_uint (ebml, &id, &num);
1515 if (ret != GST_FLOW_OK)
1518 GST_DEBUG_OBJECT (common->sinkpad,
1519 "EbmlReadVersion: %" G_GUINT64_FORMAT, num);
1524 ret = gst_matroska_read_common_parse_skip (common, ebml,
1526 if (ret != GST_FLOW_OK)
1530 /* we ignore these two, as they don't tell us anything we care about */
1531 case GST_EBML_ID_EBMLVERSION:
1532 case GST_EBML_ID_DOCTYPEVERSION:
1533 ret = gst_ebml_read_skip (ebml);
1534 if (ret != GST_FLOW_OK)
1542 if ((doctype != NULL && !strcmp (doctype, GST_MATROSKA_DOCTYPE_MATROSKA)) ||
1543 (doctype != NULL && !strcmp (doctype, GST_MATROSKA_DOCTYPE_WEBM)) ||
1544 (doctype == NULL)) {
1547 GST_INFO_OBJECT (common->sinkpad, "Input is %s version %d", doctype,
1549 if (!strcmp (doctype, GST_MATROSKA_DOCTYPE_WEBM))
1550 common->is_webm = TRUE;
1552 GST_WARNING_OBJECT (common->sinkpad,
1553 "Input is EBML without doctype, assuming " "matroska (version %d)",
1558 GST_ELEMENT_ERROR (common, STREAM, DEMUX, (NULL),
1559 ("Demuxer version (2) is too old to read %s version %d",
1560 GST_STR_NULL (doctype), version));
1561 ret = GST_FLOW_ERROR;
1564 GST_ELEMENT_ERROR (common, STREAM, WRONG_TYPE, (NULL),
1565 ("Input is not a matroska stream (doctype=%s)", doctype));
1566 ret = GST_FLOW_ERROR;
1576 static GstFlowReturn
1577 gst_matroska_read_common_parse_index_cuetrack (GstMatroskaReadCommon * common,
1578 GstEbmlRead * ebml, guint * nentries)
1582 GstMatroskaIndex idx;
1584 idx.pos = (guint64) - 1;
1586 idx.time = GST_CLOCK_TIME_NONE;
1589 DEBUG_ELEMENT_START (common, ebml, "CueTrackPositions");
1591 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
1592 DEBUG_ELEMENT_STOP (common, ebml, "CueTrackPositions", ret);
1596 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1597 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1602 case GST_MATROSKA_ID_CUETRACK:
1606 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1611 GST_WARNING_OBJECT (common->sinkpad, "Invalid CueTrack 0");
1615 GST_DEBUG_OBJECT (common->sinkpad, "CueTrack: %" G_GUINT64_FORMAT, num);
1620 /* position in file */
1621 case GST_MATROSKA_ID_CUECLUSTERPOSITION:
1625 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1628 if (num > G_MAXINT64) {
1629 GST_WARNING_OBJECT (common->sinkpad,
1630 "CueClusterPosition %" G_GUINT64_FORMAT " too large", num);
1638 /* number of block in the cluster */
1639 case GST_MATROSKA_ID_CUEBLOCKNUMBER:
1643 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1647 GST_WARNING_OBJECT (common->sinkpad, "Invalid CueBlockNumber 0");
1651 GST_DEBUG_OBJECT (common->sinkpad, "CueBlockNumber: %" G_GUINT64_FORMAT,
1655 /* mild sanity check, disregard strange cases ... */
1656 if (idx.block > G_MAXUINT16) {
1657 GST_DEBUG_OBJECT (common->sinkpad, "... looks suspicious, ignoring");
1664 ret = gst_matroska_read_common_parse_skip (common, ebml,
1665 "CueTrackPositions", id);
1668 case GST_MATROSKA_ID_CUECODECSTATE:
1669 case GST_MATROSKA_ID_CUEREFERENCE:
1670 ret = gst_ebml_read_skip (ebml);
1675 DEBUG_ELEMENT_STOP (common, ebml, "CueTrackPositions", ret);
1677 /* (e.g.) lavf typically creates entries without a block number,
1678 * which is bogus and leads to contradictory information */
1679 if (common->index->len) {
1680 GstMatroskaIndex *last_idx;
1682 last_idx = &g_array_index (common->index, GstMatroskaIndex,
1683 common->index->len - 1);
1684 if (last_idx->block == idx.block && last_idx->pos == idx.pos &&
1685 last_idx->track == idx.track && idx.time > last_idx->time) {
1686 GST_DEBUG_OBJECT (common->sinkpad, "Cue entry refers to same location, "
1687 "but has different time than previous entry; discarding");
1692 if ((ret == GST_FLOW_OK || ret == GST_FLOW_EOS)
1693 && idx.pos != (guint64) - 1 && idx.track > 0) {
1694 g_array_append_val (common->index, idx);
1696 } else if (ret == GST_FLOW_OK || ret == GST_FLOW_EOS) {
1697 GST_DEBUG_OBJECT (common->sinkpad,
1698 "CueTrackPositions without valid content");
1704 static GstFlowReturn
1705 gst_matroska_read_common_parse_index_pointentry (GstMatroskaReadCommon *
1706 common, GstEbmlRead * ebml)
1710 GstClockTime time = GST_CLOCK_TIME_NONE;
1713 DEBUG_ELEMENT_START (common, ebml, "CuePoint");
1715 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
1716 DEBUG_ELEMENT_STOP (common, ebml, "CuePoint", ret);
1720 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1721 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1725 /* one single index entry ('point') */
1726 case GST_MATROSKA_ID_CUETIME:
1728 if ((ret = gst_ebml_read_uint (ebml, &id, &time)) != GST_FLOW_OK)
1731 GST_DEBUG_OBJECT (common->sinkpad, "CueTime: %" G_GUINT64_FORMAT, time);
1732 time = time * common->time_scale;
1736 /* position in the file + track to which it belongs */
1737 case GST_MATROSKA_ID_CUETRACKPOSITIONS:
1739 ret = gst_matroska_read_common_parse_index_cuetrack (common, ebml,
1745 ret = gst_matroska_read_common_parse_skip (common, ebml, "CuePoint",
1751 DEBUG_ELEMENT_STOP (common, ebml, "CuePoint", ret);
1754 if (time == GST_CLOCK_TIME_NONE) {
1755 GST_WARNING_OBJECT (common->sinkpad, "CuePoint without valid time");
1756 g_array_remove_range (common->index, common->index->len - nentries,
1761 for (i = common->index->len - nentries; i < common->index->len; i++) {
1762 GstMatroskaIndex *idx =
1763 &g_array_index (common->index, GstMatroskaIndex, i);
1766 GST_DEBUG_OBJECT (common->sinkpad, "Index entry: pos=%" G_GUINT64_FORMAT
1767 ", time=%" GST_TIME_FORMAT ", track=%u, block=%u", idx->pos,
1768 GST_TIME_ARGS (idx->time), (guint) idx->track, (guint) idx->block);
1772 GST_DEBUG_OBJECT (common->sinkpad, "Empty CuePoint");
1779 gst_matroska_read_common_stream_from_num (GstMatroskaReadCommon * common,
1784 g_assert (common->src->len == common->num_streams);
1785 for (n = 0; n < common->src->len; n++) {
1786 GstMatroskaTrackContext *context = g_ptr_array_index (common->src, n);
1788 if (context->num == track_num) {
1793 if (n == common->num_streams)
1794 GST_WARNING_OBJECT (common->sinkpad,
1795 "Failed to find corresponding pad for tracknum %d", track_num);
1801 gst_matroska_read_common_parse_index (GstMatroskaReadCommon * common,
1805 GstFlowReturn ret = GST_FLOW_OK;
1809 g_array_free (common->index, TRUE);
1811 g_array_sized_new (FALSE, FALSE, sizeof (GstMatroskaIndex), 128);
1813 DEBUG_ELEMENT_START (common, ebml, "Cues");
1815 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
1816 DEBUG_ELEMENT_STOP (common, ebml, "Cues", ret);
1820 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1821 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1825 /* one single index entry ('point') */
1826 case GST_MATROSKA_ID_POINTENTRY:
1827 ret = gst_matroska_read_common_parse_index_pointentry (common, ebml);
1831 ret = gst_matroska_read_common_parse_skip (common, ebml, "Cues", id);
1835 DEBUG_ELEMENT_STOP (common, ebml, "Cues", ret);
1837 /* Sort index by time, smallest time first, for easier searching */
1838 g_array_sort (common->index, (GCompareFunc) gst_matroska_index_compare);
1840 /* Now sort the track specific index entries into their own arrays */
1841 for (i = 0; i < common->index->len; i++) {
1842 GstMatroskaIndex *idx = &g_array_index (common->index, GstMatroskaIndex,
1845 GstMatroskaTrackContext *ctx;
1848 if (common->element_index) {
1851 if (idx->track != 0 &&
1853 gst_matroska_read_common_stream_from_num (common,
1854 idx->track)) != -1) {
1855 ctx = g_ptr_array_index (common->src, track_num);
1857 if (ctx->index_writer_id == -1)
1858 gst_index_get_writer_id (common->element_index,
1859 GST_OBJECT (ctx->pad), &ctx->index_writer_id);
1860 writer_id = ctx->index_writer_id;
1862 if (common->element_index_writer_id == -1)
1863 gst_index_get_writer_id (common->element_index, GST_OBJECT (common),
1864 &common->element_index_writer_id);
1865 writer_id = common->element_index_writer_id;
1868 GST_LOG_OBJECT (common->sinkpad,
1869 "adding association %" GST_TIME_FORMAT "-> %" G_GUINT64_FORMAT
1870 " for writer id %d", GST_TIME_ARGS (idx->time), idx->pos, writer_id);
1871 gst_index_add_association (common->element_index, writer_id,
1872 GST_ASSOCIATION_FLAG_KEY_UNIT, GST_FORMAT_TIME, idx->time,
1873 GST_FORMAT_BYTES, idx->pos + common->ebml_segment_start, NULL);
1877 if (idx->track == 0)
1880 track_num = gst_matroska_read_common_stream_from_num (common, idx->track);
1881 if (track_num == -1)
1884 ctx = g_ptr_array_index (common->src, track_num);
1886 if (ctx->index_table == NULL)
1888 g_array_sized_new (FALSE, FALSE, sizeof (GstMatroskaIndex), 128);
1890 g_array_append_vals (ctx->index_table, idx, 1);
1893 common->index_parsed = TRUE;
1895 /* sanity check; empty index normalizes to no index */
1896 if (common->index->len == 0) {
1897 g_array_free (common->index, TRUE);
1898 common->index = NULL;
1905 gst_matroska_read_common_parse_info (GstMatroskaReadCommon * common,
1906 GstElement * el, GstEbmlRead * ebml)
1908 GstFlowReturn ret = GST_FLOW_OK;
1909 gdouble dur_f = -1.0;
1912 DEBUG_ELEMENT_START (common, ebml, "SegmentInfo");
1914 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
1915 DEBUG_ELEMENT_STOP (common, ebml, "SegmentInfo", ret);
1919 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1920 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1924 /* cluster timecode */
1925 case GST_MATROSKA_ID_TIMECODESCALE:{
1928 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1932 GST_DEBUG_OBJECT (common->sinkpad, "TimeCodeScale: %" G_GUINT64_FORMAT,
1934 common->time_scale = num;
1938 case GST_MATROSKA_ID_DURATION:{
1939 if ((ret = gst_ebml_read_float (ebml, &id, &dur_f)) != GST_FLOW_OK)
1943 GST_WARNING_OBJECT (common->sinkpad, "Invalid duration %lf", dur_f);
1947 GST_DEBUG_OBJECT (common->sinkpad, "Duration: %lf", dur_f);
1951 case GST_MATROSKA_ID_WRITINGAPP:{
1954 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1957 GST_DEBUG_OBJECT (common->sinkpad, "WritingApp: %s",
1958 GST_STR_NULL (text));
1959 common->writing_app = text;
1963 case GST_MATROSKA_ID_MUXINGAPP:{
1966 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1969 GST_DEBUG_OBJECT (common->sinkpad, "MuxingApp: %s",
1970 GST_STR_NULL (text));
1971 common->muxing_app = text;
1975 case GST_MATROSKA_ID_DATEUTC:{
1978 if ((ret = gst_ebml_read_date (ebml, &id, &time)) != GST_FLOW_OK)
1981 GST_DEBUG_OBJECT (common->sinkpad, "DateUTC: %" G_GINT64_FORMAT, time);
1982 common->created = time;
1986 case GST_MATROSKA_ID_TITLE:{
1988 GstTagList *taglist;
1990 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1993 GST_DEBUG_OBJECT (common->sinkpad, "Title: %s", GST_STR_NULL (text));
1994 taglist = gst_tag_list_new (GST_TAG_TITLE, text, NULL);
1995 gst_tag_list_set_scope (taglist, GST_TAG_SCOPE_GLOBAL);
1996 gst_matroska_read_common_found_global_tag (common, el, taglist);
2002 ret = gst_matroska_read_common_parse_skip (common, ebml,
2007 case GST_MATROSKA_ID_SEGMENTUID:
2008 case GST_MATROSKA_ID_SEGMENTFILENAME:
2009 case GST_MATROSKA_ID_PREVUID:
2010 case GST_MATROSKA_ID_PREVFILENAME:
2011 case GST_MATROSKA_ID_NEXTUID:
2012 case GST_MATROSKA_ID_NEXTFILENAME:
2013 case GST_MATROSKA_ID_SEGMENTFAMILY:
2014 case GST_MATROSKA_ID_CHAPTERTRANSLATE:
2015 ret = gst_ebml_read_skip (ebml);
2023 dur_u = gst_gdouble_to_guint64 (dur_f *
2024 gst_guint64_to_gdouble (common->time_scale));
2025 if (GST_CLOCK_TIME_IS_VALID (dur_u) && dur_u <= G_MAXINT64)
2026 common->segment.duration = dur_u;
2029 DEBUG_ELEMENT_STOP (common, ebml, "SegmentInfo", ret);
2031 common->segmentinfo_parsed = TRUE;
2036 static GstFlowReturn
2037 gst_matroska_read_common_parse_metadata_id_simple_tag (GstMatroskaReadCommon *
2038 common, GstEbmlRead * ebml, GstTagList ** p_taglist, gchar * parent)
2040 /* FIXME: check if there are more useful mappings */
2043 const gchar *matroska_tagname;
2044 const gchar *gstreamer_tagname;
2050 /* The following list has the _same_ order as the one in Matroska spec. Please, don't mess it up. */
2051 /* TODO: Nesting information:
2052 ORIGINAL A special tag that is meant to have other tags inside (using nested tags) to describe the original work of art that this item is based on. All tags in this list can be used "under" the ORIGINAL tag like LYRICIST, PERFORMER, etc.
2053 SAMPLE A tag that contains other tags to describe a sample used in the targeted item taken from another work of art. All tags in this list can be used "under" the SAMPLE tag like TITLE, ARTIST, DATE_RELEASED, etc.
2054 COUNTRY The name of the country (biblio ISO-639-2) that is meant to have other tags inside (using nested tags) to country specific information about the item. All tags in this list can be used "under" the COUNTRY_SPECIFIC tag like LABEL, PUBLISH_RATING, etc.
2057 /* Organizational Information */
2058 GST_MATROSKA_TAG_ID_TOTAL_PARTS, GST_TAG_TRACK_COUNT}, {
2059 GST_MATROSKA_TAG_ID_PART_NUMBER, GST_TAG_TRACK_NUMBER}, {
2060 /* TODO: PART_OFFSET A number to add to PART_NUMBER when the parts at that level don't start at 1. (e.g. if TargetType is TRACK, the track number of the second audio CD) */
2063 GST_MATROSKA_TAG_ID_SUBTITLE, GST_TAG_TITLE}, { /* Sub Title of the entity. Since we're concat'ing all title-like entities anyway, might as well add the sub-title. */
2064 GST_MATROSKA_TAG_ID_TITLE, GST_TAG_TITLE}, {
2065 GST_MATROSKA_TAG_ID_ALBUM, GST_TAG_ALBUM}, { /* Matroska spec does NOT have this tag! Dunno what it was doing here, probably for compatibility. */
2067 /* TODO: Nested Information:
2068 URL URL corresponding to the tag it's included in.
2069 SORT_WITH A child element to indicate what alternative value the parent tag can have to be sorted, for example "Pet Shop Boys" instead of "The Pet Shop Boys". Or "Marley Bob" and "Marley Ziggy" (no comma needed).
2070 INSTRUMENTS The instruments that are being used/played, separated by a comma. It should be a child of the following tags: ARTIST, LEAD_PERFORMER or ACCOMPANIMENT.
2071 EMAIL Email corresponding to the tag it's included in.
2072 ADDRESS The physical address of the entity. The address should include a country code. It can be useful for a recording label.
2073 FAX The fax number corresponding to the tag it's included in. It can be useful for a recording label.
2074 PHONE The phone number corresponding to the tag it's included in. It can be useful for a recording label.
2078 GST_MATROSKA_TAG_ID_ARTIST, GST_TAG_ARTIST}, {
2079 GST_MATROSKA_TAG_ID_LEAD_PERFORMER, GST_TAG_PERFORMER}, {
2080 GST_MATROSKA_TAG_ID_ACCOMPANIMENT, GST_TAG_PERFORMER}, { /* Band/orchestra/accompaniment/musician. This is akin to the TPE2 tag in ID3. */
2081 GST_MATROSKA_TAG_ID_COMPOSER, GST_TAG_COMPOSER}, {
2082 /* ARRANGER The person who arranged the piece, e.g., Ravel. */
2083 GST_MATROSKA_TAG_ID_LYRICS, GST_TAG_LYRICS}, { /* The lyrics corresponding to a song (in case audio synchronization is not known or as a doublon to a subtitle track). Editing this value when subtitles are found should also result in editing the subtitle track for more consistency. */
2084 /* LYRICIST The person who wrote the lyrics for a musical item. This is akin to the TEXT tag in ID3. */
2085 GST_MATROSKA_TAG_ID_CONDUCTOR, GST_TAG_PERFORMER}, { /* Conductor/performer refinement. This is akin to the TPE3 tag in ID3. */
2086 /* DIRECTOR This is akin to the IART tag in RIFF. */
2087 GST_MATROSKA_TAG_ID_AUTHOR, GST_TAG_ARTIST}, {
2088 /* ASSISTANT_DIRECTOR The name of the assistant director. */
2089 /* DIRECTOR_OF_PHOTOGRAPHY The name of the director of photography, also known as cinematographer. This is akin to the ICNM tag in Extended RIFF. */
2090 /* SOUND_ENGINEER The name of the sound engineer or sound recordist. */
2091 /* ART_DIRECTOR The person who oversees the artists and craftspeople who build the sets. */
2092 /* PRODUCTION_DESIGNER Artist responsible for designing the overall visual appearance of a movie. */
2093 /* CHOREGRAPHER The name of the choregrapher */
2094 /* COSTUME_DESIGNER The name of the costume designer */
2095 /* ACTOR An actor or actress playing a role in this movie. This is the person's real name, not the character's name the person is playing. */
2096 /* CHARACTER The name of the character an actor or actress plays in this movie. This should be a sub-tag of an ACTOR tag in order not to cause ambiguities. */
2097 /* WRITTEN_BY The author of the story or script (used for movies and TV shows). */
2098 /* SCREENPLAY_BY The author of the screenplay or scenario (used for movies and TV shows). */
2099 /* EDITED_BY This is akin to the IEDT tag in Extended RIFF. */
2100 /* PRODUCER Produced by. This is akin to the IPRO tag in Extended RIFF. */
2101 /* COPRODUCER The name of a co-producer. */
2102 /* EXECUTIVE_PRODUCER The name of an executive producer. */
2103 /* DISTRIBUTED_BY This is akin to the IDST tag in Extended RIFF. */
2104 /* MASTERED_BY The engineer who mastered the content for a physical medium or for digital distribution. */
2105 GST_MATROSKA_TAG_ID_ENCODED_BY, GST_TAG_ENCODED_BY}, { /* This is akin to the TENC tag in ID3. */
2106 /* MIXED_BY DJ mix by the artist specified */
2107 /* REMIXED_BY Interpreted, remixed, or otherwise modified by. This is akin to the TPE4 tag in ID3. */
2108 /* PRODUCTION_STUDIO This is akin to the ISTD tag in Extended RIFF. */
2109 /* THANKS_TO A very general tag for everyone else that wants to be listed. */
2110 /* PUBLISHER This is akin to the TPUB tag in ID3. */
2111 /* LABEL The record label or imprint on the disc. */
2112 /* Search / Classification */
2113 GST_MATROSKA_TAG_ID_GENRE, GST_TAG_GENRE}, {
2114 /* MOOD Intended to reflect the mood of the item with a few keywords, e.g. "Romantic", "Sad" or "Uplifting". The format follows that of the TMOO tag in ID3. */
2115 /* ORIGINAL_MEDIA_TYPE Describes the original type of the media, such as, "DVD", "CD", "computer image," "drawing," "lithograph," and so forth. This is akin to the TMED tag in ID3. */
2116 /* CONTENT_TYPE The type of the item. e.g. Documentary, Feature Film, Cartoon, Music Video, Music, Sound FX, ... */
2117 /* SUBJECT Describes the topic of the file, such as "Aerial view of Seattle." */
2118 GST_MATROSKA_TAG_ID_DESCRIPTION, GST_TAG_DESCRIPTION}, { /* A short description of the content, such as "Two birds flying." */
2119 GST_MATROSKA_TAG_ID_KEYWORDS, GST_TAG_KEYWORDS}, { /* Keywords to the item separated by a comma, used for searching. */
2120 /* SUMMARY A plot outline or a summary of the story. */
2121 /* SYNOPSIS A description of the story line of the item. */
2122 /* INITIAL_KEY The initial key that a musical track starts in. The format is identical to ID3. */
2123 /* PERIOD Describes the period that the piece is from or about. For example, "Renaissance". */
2124 /* LAW_RATING Depending on the country it's the format of the rating of a movie (P, R, X in the USA, an age in other countries or a URI defining a logo). */
2125 /* ICRA The ICRA content rating for parental control. (Previously RSACi) */
2127 /* Temporal Information */
2128 GST_MATROSKA_TAG_ID_DATE_RELEASED, GST_TAG_DATE}, { /* The time that the item was originaly released. This is akin to the TDRL tag in ID3. */
2129 GST_MATROSKA_TAG_ID_DATE_RECORDED, GST_TAG_DATE}, { /* The time that the recording began. This is akin to the TDRC tag in ID3. */
2130 GST_MATROSKA_TAG_ID_DATE_ENCODED, GST_TAG_DATE}, { /* The time that the encoding of this item was completed began. This is akin to the TDEN tag in ID3. */
2131 GST_MATROSKA_TAG_ID_DATE_TAGGED, GST_TAG_DATE}, { /* The time that the tags were done for this item. This is akin to the TDTG tag in ID3. */
2132 GST_MATROSKA_TAG_ID_DATE_DIGITIZED, GST_TAG_DATE}, { /* The time that the item was tranfered to a digital medium. This is akin to the IDIT tag in RIFF. */
2133 GST_MATROSKA_TAG_ID_DATE_WRITTEN, GST_TAG_DATE}, { /* The time that the writing of the music/script began. */
2134 GST_MATROSKA_TAG_ID_DATE_PURCHASED, GST_TAG_DATE}, { /* Information on when the file was purchased (see also purchase tags). */
2135 GST_MATROSKA_TAG_ID_DATE, GST_TAG_DATE}, { /* Matroska spec does NOT have this tag! Dunno what it was doing here, probably for compatibility. */
2137 /* Spacial Information */
2138 GST_MATROSKA_TAG_ID_RECORDING_LOCATION, GST_TAG_GEO_LOCATION_NAME}, { /* The location where the item was recorded. The countries corresponding to the string, same 2 octets as in Internet domains, or possibly ISO-3166. This code is followed by a comma, then more detailed information such as state/province, another comma, and then city. For example, "US, Texas, Austin". This will allow for easy sorting. It is okay to only store the country, or the country and the state/province. More detailed information can be added after the city through the use of additional commas. In cases where the province/state is unknown, but you want to store the city, simply leave a space between the two commas. For example, "US, , Austin". */
2139 /* COMPOSITION_LOCATION Location that the item was originaly designed/written. The countries corresponding to the string, same 2 octets as in Internet domains, or possibly ISO-3166. This code is followed by a comma, then more detailed information such as state/province, another comma, and then city. For example, "US, Texas, Austin". This will allow for easy sorting. It is okay to only store the country, or the country and the state/province. More detailed information can be added after the city through the use of additional commas. In cases where the province/state is unknown, but you want to store the city, simply leave a space between the two commas. For example, "US, , Austin". */
2140 /* COMPOSER_NATIONALITY Nationality of the main composer of the item, mostly for classical music. The countries corresponding to the string, same 2 octets as in Internet domains, or possibly ISO-3166. */
2143 GST_MATROSKA_TAG_ID_COMMENT, GST_TAG_COMMENT}, { /* Any comment related to the content. */
2144 GST_MATROSKA_TAG_ID_COMMENTS, GST_TAG_COMMENT}, { /* Matroska spec does NOT have this tag! Dunno what it was doing here, probably for compatibility. */
2145 /* PLAY_COUNTER The number of time the item has been played. */
2146 /* TODO: RATING A numeric value defining how much a person likes the song/movie. The number is between 0 and 5 with decimal values possible (e.g. 2.7), 5(.0) being the highest possible rating. Other rating systems with different ranges will have to be scaled. */
2148 /* Technical Information */
2149 GST_MATROSKA_TAG_ID_ENCODER, GST_TAG_ENCODER}, {
2150 /* ENCODER_SETTINGS A list of the settings used for encoding this item. No specific format. */
2151 GST_MATROSKA_TAG_ID_BPS, GST_TAG_BITRATE}, {
2152 GST_MATROSKA_TAG_ID_BITSPS, GST_TAG_BITRATE}, { /* Matroska spec does NOT have this tag! Dunno what it was doing here, probably for compatibility. */
2153 /* WONTFIX (already handled in another way): FPS The average frames per second of the specified item. This is typically the average number of Blocks per second. In the event that lacing is used, each laced chunk is to be counted as a seperate frame. */
2154 GST_MATROSKA_TAG_ID_BPM, GST_TAG_BEATS_PER_MINUTE}, {
2155 /* MEASURE In music, a measure is a unit of time in Western music like "4/4". It represents a regular grouping of beats, a meter, as indicated in musical notation by the time signature.. The majority of the contemporary rock and pop music you hear on the radio these days is written in the 4/4 time signature. */
2156 /* TUNING It is saved as a frequency in hertz to allow near-perfect tuning of instruments to the same tone as the musical piece (e.g. "441.34" in Hertz). The default value is 440.0 Hz. */
2157 /* TODO: REPLAYGAIN_GAIN The gain to apply to reach 89dB SPL on playback. This is based on the Replay Gain standard. Note that ReplayGain information can be found at all TargetType levels (track, album, etc). */
2158 /* TODO: REPLAYGAIN_PEAK The maximum absolute peak value of the item. This is based on the Replay Gain standard. */
2161 GST_MATROSKA_TAG_ID_ISRC, GST_TAG_ISRC}, {
2162 /* MCDI This is a binary dump of the TOC of the CDROM that this item was taken from. This holds the same information as the MCDI in ID3. */
2163 /* ISBN International Standard Book Number */
2164 /* BARCODE EAN-13 (European Article Numbering) or UPC-A (Universal Product Code) bar code identifier */
2165 /* CATALOG_NUMBER A label-specific string used to identify the release (TIC 01 for example). */
2166 /* LABEL_CODE A 4-digit or 5-digit number to identify the record label, typically printed as (LC) xxxx or (LC) 0xxxx on CDs medias or covers (only the number is stored). */
2167 /* LCCN Library of Congress Control Number */
2170 /* PURCHASE_ITEM URL to purchase this file. This is akin to the WPAY tag in ID3. */
2171 /* PURCHASE_INFO Information on where to purchase this album. This is akin to the WCOM tag in ID3. */
2172 /* PURCHASE_OWNER Information on the person who purchased the file. This is akin to the TOWN tag in ID3. */
2173 /* PURCHASE_PRICE The amount paid for entity. There should only be a numeric value in here. Only numbers, no letters or symbols other than ".". For instance, you would store "15.59" instead of "$15.59USD". */
2174 /* PURCHASE_CURRENCY The currency type used to pay for the entity. Use ISO-4217 for the 3 letter currency code. */
2177 GST_MATROSKA_TAG_ID_COPYRIGHT, GST_TAG_COPYRIGHT}, {
2178 GST_MATROSKA_TAG_ID_PRODUCTION_COPYRIGHT, GST_TAG_COPYRIGHT}, { /* The copyright information as per the production copyright holder. This is akin to the TPRO tag in ID3. */
2179 GST_MATROSKA_TAG_ID_LICENSE, GST_TAG_LICENSE}, { /* The license applied to the content (like Creative Commons variants). */
2180 GST_MATROSKA_TAG_ID_TERMS_OF_USE, GST_TAG_LICENSE}
2185 const gchar *matroska_tagname;
2186 const gchar *gstreamer_tagname;
2190 child_tag_conv[] = {
2192 "TITLE/SORT_WITH=", GST_TAG_TITLE_SORTNAME}, {
2193 "ARTIST/SORT_WITH=", GST_TAG_ARTIST_SORTNAME}, {
2194 /* ALBUM-stuff is handled elsewhere */
2195 "COMPOSER/SORT_WITH=", GST_TAG_TITLE_SORTNAME}, {
2196 "ORIGINAL/URL=", GST_TAG_LOCATION}, {
2197 /* EMAIL, PHONE, FAX all can be mapped to GST_TAG_CONTACT, there is special
2198 * code for that later.
2200 "TITLE/URL=", GST_TAG_HOMEPAGE}, {
2201 "ARTIST/URL=", GST_TAG_HOMEPAGE}, {
2202 "COPYRIGHT/URL=", GST_TAG_COPYRIGHT_URI}, {
2203 "LICENSE/URL=", GST_TAG_LICENSE_URI}, {
2204 "LICENSE/URL=", GST_TAG_LICENSE_URI}
2209 gchar *value = NULL;
2211 gchar *name_with_parent = NULL;
2212 GstTagList *child_taglist = NULL;
2214 DEBUG_ELEMENT_START (common, ebml, "SimpleTag");
2216 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2217 DEBUG_ELEMENT_STOP (common, ebml, "SimpleTag", ret);
2222 child_taglist = *p_taglist;
2224 child_taglist = gst_tag_list_new_empty ();
2226 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
2227 /* read all sub-entries */
2229 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
2233 case GST_MATROSKA_ID_TAGNAME:
2236 ret = gst_ebml_read_ascii (ebml, &id, &tag);
2237 GST_DEBUG_OBJECT (common->sinkpad, "TagName: %s", GST_STR_NULL (tag));
2238 g_free (name_with_parent);
2240 name_with_parent = g_strdup_printf ("%s/%s", parent, tag);
2242 name_with_parent = g_strdup (tag);
2245 case GST_MATROSKA_ID_TAGSTRING:
2248 ret = gst_ebml_read_utf8 (ebml, &id, &value);
2249 GST_DEBUG_OBJECT (common->sinkpad, "TagString: %s",
2250 GST_STR_NULL (value));
2253 case GST_MATROSKA_ID_SIMPLETAG:
2254 /* Recursive SimpleTag */
2255 /* This implementation requires tag name of _this_ tag to be known
2256 * in order to read its children. It's not in the spec, just the way
2257 * the code is written.
2259 if (name_with_parent != NULL) {
2260 ret = gst_matroska_read_common_parse_metadata_id_simple_tag (common,
2261 ebml, &child_taglist, name_with_parent);
2267 ret = gst_matroska_read_common_parse_skip (common, ebml, "SimpleTag",
2271 case GST_MATROSKA_ID_TAGLANGUAGE:
2272 case GST_MATROSKA_ID_TAGDEFAULT:
2273 case GST_MATROSKA_ID_TAGBINARY:
2274 ret = gst_ebml_read_skip (ebml);
2279 DEBUG_ELEMENT_STOP (common, ebml, "SimpleTag", ret);
2281 if (parent && tag && value && *value != '\0') {
2282 /* Don't bother mapping children tags - parent will do that */
2284 /* TODO: read LANGUAGE sub-tag, and use "key[lc]=val" form */
2285 key_val = g_strdup_printf ("%s=%s", name_with_parent, value);
2286 gst_tag_list_add (*p_taglist, GST_TAG_MERGE_APPEND,
2287 GST_TAG_EXTENDED_COMMENT, key_val, NULL);
2289 } else if (tag && value && *value != '\0') {
2290 gboolean matched = FALSE;
2293 for (i = 0; !matched && i < G_N_ELEMENTS (tag_conv); i++) {
2294 const gchar *tagname_gst = tag_conv[i].gstreamer_tagname;
2296 const gchar *tagname_mkv = tag_conv[i].matroska_tagname;
2298 if (strcmp (tagname_mkv, tag) == 0) {
2299 GValue dest = { 0, };
2300 GType dest_type = gst_tag_get_type (tagname_gst);
2302 /* Ensure that any date string is complete */
2303 if (dest_type == G_TYPE_DATE) {
2304 guint year = 1901, month = 1, day = 1;
2306 /* Dates can be yyyy-MM-dd, yyyy-MM or yyyy, but we need
2308 if (sscanf (value, "%04u-%02u-%02u", &year, &month, &day) != 0) {
2310 value = g_strdup_printf ("%04u-%02u-%02u", year, month, day);
2314 g_value_init (&dest, dest_type);
2315 if (gst_value_deserialize (&dest, value)) {
2316 gst_tag_list_add_values (*p_taglist, GST_TAG_MERGE_APPEND,
2317 tagname_gst, &dest, NULL);
2319 GST_WARNING_OBJECT (common->sinkpad, "Can't transform tag '%s' with "
2320 "value '%s' to target type '%s'", tag, value,
2321 g_type_name (dest_type));
2323 g_value_unset (&dest);
2329 /* TODO: read LANGUAGE sub-tag, and use "key[lc]=val" form */
2330 key_val = g_strdup_printf ("%s=%s", tag, value);
2331 gst_tag_list_add (*p_taglist, GST_TAG_MERGE_APPEND,
2332 GST_TAG_EXTENDED_COMMENT, key_val, NULL);
2338 /* Map children tags. This only supports top-anchored mapping. That is,
2339 * we start at toplevel tag (this tag), and see how its combinations
2340 * with its children can be mapped. Which means that grandchildren
2341 * are also combined here, with _this_ tag taken into consideration.
2342 * If grandchildren can be combined only with children, that combination
2345 gint child_tags_n = gst_tag_list_n_tags (child_taglist);
2346 if (child_tags_n > 0) {
2348 for (i = 0; i < child_tags_n; i++) {
2350 const gchar *child_name = gst_tag_list_nth_tag_name (child_taglist, i);
2351 guint taglen = gst_tag_list_get_tag_size (child_taglist, child_name);
2352 for (j = 0; j < taglen; j++) {
2354 gboolean matched = FALSE;
2355 gchar *val_pre, *val_post;
2358 if (!gst_tag_list_get_string_index (child_taglist, child_name,
2361 if (!strchr (val, '=')) {
2365 val_post = g_strdup (strchr (val, '=') + 1);
2366 val_pre = g_strdup (val);
2367 *(strchr (val_pre, '=') + 1) = '\0';
2369 for (k = 0; !matched && k < G_N_ELEMENTS (child_tag_conv); k++) {
2370 const gchar *tagname_gst = child_tag_conv[k].gstreamer_tagname;
2372 const gchar *tagname_mkv = child_tag_conv[k].matroska_tagname;
2374 /* TODO: Once "key[lc]=value" form support is implemented,
2375 * strip [lc] here. It can't be used in combined tags.
2376 * If a tag is not combined, leave [lc] as it is.
2378 if (strcmp (tagname_mkv, val_pre) == 0) {
2379 GValue dest = { 0, };
2380 GType dest_type = gst_tag_get_type (tagname_gst);
2382 g_value_init (&dest, dest_type);
2383 if (gst_value_deserialize (&dest, val_post)) {
2384 gst_tag_list_add_values (*p_taglist, GST_TAG_MERGE_APPEND,
2385 tagname_gst, &dest, NULL);
2387 GST_WARNING_OBJECT (common->sinkpad,
2388 "Can't transform complex tag '%s' " "to target type '%s'",
2389 val, g_type_name (dest_type));
2391 g_value_unset (&dest);
2396 gchar *last_slash = strrchr (val_pre, '/');
2399 if (strcmp (last_slash, "EMAIL=") == 0 ||
2400 strcmp (last_slash, "PHONE=") == 0 ||
2401 strcmp (last_slash, "ADDRESS=") == 0 ||
2402 strcmp (last_slash, "FAX=") == 0) {
2403 gst_tag_list_add (*p_taglist, GST_TAG_MERGE_APPEND,
2404 GST_TAG_CONTACT, val_post, NULL);
2410 gst_tag_list_add (*p_taglist, GST_TAG_MERGE_APPEND,
2411 GST_TAG_EXTENDED_COMMENT, val, NULL);
2418 gst_tag_list_unref (child_taglist);
2423 g_free (name_with_parent);
2430 gst_matroska_read_common_count_streams (GstMatroskaReadCommon * common,
2431 gint * a, gint * v, gint * s)
2434 gint video_streams = 0, audio_streams = 0, subtitle_streams = 0;
2436 for (i = 0; i < common->src->len; i++) {
2437 GstMatroskaTrackContext *stream;
2439 stream = g_ptr_array_index (common->src, i);
2440 if (stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO)
2442 else if (stream->type == GST_MATROSKA_TRACK_TYPE_AUDIO)
2444 else if (stream->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)
2445 subtitle_streams += 1;
2449 *s = subtitle_streams;
2454 gst_matroska_read_common_apply_target_type_foreach (const GstTagList * list,
2455 const gchar * tag, gpointer user_data)
2459 TargetTypeContext *ctx = (TargetTypeContext *) user_data;
2461 vallen = gst_tag_list_get_tag_size (list, tag);
2465 for (i = 0; i < vallen; i++) {
2466 const GValue *val_ref;
2468 val_ref = gst_tag_list_get_value_index (list, tag, i);
2469 if (val_ref == NULL)
2472 /* TODO: use the optional ctx->target_type somehow */
2473 if (strcmp (tag, GST_TAG_TITLE) == 0) {
2474 if (ctx->target_type_value >= 70 && !ctx->audio_only) {
2475 gst_tag_list_add_value (ctx->result, GST_TAG_MERGE_APPEND,
2476 GST_TAG_SHOW_NAME, val_ref);
2478 } else if (ctx->target_type_value >= 50) {
2479 gst_tag_list_add_value (ctx->result, GST_TAG_MERGE_APPEND,
2480 GST_TAG_TITLE, val_ref);
2483 } else if (strcmp (tag, GST_TAG_TITLE_SORTNAME) == 0) {
2484 if (ctx->target_type_value >= 70 && !ctx->audio_only) {
2485 gst_tag_list_add_value (ctx->result, GST_TAG_MERGE_APPEND,
2486 GST_TAG_SHOW_SORTNAME, val_ref);
2488 } else if (ctx->target_type_value >= 50) {
2489 gst_tag_list_add_value (ctx->result, GST_TAG_MERGE_APPEND,
2490 GST_TAG_TITLE_SORTNAME, val_ref);
2493 } else if (strcmp (tag, GST_TAG_ARTIST) == 0) {
2494 if (ctx->target_type_value >= 50) {
2495 gst_tag_list_add_value (ctx->result, GST_TAG_MERGE_APPEND,
2496 GST_TAG_ARTIST, val_ref);
2499 } else if (strcmp (tag, GST_TAG_ARTIST_SORTNAME) == 0) {
2500 if (ctx->target_type_value >= 50) {
2501 gst_tag_list_add_value (ctx->result, GST_TAG_MERGE_APPEND,
2502 GST_TAG_ARTIST_SORTNAME, val_ref);
2505 } else if (strcmp (tag, GST_TAG_TRACK_COUNT) == 0) {
2506 if (ctx->target_type_value >= 60) {
2507 gst_tag_list_add_value (ctx->result, GST_TAG_MERGE_APPEND,
2508 GST_TAG_ALBUM_VOLUME_COUNT, val_ref);
2511 } else if (strcmp (tag, GST_TAG_TRACK_NUMBER) == 0) {
2512 if (ctx->target_type_value >= 60 && !ctx->audio_only) {
2513 gst_tag_list_add_value (ctx->result, GST_TAG_MERGE_APPEND,
2514 GST_TAG_SHOW_SEASON_NUMBER, val_ref);
2516 } else if (ctx->target_type_value >= 50 && !ctx->audio_only) {
2517 gst_tag_list_add_value (ctx->result, GST_TAG_MERGE_APPEND,
2518 GST_TAG_SHOW_EPISODE_NUMBER, val_ref);
2520 } else if (ctx->target_type_value >= 50) {
2521 gst_tag_list_add_value (ctx->result, GST_TAG_MERGE_APPEND,
2522 GST_TAG_ALBUM_VOLUME_NUMBER, val_ref);
2526 gst_tag_list_add_value (ctx->result, GST_TAG_MERGE_APPEND, tag, val_ref);
2532 gst_matroska_read_common_apply_target_type (GstMatroskaReadCommon * common,
2533 GstTagList * taglist, guint64 target_type_value, gchar * target_type)
2535 TargetTypeContext ctx;
2540 gst_matroska_read_common_count_streams (common, &a, &v, &s);
2542 ctx.audio_only = (a > 0 && v == 0 && s == 0);
2543 ctx.result = gst_tag_list_new_empty ();
2544 ctx.target_type_value = target_type_value;
2545 ctx.target_type = target_type;
2547 gst_tag_list_foreach (taglist,
2548 gst_matroska_read_common_apply_target_type_foreach, &ctx);
2550 gst_tag_list_unref (taglist);
2555 static GstFlowReturn
2556 gst_matroska_read_common_parse_metadata_id_tag (GstMatroskaReadCommon * common,
2557 GstEbmlRead * ebml, GstTagList ** p_taglist)
2561 GArray *chapter_targets, *edition_targets, *track_targets;
2562 GstTagList *taglist;
2563 GList *cur, *internal_cur;
2564 guint64 target_type_value = 50;
2565 gchar *target_type = NULL;
2567 DEBUG_ELEMENT_START (common, ebml, "Tag");
2569 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2570 DEBUG_ELEMENT_STOP (common, ebml, "Tag", ret);
2574 edition_targets = g_array_new (FALSE, FALSE, sizeof (guint64));
2575 chapter_targets = g_array_new (FALSE, FALSE, sizeof (guint64));
2576 track_targets = g_array_new (FALSE, FALSE, sizeof (guint64));
2577 taglist = gst_tag_list_new_empty ();
2580 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
2581 /* read all sub-entries */
2583 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
2587 case GST_MATROSKA_ID_SIMPLETAG:
2588 ret = gst_matroska_read_common_parse_metadata_id_simple_tag (common,
2589 ebml, &taglist, NULL);
2592 case GST_MATROSKA_ID_TARGETS:
2593 g_free (target_type);
2595 target_type_value = 50;
2596 ret = gst_matroska_read_common_parse_metadata_targets (common, ebml,
2597 edition_targets, chapter_targets, track_targets,
2598 &target_type_value, &target_type);
2602 ret = gst_matroska_read_common_parse_skip (common, ebml, "Tag", id);
2607 DEBUG_ELEMENT_STOP (common, ebml, "Tag", ret);
2609 taglist = gst_matroska_read_common_apply_target_type (common, taglist,
2610 target_type_value, target_type);
2611 g_free (target_type);
2613 /* if tag is chapter/edition specific - try to find that entry */
2614 if (G_UNLIKELY (chapter_targets->len > 0 || edition_targets->len > 0 ||
2615 track_targets->len > 0)) {
2617 if (chapter_targets->len > 0 || edition_targets->len > 0) {
2618 if (common->toc == NULL)
2619 GST_WARNING_OBJECT (common->sinkpad,
2620 "Found chapter/edition specific tag, but TOC is not present");
2622 cur = gst_toc_get_entries (common->toc);
2623 internal_cur = gst_toc_get_entries (common->internal_toc);
2624 while (cur != NULL && internal_cur != NULL) {
2625 gst_matroska_read_common_parse_toc_tag (cur->data, internal_cur->data,
2626 edition_targets, chapter_targets, taglist);
2628 internal_cur = internal_cur->next;
2630 common->toc_updated = TRUE;
2633 for (i = 0; i < track_targets->len; i++) {
2635 gboolean found = FALSE;
2636 guint64 tgt = g_array_index (track_targets, guint64, i);
2638 for (j = 0; j < common->src->len; j++) {
2639 GstMatroskaTrackContext *stream = g_ptr_array_index (common->src, j);
2641 if (stream->uid == tgt) {
2642 gst_tag_list_insert (stream->tags, taglist, GST_TAG_MERGE_REPLACE);
2643 stream->tags_changed = TRUE;
2648 /* Cache the track taglist: possibly belongs to a track that will be parsed
2649 later in gst_matroska_demux.c:gst_matroska_demux_add_stream (...) */
2650 gpointer track_uid = GUINT_TO_POINTER (tgt);
2651 GstTagList *cached_taglist =
2652 g_hash_table_lookup (common->cached_track_taglists, track_uid);
2654 gst_tag_list_insert (cached_taglist, taglist, GST_TAG_MERGE_REPLACE);
2656 gst_tag_list_ref (taglist);
2657 g_hash_table_insert (common->cached_track_taglists, track_uid,
2660 GST_DEBUG_OBJECT (common->sinkpad,
2661 "Found track-specific tag(s), but track %" G_GUINT64_FORMAT
2662 " is not known yet, caching", tgt);
2666 gst_tag_list_insert (*p_taglist, taglist, GST_TAG_MERGE_APPEND);
2668 gst_tag_list_unref (taglist);
2669 g_array_unref (chapter_targets);
2670 g_array_unref (edition_targets);
2671 g_array_unref (track_targets);
2677 gst_matroska_read_common_parse_metadata (GstMatroskaReadCommon * common,
2678 GstElement * el, GstEbmlRead * ebml)
2680 GstTagList *taglist;
2681 GstFlowReturn ret = GST_FLOW_OK;
2686 /* Make sure we don't parse a tags element twice and
2687 * post it's tags twice */
2688 curpos = gst_ebml_read_get_pos (ebml);
2689 for (l = common->tags_parsed; l; l = l->next) {
2690 guint64 *pos = l->data;
2692 if (*pos == curpos) {
2693 GST_DEBUG_OBJECT (common->sinkpad,
2694 "Skipping already parsed Tags at offset %" G_GUINT64_FORMAT, curpos);
2699 common->tags_parsed =
2700 g_list_prepend (common->tags_parsed, g_slice_new (guint64));
2701 *((guint64 *) common->tags_parsed->data) = curpos;
2704 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2705 DEBUG_ELEMENT_STOP (common, ebml, "Tags", ret);
2709 taglist = gst_tag_list_new_empty ();
2710 gst_tag_list_set_scope (taglist, GST_TAG_SCOPE_GLOBAL);
2711 common->toc_updated = FALSE;
2713 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
2714 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
2718 case GST_MATROSKA_ID_TAG:
2719 ret = gst_matroska_read_common_parse_metadata_id_tag (common, ebml,
2724 ret = gst_matroska_read_common_parse_skip (common, ebml, "Tags", id);
2726 /* FIXME: Use to limit the tags to specific pads */
2730 DEBUG_ELEMENT_STOP (common, ebml, "Tags", ret);
2732 if (G_LIKELY (!gst_tag_list_is_empty (taglist)))
2733 gst_matroska_read_common_found_global_tag (common, el, taglist);
2735 gst_tag_list_unref (taglist);
2740 static GstFlowReturn
2741 gst_matroska_read_common_peek_adapter (GstMatroskaReadCommon * common, guint
2742 peek, const guint8 ** data)
2744 /* Caller needs to gst_adapter_unmap. */
2745 *data = gst_adapter_map (common->adapter, peek);
2747 return GST_FLOW_EOS;
2753 * Calls pull_range for (offset,size) without advancing our offset
2756 gst_matroska_read_common_peek_bytes (GstMatroskaReadCommon * common, guint64
2757 offset, guint size, GstBuffer ** p_buf, guint8 ** bytes)
2761 /* Caching here actually makes much less difference than one would expect.
2762 * We do it mainly to avoid pulling buffers of 1 byte all the time */
2763 if (common->cached_buffer) {
2764 guint64 cache_offset = GST_BUFFER_OFFSET (common->cached_buffer);
2765 gsize cache_size = gst_buffer_get_size (common->cached_buffer);
2767 if (cache_offset <= common->offset &&
2768 (common->offset + size) <= (cache_offset + cache_size)) {
2770 *p_buf = gst_buffer_copy_region (common->cached_buffer,
2771 GST_BUFFER_COPY_ALL, common->offset - cache_offset, size);
2773 if (!common->cached_data) {
2774 gst_buffer_map (common->cached_buffer, &common->cached_map,
2776 common->cached_data = common->cached_map.data;
2778 *bytes = common->cached_data + common->offset - cache_offset;
2782 /* not enough data in the cache, free cache and get a new one */
2783 if (common->cached_data) {
2784 gst_buffer_unmap (common->cached_buffer, &common->cached_map);
2785 common->cached_data = NULL;
2787 gst_buffer_unref (common->cached_buffer);
2788 common->cached_buffer = NULL;
2791 /* refill the cache */
2792 ret = gst_pad_pull_range (common->sinkpad, common->offset,
2793 MAX (size, 64 * 1024), &common->cached_buffer);
2794 if (ret != GST_FLOW_OK) {
2795 common->cached_buffer = NULL;
2799 if (gst_buffer_get_size (common->cached_buffer) >= size) {
2801 *p_buf = gst_buffer_copy_region (common->cached_buffer,
2802 GST_BUFFER_COPY_ALL, 0, size);
2804 gst_buffer_map (common->cached_buffer, &common->cached_map, GST_MAP_READ);
2805 common->cached_data = common->cached_map.data;
2806 *bytes = common->cached_data;
2811 /* Not possible to get enough data, try a last time with
2812 * requesting exactly the size we need */
2813 gst_buffer_unref (common->cached_buffer);
2814 common->cached_buffer = NULL;
2817 gst_pad_pull_range (common->sinkpad, common->offset, size,
2818 &common->cached_buffer);
2819 if (ret != GST_FLOW_OK) {
2820 GST_DEBUG_OBJECT (common->sinkpad, "pull_range returned %d", ret);
2828 if (gst_buffer_get_size (common->cached_buffer) < size) {
2829 GST_WARNING_OBJECT (common->sinkpad, "Dropping short buffer at offset %"
2830 G_GUINT64_FORMAT ": wanted %u bytes, got %" G_GSIZE_FORMAT " bytes",
2831 common->offset, size, gst_buffer_get_size (common->cached_buffer));
2833 gst_buffer_unref (common->cached_buffer);
2834 common->cached_buffer = NULL;
2839 return GST_FLOW_EOS;
2843 *p_buf = gst_buffer_copy_region (common->cached_buffer,
2844 GST_BUFFER_COPY_ALL, 0, size);
2846 gst_buffer_map (common->cached_buffer, &common->cached_map, GST_MAP_READ);
2847 common->cached_data = common->cached_map.data;
2848 *bytes = common->cached_data;
2854 static GstFlowReturn
2855 gst_matroska_read_common_peek_pull (GstMatroskaReadCommon * common, guint peek,
2858 return gst_matroska_read_common_peek_bytes (common, common->offset, peek,
2863 gst_matroska_read_common_peek_id_length_pull (GstMatroskaReadCommon * common,
2864 GstElement * el, guint32 * _id, guint64 * _length, guint * _needed)
2866 return gst_ebml_peek_id_length (_id, _length, _needed,
2867 (GstPeekData) gst_matroska_read_common_peek_pull, (gpointer) common, el,
2872 gst_matroska_read_common_peek_id_length_push (GstMatroskaReadCommon * common,
2873 GstElement * el, guint32 * _id, guint64 * _length, guint * _needed)
2877 ret = gst_ebml_peek_id_length (_id, _length, _needed,
2878 (GstPeekData) gst_matroska_read_common_peek_adapter, (gpointer) common,
2879 el, common->offset);
2881 gst_adapter_unmap (common->adapter);
2886 static GstFlowReturn
2887 gst_matroska_read_common_read_track_encoding (GstMatroskaReadCommon * common,
2888 GstEbmlRead * ebml, GstMatroskaTrackContext * context)
2890 GstMatroskaTrackEncoding enc = { 0, };
2894 DEBUG_ELEMENT_START (common, ebml, "ContentEncoding");
2895 /* Set default values */
2897 /* All other default values are 0 */
2899 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2900 DEBUG_ELEMENT_STOP (common, ebml, "ContentEncoding", ret);
2904 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
2905 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
2909 case GST_MATROSKA_ID_CONTENTENCODINGORDER:{
2912 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
2915 if (!gst_matroska_read_common_encoding_order_unique (context->encodings,
2917 GST_ERROR_OBJECT (common->sinkpad,
2918 "ContentEncodingOrder %" G_GUINT64_FORMAT
2919 "is not unique for track %" G_GUINT64_FORMAT, num, context->num);
2920 ret = GST_FLOW_ERROR;
2924 GST_DEBUG_OBJECT (common->sinkpad,
2925 "ContentEncodingOrder: %" G_GUINT64_FORMAT, num);
2929 case GST_MATROSKA_ID_CONTENTENCODINGSCOPE:{
2932 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
2935 if (num > 7 || num == 0) {
2936 GST_ERROR_OBJECT (common->sinkpad, "Invalid ContentEncodingScope %"
2937 G_GUINT64_FORMAT, num);
2938 ret = GST_FLOW_ERROR;
2942 GST_DEBUG_OBJECT (common->sinkpad,
2943 "ContentEncodingScope: %" G_GUINT64_FORMAT, num);
2948 case GST_MATROSKA_ID_CONTENTENCODINGTYPE:{
2951 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
2955 GST_ERROR_OBJECT (common->sinkpad, "Invalid ContentEncodingType %"
2956 G_GUINT64_FORMAT, num);
2957 ret = GST_FLOW_ERROR;
2961 if ((!common->is_webm) && (num == GST_MATROSKA_ENCODING_ENCRYPTION)) {
2962 GST_ERROR_OBJECT (common->sinkpad,
2963 "Encrypted tracks are supported only in WebM");
2964 ret = GST_FLOW_ERROR;
2967 GST_DEBUG_OBJECT (common->sinkpad,
2968 "ContentEncodingType: %" G_GUINT64_FORMAT, num);
2972 case GST_MATROSKA_ID_CONTENTCOMPRESSION:{
2974 DEBUG_ELEMENT_START (common, ebml, "ContentCompression");
2976 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
2979 while (ret == GST_FLOW_OK &&
2980 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
2981 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
2985 case GST_MATROSKA_ID_CONTENTCOMPALGO:{
2988 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK) {
2992 GST_ERROR_OBJECT (common->sinkpad, "Invalid ContentCompAlgo %"
2993 G_GUINT64_FORMAT, num);
2994 ret = GST_FLOW_ERROR;
2997 GST_DEBUG_OBJECT (common->sinkpad,
2998 "ContentCompAlgo: %" G_GUINT64_FORMAT, num);
2999 enc.comp_algo = num;
3003 case GST_MATROSKA_ID_CONTENTCOMPSETTINGS:{
3008 gst_ebml_read_binary (ebml, &id, &data,
3009 &size)) != GST_FLOW_OK) {
3012 enc.comp_settings = data;
3013 enc.comp_settings_length = size;
3014 GST_DEBUG_OBJECT (common->sinkpad,
3015 "ContentCompSettings of size %" G_GUINT64_FORMAT, size);
3019 GST_WARNING_OBJECT (common->sinkpad,
3020 "Unknown ContentCompression subelement 0x%x - ignoring", id);
3021 ret = gst_ebml_read_skip (ebml);
3025 DEBUG_ELEMENT_STOP (common, ebml, "ContentCompression", ret);
3029 case GST_MATROSKA_ID_CONTENTENCRYPTION:{
3031 DEBUG_ELEMENT_START (common, ebml, "ContentEncryption");
3033 if (enc.type != GST_MATROSKA_ENCODING_ENCRYPTION) {
3034 GST_WARNING_OBJECT (common->sinkpad,
3035 "Unexpected to have Content Encryption because it isn't encryption type");
3036 ret = GST_FLOW_ERROR;
3040 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
3043 while (ret == GST_FLOW_OK &&
3044 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3045 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3049 case GST_MATROSKA_ID_CONTENTENCALGO:{
3052 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK) {
3056 if (num > GST_MATROSKA_TRACK_ENCRYPTION_ALGORITHM_AES) {
3057 GST_ERROR_OBJECT (common->sinkpad, "Invalid ContentEncAlgo %"
3058 G_GUINT64_FORMAT, num);
3059 ret = GST_FLOW_ERROR;
3062 GST_DEBUG_OBJECT (common->sinkpad,
3063 "ContentEncAlgo: %" G_GUINT64_FORMAT, num);
3068 case GST_MATROSKA_ID_CONTENTENCAESSETTINGS:{
3070 DEBUG_ELEMENT_START (common, ebml, "ContentEncAESSettings");
3072 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
3075 while (ret == GST_FLOW_OK &&
3076 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3077 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3081 case GST_MATROSKA_ID_AESSETTINGSCIPHERMODE:{
3085 gst_ebml_read_uint (ebml, &id,
3086 &num)) != GST_FLOW_OK) {
3090 GST_ERROR_OBJECT (common->sinkpad, "Invalid Cipher Mode %"
3091 G_GUINT64_FORMAT, num);
3092 ret = GST_FLOW_ERROR;
3095 GST_DEBUG_OBJECT (common->sinkpad,
3096 "ContentEncAESSettings: %" G_GUINT64_FORMAT, num);
3097 enc.enc_cipher_mode = num;
3101 GST_WARNING_OBJECT (common->sinkpad,
3102 "Unknown ContentEncAESSettings subelement 0x%x - ignoring",
3104 ret = gst_ebml_read_skip (ebml);
3108 DEBUG_ELEMENT_STOP (common, ebml, "ContentEncAESSettings", ret);
3112 case GST_MATROSKA_ID_CONTENTENCKEYID:{
3115 GstBuffer *keyId_buf;
3119 gst_ebml_read_binary (ebml, &id, &data,
3120 &size)) != GST_FLOW_OK) {
3123 GST_DEBUG_OBJECT (common->sinkpad,
3124 "ContentEncrypt KeyID length : %" G_GUINT64_FORMAT, size);
3125 keyId_buf = gst_buffer_new_wrapped (data, size);
3127 /* Push an event containing the Key ID into the queues of all streams. */
3128 /* system_id field is set to GST_PROTECTION_UNSPECIFIED_SYSTEM_ID because it isn't specified neither in WebM nor in Matroska spec. */
3130 gst_event_new_protection
3131 (GST_PROTECTION_UNSPECIFIED_SYSTEM_ID, keyId_buf,
3133 GST_TRACE_OBJECT (common->sinkpad,
3134 "adding protection event for stream %d", context->index);
3135 g_queue_push_tail (&context->protection_event_queue, event);
3137 context->protection_info =
3138 gst_structure_new ("application/x-cenc", "iv_size",
3139 G_TYPE_UINT, 8, "encrypted", G_TYPE_BOOLEAN, TRUE, "kid",
3140 GST_TYPE_BUFFER, keyId_buf, NULL);
3142 gst_buffer_unref (keyId_buf);
3146 GST_WARNING_OBJECT (common->sinkpad,
3147 "Unknown ContentEncryption subelement 0x%x - ignoring", id);
3148 ret = gst_ebml_read_skip (ebml);
3152 DEBUG_ELEMENT_STOP (common, ebml, "ContentEncryption", ret);
3156 GST_WARNING_OBJECT (common->sinkpad,
3157 "Unknown ContentEncoding subelement 0x%x - ignoring", id);
3158 ret = gst_ebml_read_skip (ebml);
3163 DEBUG_ELEMENT_STOP (common, ebml, "ContentEncoding", ret);
3164 if (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)
3167 /* TODO: Check if the combination of values is valid */
3169 g_array_append_val (context->encodings, enc);
3175 gst_matroska_read_common_read_track_encodings (GstMatroskaReadCommon * common,
3176 GstEbmlRead * ebml, GstMatroskaTrackContext * context)
3181 DEBUG_ELEMENT_START (common, ebml, "ContentEncodings");
3183 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3184 DEBUG_ELEMENT_STOP (common, ebml, "ContentEncodings", ret);
3188 context->encodings =
3189 g_array_sized_new (FALSE, FALSE, sizeof (GstMatroskaTrackEncoding), 1);
3191 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3192 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3196 case GST_MATROSKA_ID_CONTENTENCODING:
3197 ret = gst_matroska_read_common_read_track_encoding (common, ebml,
3201 GST_WARNING_OBJECT (common->sinkpad,
3202 "Unknown ContentEncodings subelement 0x%x - ignoring", id);
3203 ret = gst_ebml_read_skip (ebml);
3208 DEBUG_ELEMENT_STOP (common, ebml, "ContentEncodings", ret);
3209 if (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)
3212 /* Sort encodings according to their order */
3213 g_array_sort (context->encodings,
3214 (GCompareFunc) gst_matroska_read_common_encoding_cmp);
3216 return gst_matroska_decode_content_encodings (context->encodings);
3220 gst_matroska_read_common_free_parsed_el (gpointer mem, gpointer user_data)
3222 g_slice_free (guint64, mem);
3226 gst_matroska_read_common_init (GstMatroskaReadCommon * ctx)
3229 ctx->writing_app = NULL;
3230 ctx->muxing_app = NULL;
3232 ctx->global_tags = NULL;
3233 ctx->adapter = gst_adapter_new ();
3235 ctx->internal_toc = NULL;
3236 ctx->toc_updated = FALSE;
3237 ctx->cached_track_taglists =
3238 g_hash_table_new_full (NULL, NULL, NULL,
3239 (GDestroyNotify) gst_tag_list_unref);
3243 gst_matroska_read_common_finalize (GstMatroskaReadCommon * ctx)
3246 g_ptr_array_free (ctx->src, TRUE);
3250 if (ctx->global_tags) {
3251 gst_tag_list_unref (ctx->global_tags);
3252 ctx->global_tags = NULL;
3256 gst_toc_unref (ctx->toc);
3259 if (ctx->internal_toc) {
3260 gst_toc_unref (ctx->internal_toc);
3261 ctx->internal_toc = NULL;
3264 ctx->toc_updated = FALSE;
3266 g_object_unref (ctx->adapter);
3267 g_hash_table_remove_all (ctx->cached_track_taglists);
3268 g_hash_table_unref (ctx->cached_track_taglists);
3273 gst_matroska_read_common_reset (GstElement * element,
3274 GstMatroskaReadCommon * ctx)
3278 GST_LOG_OBJECT (ctx->sinkpad, "resetting read context");
3281 ctx->state = GST_MATROSKA_READ_STATE_START;
3283 /* clean up existing streams if any */
3285 g_assert (ctx->src->len == ctx->num_streams);
3286 for (i = 0; i < ctx->src->len; i++) {
3287 GstMatroskaTrackContext *context = g_ptr_array_index (ctx->src, i);
3289 if (context->pad != NULL)
3290 gst_element_remove_pad (element, context->pad);
3292 gst_matroska_track_free (context);
3294 g_ptr_array_free (ctx->src, TRUE);
3296 ctx->src = g_ptr_array_new ();
3297 ctx->num_streams = 0;
3299 /* reset media info */
3300 g_free (ctx->writing_app);
3301 ctx->writing_app = NULL;
3302 g_free (ctx->muxing_app);
3303 ctx->muxing_app = NULL;
3305 /* reset stream type */
3306 ctx->is_webm = FALSE;
3307 ctx->has_video = FALSE;
3311 g_array_free (ctx->index, TRUE);
3316 ctx->time_scale = 1000000;
3317 ctx->created = G_MININT64;
3319 /* cues/tracks/segmentinfo */
3320 ctx->index_parsed = FALSE;
3321 ctx->segmentinfo_parsed = FALSE;
3322 ctx->attachments_parsed = FALSE;
3323 ctx->chapters_parsed = FALSE;
3326 ctx->global_tags_changed = FALSE;
3327 g_list_foreach (ctx->tags_parsed,
3328 (GFunc) gst_matroska_read_common_free_parsed_el, NULL);
3329 g_list_free (ctx->tags_parsed);
3330 ctx->tags_parsed = NULL;
3331 if (ctx->global_tags) {
3332 gst_tag_list_unref (ctx->global_tags);
3334 ctx->global_tags = gst_tag_list_new_empty ();
3335 gst_tag_list_set_scope (ctx->global_tags, GST_TAG_SCOPE_GLOBAL);
3337 gst_segment_init (&ctx->segment, GST_FORMAT_TIME);
3339 ctx->start_resync_offset = -1;
3340 ctx->state_to_restore = -1;
3342 if (ctx->cached_buffer) {
3343 if (ctx->cached_data) {
3344 gst_buffer_unmap (ctx->cached_buffer, &ctx->cached_map);
3345 ctx->cached_data = NULL;
3347 gst_buffer_unref (ctx->cached_buffer);
3348 ctx->cached_buffer = NULL;
3351 /* free chapters TOC if any */
3353 gst_toc_unref (ctx->toc);
3356 if (ctx->internal_toc) {
3357 gst_toc_unref (ctx->internal_toc);
3358 ctx->internal_toc = NULL;
3360 ctx->toc_updated = FALSE;
3363 /* call with object lock held */
3365 gst_matroska_read_common_reset_streams (GstMatroskaReadCommon * common,
3366 GstClockTime time, gboolean full)
3370 GST_DEBUG_OBJECT (common->sinkpad, "resetting stream state");
3372 g_assert (common->src->len == common->num_streams);
3373 for (i = 0; i < common->src->len; i++) {
3374 GstMatroskaTrackContext *context = g_ptr_array_index (common->src, i);
3375 context->pos = time;
3376 context->set_discont = TRUE;
3377 context->eos = FALSE;
3378 context->from_time = GST_CLOCK_TIME_NONE;
3379 if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
3380 GstMatroskaTrackVideoContext *videocontext =
3381 (GstMatroskaTrackVideoContext *) context;
3382 /* demux object lock held by caller */
3383 videocontext->earliest_time = GST_CLOCK_TIME_NONE;
3389 gst_matroska_read_common_tracknumber_unique (GstMatroskaReadCommon * common,
3394 g_assert (common->src->len == common->num_streams);
3395 for (i = 0; i < common->src->len; i++) {
3396 GstMatroskaTrackContext *context = g_ptr_array_index (common->src, i);
3398 if (context->num == num)