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>
6 * matroska-demux.c: matroska file/stream demuxer
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details.
18 * You should have received a copy of the GNU Library General Public
19 * License along with this library; if not, write to the
20 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 * Boston, MA 02111-1307, USA.
24 /* TODO: check CRC32 if present
25 * TODO: there can be a segment after the first segment. Handle like
26 * chained oggs. Fixes #334082
27 * TODO: Test samples: http://www.matroska.org/samples/matrix/index.html
28 * http://samples.mplayerhq.hu/Matroska/
29 * TODO: check if demuxing is done correct for all codecs according to spec
30 * TODO: seeking with incomplete or without CUE
34 * SECTION:element-matroskademux
36 * matroskademux demuxes a Matroska file into the different contained streams.
39 * <title>Example launch line</title>
41 * gst-launch -v filesrc location=/path/to/mkv ! matroskademux ! vorbisdec ! audioconvert ! audioresample ! autoaudiosink
42 * ]| This pipeline demuxes a Matroska file and outputs the contained Vorbis audio.
54 /* For AVI compatibility mode
55 and for fourcc stuff */
56 #include <gst/riff/riff-read.h>
57 #include <gst/riff/riff-ids.h>
58 #include <gst/riff/riff-media.h>
60 #include <gst/tag/tag.h>
62 #include <gst/base/gsttypefindhelper.h>
74 #include "matroska-demux.h"
75 #include "matroska-ids.h"
77 GST_DEBUG_CATEGORY_STATIC (matroskademux_debug);
78 #define GST_CAT_DEFAULT matroskademux_debug
80 #define DEBUG_ELEMENT_START(demux, ebml, element) \
81 GST_DEBUG_OBJECT (demux, "Parsing " element " element at offset %" \
82 G_GUINT64_FORMAT, ebml->offset)
84 #define DEBUG_ELEMENT_STOP(demux, ebml, element, ret) \
85 GST_DEBUG_OBJECT (demux, "Parsing " element " element at offset %" \
86 G_GUINT64_FORMAT " finished with '%s'", ebml->offset, \
87 gst_flow_get_name (ret))
96 static GstStaticPadTemplate sink_templ = GST_STATIC_PAD_TEMPLATE ("sink",
99 GST_STATIC_CAPS ("video/x-matroska")
102 /* TODO: fill in caps! */
104 static GstStaticPadTemplate audio_src_templ =
105 GST_STATIC_PAD_TEMPLATE ("audio_%02d",
108 GST_STATIC_CAPS ("ANY")
111 static GstStaticPadTemplate video_src_templ =
112 GST_STATIC_PAD_TEMPLATE ("video_%02d",
115 GST_STATIC_CAPS ("ANY")
118 static GstStaticPadTemplate subtitle_src_templ =
119 GST_STATIC_PAD_TEMPLATE ("subtitle_%02d",
122 GST_STATIC_CAPS ("text/plain; application/x-ssa; application/x-ass; "
123 "application/x-usf; video/x-dvd-subpicture; "
124 "subpicture/x-pgs; subtitle/x-kate; "
125 "application/x-subtitle-unknown")
128 static GstFlowReturn gst_matroska_demux_parse_contents (GstMatroskaDemux *
131 /* element functions */
132 static void gst_matroska_demux_loop (GstPad * pad);
134 static gboolean gst_matroska_demux_element_send_event (GstElement * element,
136 static gboolean gst_matroska_demux_element_query (GstElement * element,
140 static gboolean gst_matroska_demux_sink_activate_pull (GstPad * sinkpad,
142 static gboolean gst_matroska_demux_sink_activate (GstPad * sinkpad);
144 static gboolean gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
145 GstPad * pad, GstEvent * event);
146 static gboolean gst_matroska_demux_handle_src_event (GstPad * pad,
148 static const GstQueryType *gst_matroska_demux_get_src_query_types (GstPad *
150 static gboolean gst_matroska_demux_handle_src_query (GstPad * pad,
153 static GstStateChangeReturn
154 gst_matroska_demux_change_state (GstElement * element,
155 GstStateChange transition);
157 gst_matroska_demux_set_index (GstElement * element, GstIndex * index);
158 static GstIndex *gst_matroska_demux_get_index (GstElement * element);
161 static GstCaps *gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext
163 const gchar * codec_id, guint8 * data, guint size, gchar ** codec_name);
164 static GstCaps *gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext
166 const gchar * codec_id, guint8 * data, guint size, gchar ** codec_name);
168 * gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
169 subtitlecontext, const gchar * codec_id, gpointer data, guint size);
172 static void gst_matroska_demux_reset (GstElement * element);
174 GST_BOILERPLATE (GstMatroskaDemux, gst_matroska_demux, GstEbmlRead,
178 gst_matroska_demux_base_init (gpointer klass)
180 GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
182 gst_element_class_add_pad_template (element_class,
183 gst_static_pad_template_get (&video_src_templ));
184 gst_element_class_add_pad_template (element_class,
185 gst_static_pad_template_get (&audio_src_templ));
186 gst_element_class_add_pad_template (element_class,
187 gst_static_pad_template_get (&subtitle_src_templ));
188 gst_element_class_add_pad_template (element_class,
189 gst_static_pad_template_get (&sink_templ));
191 gst_element_class_set_details_simple (element_class, "Matroska demuxer",
193 "Demuxes a Matroska Stream into video/audio/subtitles",
194 "Ronald Bultje <rbultje@ronald.bitfreak.net>");
198 gst_matroska_demux_finalize (GObject * object)
200 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (object);
203 g_ptr_array_free (demux->src, TRUE);
207 G_OBJECT_CLASS (parent_class)->finalize (object);
211 gst_matroska_demux_class_init (GstMatroskaDemuxClass * klass)
213 GObjectClass *gobject_class = (GObjectClass *) klass;
214 GstElementClass *gstelement_class = (GstElementClass *) klass;
216 GST_DEBUG_CATEGORY_INIT (matroskademux_debug, "matroskademux", 0,
219 gobject_class->finalize = gst_matroska_demux_finalize;
221 gstelement_class->change_state =
222 GST_DEBUG_FUNCPTR (gst_matroska_demux_change_state);
223 gstelement_class->send_event =
224 GST_DEBUG_FUNCPTR (gst_matroska_demux_element_send_event);
225 gstelement_class->query =
226 GST_DEBUG_FUNCPTR (gst_matroska_demux_element_query);
228 gstelement_class->set_index =
229 GST_DEBUG_FUNCPTR (gst_matroska_demux_set_index);
230 gstelement_class->get_index =
231 GST_DEBUG_FUNCPTR (gst_matroska_demux_get_index);
235 gst_matroska_demux_init (GstMatroskaDemux * demux,
236 GstMatroskaDemuxClass * klass)
238 demux->sinkpad = gst_pad_new_from_static_template (&sink_templ, "sink");
239 gst_pad_set_activate_function (demux->sinkpad,
240 GST_DEBUG_FUNCPTR (gst_matroska_demux_sink_activate));
241 gst_pad_set_activatepull_function (demux->sinkpad,
242 GST_DEBUG_FUNCPTR (gst_matroska_demux_sink_activate_pull));
243 gst_element_add_pad (GST_ELEMENT (demux), demux->sinkpad);
244 GST_EBML_READ (demux)->sinkpad = demux->sinkpad;
246 /* initial stream no. */
249 demux->writing_app = NULL;
250 demux->muxing_app = NULL;
254 gst_matroska_demux_reset (GST_ELEMENT (demux));
258 gst_matroska_track_free (GstMatroskaTrackContext * track)
260 g_free (track->codec_id);
261 g_free (track->codec_name);
262 g_free (track->name);
263 g_free (track->language);
264 g_free (track->codec_priv);
265 g_free (track->codec_state);
267 if (track->encodings != NULL) {
270 for (i = 0; i < track->encodings->len; ++i) {
271 GstMatroskaTrackEncoding *enc = &g_array_index (track->encodings,
272 GstMatroskaTrackEncoding,
275 g_free (enc->comp_settings);
277 g_array_free (track->encodings, TRUE);
280 if (track->pending_tags)
281 gst_tag_list_free (track->pending_tags);
283 if (track->index_table)
284 g_array_free (track->index_table, TRUE);
290 * Returns the aggregated GstFlowReturn.
293 gst_matroska_demux_combine_flows (GstMatroskaDemux * demux,
294 GstMatroskaTrackContext * track, GstFlowReturn ret)
298 /* store the value */
299 track->last_flow = ret;
301 /* any other error that is not-linked can be returned right away */
302 if (ret != GST_FLOW_NOT_LINKED)
305 /* only return NOT_LINKED if all other pads returned NOT_LINKED */
306 g_assert (demux->src->len == demux->num_streams);
307 for (i = 0; i < demux->src->len; i++) {
308 GstMatroskaTrackContext *ostream = g_ptr_array_index (demux->src, i);
313 ret = ostream->last_flow;
314 /* some other return value (must be SUCCESS but we can return
315 * other values as well) */
316 if (ret != GST_FLOW_NOT_LINKED)
319 /* if we get here, all other pads were unlinked and we return
322 GST_LOG_OBJECT (demux, "combined return %s", gst_flow_get_name (ret));
327 gst_matroska_demux_reset (GstElement * element)
329 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
332 GST_DEBUG_OBJECT (demux, "Resetting state");
335 demux->state = GST_MATROSKA_DEMUX_STATE_START;
337 /* clean up existing streams */
339 g_assert (demux->src->len == demux->num_streams);
340 for (i = 0; i < demux->src->len; i++) {
341 GstMatroskaTrackContext *context = g_ptr_array_index (demux->src, i);
343 if (context->pad != NULL)
344 gst_element_remove_pad (GST_ELEMENT (demux), context->pad);
346 gst_caps_replace (&context->caps, NULL);
347 gst_matroska_track_free (context);
349 g_ptr_array_free (demux->src, TRUE);
351 demux->src = g_ptr_array_new ();
353 demux->num_streams = 0;
354 demux->num_a_streams = 0;
355 demux->num_t_streams = 0;
356 demux->num_v_streams = 0;
358 /* reset media info */
359 g_free (demux->writing_app);
360 demux->writing_app = NULL;
361 g_free (demux->muxing_app);
362 demux->muxing_app = NULL;
366 g_array_free (demux->index, TRUE);
372 demux->time_scale = 1000000;
373 demux->created = G_MININT64;
375 demux->index_parsed = FALSE;
376 demux->tracks_parsed = FALSE;
377 demux->segmentinfo_parsed = FALSE;
378 demux->attachments_parsed = FALSE;
380 g_list_foreach (demux->tags_parsed, (GFunc) gst_ebml_level_free, NULL);
381 g_list_free (demux->tags_parsed);
382 demux->tags_parsed = NULL;
384 gst_segment_init (&demux->segment, GST_FORMAT_TIME);
385 demux->duration = -1;
387 if (demux->close_segment) {
388 gst_event_unref (demux->close_segment);
389 demux->close_segment = NULL;
392 if (demux->new_segment) {
393 gst_event_unref (demux->new_segment);
394 demux->new_segment = NULL;
397 if (demux->element_index) {
398 gst_object_unref (demux->element_index);
399 demux->element_index = NULL;
401 demux->element_index_writer_id = -1;
405 gst_matroska_demux_stream_from_num (GstMatroskaDemux * demux, guint track_num)
409 g_assert (demux->src->len == demux->num_streams);
410 for (n = 0; n < demux->src->len; n++) {
411 GstMatroskaTrackContext *context = g_ptr_array_index (demux->src, n);
413 if (context->num == track_num) {
418 if (n == demux->num_streams)
419 GST_WARNING_OBJECT (demux,
420 "Failed to find corresponding pad for tracknum %d", track_num);
426 gst_matroska_demux_encoding_cmp (GstMatroskaTrackEncoding * a,
427 GstMatroskaTrackEncoding * b)
429 if (b->order > a->order)
431 else if (b->order < a->order)
438 gst_matroska_demux_encoding_order_unique (GArray * encodings, guint64 order)
442 if (encodings == NULL || encodings->len == 0)
445 for (i = 0; i < encodings->len; i++)
446 if (g_array_index (encodings, GstMatroskaTrackEncoding, i).order == order)
453 gst_matroska_demux_read_track_encoding (GstMatroskaDemux * demux,
454 GstMatroskaTrackContext * context)
456 GstMatroskaTrackEncoding enc = { 0, };
457 GstEbmlRead *ebml = GST_EBML_READ (demux);
461 DEBUG_ELEMENT_START (demux, ebml, "ContentEncoding");
462 /* Set default values */
464 /* All other default values are 0 */
466 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
467 DEBUG_ELEMENT_STOP (demux, ebml, "ContentEncoding", ret);
471 while (ret == GST_FLOW_OK) {
472 if ((ret = gst_ebml_peek_id (ebml, &demux->level_up, &id)) != GST_FLOW_OK)
475 if (demux->level_up) {
481 case GST_MATROSKA_ID_CONTENTENCODINGORDER:{
484 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
487 if (!gst_matroska_demux_encoding_order_unique (context->encodings, num)) {
488 GST_ERROR_OBJECT (demux, "ContentEncodingOrder %" G_GUINT64_FORMAT
489 "is not unique for track %d", num, context->num);
490 ret = GST_FLOW_ERROR;
494 GST_DEBUG_OBJECT (demux, "ContentEncodingOrder: %" G_GUINT64_FORMAT,
499 case GST_MATROSKA_ID_CONTENTENCODINGSCOPE:{
502 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
505 if (num > 7 && num == 0) {
506 GST_ERROR_OBJECT (demux, "Invalid ContentEncodingScope %"
507 G_GUINT64_FORMAT, num);
508 ret = GST_FLOW_ERROR;
512 GST_DEBUG_OBJECT (demux, "ContentEncodingScope: %" G_GUINT64_FORMAT,
518 case GST_MATROSKA_ID_CONTENTENCODINGTYPE:{
521 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
525 GST_ERROR_OBJECT (demux, "Invalid ContentEncodingType %"
526 G_GUINT64_FORMAT, num);
527 ret = GST_FLOW_ERROR;
529 } else if (num != 0) {
530 GST_ERROR_OBJECT (demux, "Encrypted tracks are not supported yet");
531 ret = GST_FLOW_ERROR;
534 GST_DEBUG_OBJECT (demux, "ContentEncodingType: %" G_GUINT64_FORMAT,
539 case GST_MATROSKA_ID_CONTENTCOMPRESSION:{
541 DEBUG_ELEMENT_START (demux, ebml, "ContentCompression");
543 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
546 while (ret == GST_FLOW_OK) {
547 if ((ret = gst_ebml_peek_id (ebml, &demux->level_up,
548 &id)) != GST_FLOW_OK)
551 if (demux->level_up) {
557 case GST_MATROSKA_ID_CONTENTCOMPALGO:{
560 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK) {
564 GST_ERROR_OBJECT (demux, "Invalid ContentCompAlgo %"
565 G_GUINT64_FORMAT, num);
566 ret = GST_FLOW_ERROR;
569 GST_DEBUG_OBJECT (demux, "ContentCompAlgo: %" G_GUINT64_FORMAT,
575 case GST_MATROSKA_ID_CONTENTCOMPSETTINGS:{
580 gst_ebml_read_binary (ebml, &id, &data,
581 &size)) != GST_FLOW_OK) {
584 enc.comp_settings = data;
585 enc.comp_settings_length = size;
586 GST_DEBUG_OBJECT (demux,
587 "ContentCompSettings of size %" G_GUINT64_FORMAT, size);
591 GST_WARNING_OBJECT (demux,
592 "Unknown ContentCompression subelement 0x%x - ignoring", id);
593 ret = gst_ebml_read_skip (ebml);
597 if (demux->level_up) {
602 DEBUG_ELEMENT_STOP (demux, ebml, "ContentCompression", ret);
606 case GST_MATROSKA_ID_CONTENTENCRYPTION:
607 GST_ERROR_OBJECT (demux, "Encrypted tracks not yet supported");
608 gst_ebml_read_skip (ebml);
609 ret = GST_FLOW_ERROR;
612 GST_WARNING_OBJECT (demux,
613 "Unknown ContentEncoding subelement 0x%x - ignoring", id);
614 ret = gst_ebml_read_skip (ebml);
618 if (demux->level_up) {
624 DEBUG_ELEMENT_STOP (demux, ebml, "ContentEncoding", ret);
625 if (ret != GST_FLOW_OK && ret != GST_FLOW_UNEXPECTED)
628 /* TODO: Check if the combination of values is valid */
630 g_array_append_val (context->encodings, enc);
636 gst_matroska_decompress_data (GstMatroskaTrackEncoding * enc,
637 guint8 ** data_out, guint * size_out,
638 GstMatroskaTrackCompressionAlgorithm algo)
640 guint8 *new_data = NULL;
643 guint8 *data = *data_out;
644 guint size = *size_out;
648 if (algo == GST_MATROSKA_TRACK_COMPRESSION_ALGORITHM_ZLIB) {
650 /* zlib encoded data */
656 zstream.zalloc = (alloc_func) 0;
657 zstream.zfree = (free_func) 0;
658 zstream.opaque = (voidpf) 0;
659 if (inflateInit (&zstream) != Z_OK) {
660 GST_WARNING ("zlib initialization failed.");
664 zstream.next_in = (Bytef *) data;
665 zstream.avail_in = orig_size;
666 new_size = orig_size;
667 new_data = g_malloc (new_size);
668 zstream.avail_out = new_size;
669 zstream.next_out = (Bytef *) new_data;
672 result = inflate (&zstream, Z_NO_FLUSH);
673 if (result != Z_OK && result != Z_STREAM_END) {
674 GST_WARNING ("zlib decompression failed.");
676 inflateEnd (&zstream);
680 new_data = g_realloc (new_data, new_size);
681 zstream.next_out = (Bytef *) (new_data + zstream.total_out);
682 zstream.avail_out += 4000;
683 } while (zstream.avail_in != 0 && result != Z_STREAM_END);
685 if (result != Z_STREAM_END) {
689 new_size = zstream.total_out;
690 inflateEnd (&zstream);
693 GST_WARNING ("zlib encoded tracks not supported.");
697 } else if (algo == GST_MATROSKA_TRACK_COMPRESSION_ALGORITHM_BZLIB) {
699 /* bzip2 encoded data */
704 bzstream.bzalloc = NULL;
705 bzstream.bzfree = NULL;
706 bzstream.opaque = NULL;
709 if ((result = BZ2_bzDecompressInit (&bzstream, 0, 0)) != BZ_OK) {
710 GST_WARNING ("bzip2 initialization failed.");
715 bzstream.next_in = (char *) data;
716 bzstream.avail_in = orig_size;
717 new_size = orig_size;
718 new_data = g_malloc (new_size);
719 bzstream.avail_out = new_size;
720 bzstream.next_out = (char *) new_data;
723 result = BZ2_bzDecompress (&bzstream);
724 if (result != BZ_OK && result != BZ_STREAM_END) {
725 GST_WARNING ("bzip2 decompression failed.");
727 BZ2_bzDecompressEnd (&bzstream);
731 new_data = g_realloc (new_data, new_size);
732 bzstream.next_out = (char *) (new_data + bzstream.total_out_lo32);
733 bzstream.avail_out += 4000;
734 } while (bzstream.avail_in != 0 && result != BZ_STREAM_END);
736 if (result != BZ_STREAM_END) {
740 new_size = bzstream.total_out_lo32;
741 BZ2_bzDecompressEnd (&bzstream);
744 GST_WARNING ("bzip2 encoded tracks not supported.");
748 } else if (algo == GST_MATROSKA_TRACK_COMPRESSION_ALGORITHM_LZO1X) {
749 /* lzo encoded data */
751 int orig_size, out_size;
756 new_data = g_malloc (new_size);
762 result = lzo1x_decode (new_data, &out_size, data, &orig_size);
766 new_data = g_realloc (new_data, new_size);
768 } while (orig_size > 0 && result == LZO_OUTPUT_FULL);
770 new_size -= out_size;
772 if (result != LZO_OUTPUT_FULL) {
773 GST_WARNING ("lzo decompression failed");
780 } else if (algo == GST_MATROSKA_TRACK_COMPRESSION_ALGORITHM_HEADERSTRIP) {
781 /* header stripped encoded data */
782 if (enc->comp_settings_length > 0) {
783 new_data = g_malloc (size + enc->comp_settings_length);
784 new_size = size + enc->comp_settings_length;
786 memcpy (new_data, enc->comp_settings, enc->comp_settings_length);
787 memcpy (new_data + enc->comp_settings_length, data, size);
790 g_assert_not_reached ();
799 *data_out = new_data;
800 *size_out = new_size;
807 gst_matroska_decode_data (GArray * encodings, guint8 ** data_out,
808 guint * size_out, GstMatroskaTrackEncodingScope scope, gboolean free)
815 g_return_val_if_fail (encodings != NULL, FALSE);
816 g_return_val_if_fail (data_out != NULL && *data_out != NULL, FALSE);
817 g_return_val_if_fail (size_out != NULL, FALSE);
822 for (i = 0; i < encodings->len; i++) {
823 GstMatroskaTrackEncoding *enc =
824 &g_array_index (encodings, GstMatroskaTrackEncoding, i);
825 guint8 *new_data = NULL;
828 if ((enc->scope & scope) == 0)
831 /* Encryption not supported yet */
832 if (enc->type != 0) {
841 gst_matroska_decompress_data (enc, &new_data, &new_size,
847 if ((data == *data_out && free) || (data != *data_out))
855 if ((data == *data_out && free) || (data != *data_out))
869 gst_matroska_decode_buffer (GstMatroskaTrackContext * context, GstBuffer * buf)
875 g_return_val_if_fail (GST_IS_BUFFER (buf), NULL);
877 GST_DEBUG ("decoding buffer %p", buf);
879 data = GST_BUFFER_DATA (buf);
880 size = GST_BUFFER_SIZE (buf);
882 g_return_val_if_fail (data != NULL && size > 0, buf);
884 if (gst_matroska_decode_data (context->encodings, &data, &size,
885 GST_MATROSKA_TRACK_ENCODING_SCOPE_FRAME, FALSE)) {
886 new_buf = gst_buffer_new ();
887 GST_BUFFER_MALLOCDATA (new_buf) = (guint8 *) data;
888 GST_BUFFER_DATA (new_buf) = (guint8 *) data;
889 GST_BUFFER_SIZE (new_buf) = size;
891 gst_buffer_unref (buf);
896 GST_DEBUG ("decode data failed");
897 gst_buffer_unref (buf);
903 gst_matroska_decode_content_encodings (GArray * encodings)
907 if (encodings == NULL)
910 for (i = 0; i < encodings->len; i++) {
911 GstMatroskaTrackEncoding *enc =
912 &g_array_index (encodings, GstMatroskaTrackEncoding, i);
913 GstMatroskaTrackEncoding *enc2;
917 if ((enc->scope & GST_MATROSKA_TRACK_ENCODING_SCOPE_NEXT_CONTENT_ENCODING)
921 /* Encryption not supported yet */
923 return GST_FLOW_ERROR;
925 if (i + 1 >= encodings->len)
926 return GST_FLOW_ERROR;
928 enc2 = &g_array_index (encodings, GstMatroskaTrackEncoding, i + 1);
930 if (enc->comp_settings_length == 0)
933 data = enc->comp_settings;
934 size = enc->comp_settings_length;
936 if (!gst_matroska_decompress_data (enc, &data, &size, enc->comp_algo))
937 return GST_FLOW_ERROR;
939 g_free (enc->comp_settings);
941 enc->comp_settings = data;
942 enc->comp_settings_length = size;
949 gst_matroska_demux_read_track_encodings (GstMatroskaDemux * demux,
950 GstMatroskaTrackContext * context)
953 GstEbmlRead *ebml = GST_EBML_READ (demux);
956 DEBUG_ELEMENT_START (demux, ebml, "ContentEncodings");
958 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
959 DEBUG_ELEMENT_STOP (demux, ebml, "ContentEncodings", ret);
964 g_array_sized_new (FALSE, FALSE, sizeof (GstMatroskaTrackEncoding), 1);
966 while (ret == GST_FLOW_OK) {
967 if ((ret = gst_ebml_peek_id (ebml, &demux->level_up, &id)) != GST_FLOW_OK)
970 if (demux->level_up) {
976 case GST_MATROSKA_ID_CONTENTENCODING:
977 ret = gst_matroska_demux_read_track_encoding (demux, context);
980 GST_WARNING_OBJECT (demux,
981 "Unknown ContentEncodings subelement 0x%x - ignoring", id);
982 ret = gst_ebml_read_skip (ebml);
986 if (demux->level_up) {
992 DEBUG_ELEMENT_STOP (demux, ebml, "ContentEncodings", ret);
993 if (ret != GST_FLOW_OK && ret != GST_FLOW_UNEXPECTED)
996 /* Sort encodings according to their order */
997 g_array_sort (context->encodings,
998 (GCompareFunc) gst_matroska_demux_encoding_cmp);
1000 return gst_matroska_decode_content_encodings (context->encodings);
1004 gst_matroska_demux_tracknumber_unique (GstMatroskaDemux * demux, guint64 num)
1008 g_assert (demux->src->len == demux->num_streams);
1009 for (i = 0; i < demux->src->len; i++) {
1010 GstMatroskaTrackContext *context = g_ptr_array_index (demux->src, i);
1012 if (context->num == num)
1019 static GstFlowReturn
1020 gst_matroska_demux_add_stream (GstMatroskaDemux * demux)
1022 GstElementClass *klass = GST_ELEMENT_GET_CLASS (demux);
1023 GstEbmlRead *ebml = GST_EBML_READ (demux);
1024 GstMatroskaTrackContext *context;
1025 GstPadTemplate *templ = NULL;
1026 GstCaps *caps = NULL;
1027 gchar *padname = NULL;
1030 GstTagList *list = NULL;
1031 gchar *codec = NULL;
1033 DEBUG_ELEMENT_START (demux, ebml, "TrackEntry");
1035 /* start with the master */
1036 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
1037 DEBUG_ELEMENT_STOP (demux, ebml, "TrackEntry", ret);
1041 /* allocate generic... if we know the type, we'll g_renew()
1042 * with the precise type */
1043 context = g_new0 (GstMatroskaTrackContext, 1);
1044 g_ptr_array_add (demux->src, context);
1045 context->index = demux->num_streams;
1046 context->index_writer_id = -1;
1047 context->type = 0; /* no type yet */
1048 context->default_duration = 0;
1050 context->set_discont = TRUE;
1051 context->timecodescale = 1.0;
1053 GST_MATROSKA_TRACK_ENABLED | GST_MATROSKA_TRACK_DEFAULT |
1054 GST_MATROSKA_TRACK_LACING;
1055 context->last_flow = GST_FLOW_OK;
1056 demux->num_streams++;
1057 g_assert (demux->src->len == demux->num_streams);
1059 GST_DEBUG_OBJECT (demux, "Stream number %d", context->index);
1061 /* try reading the trackentry headers */
1062 while (ret == GST_FLOW_OK) {
1063 if ((ret = gst_ebml_peek_id (ebml, &demux->level_up, &id)) != GST_FLOW_OK)
1066 if (demux->level_up) {
1072 /* track number (unique stream ID) */
1073 case GST_MATROSKA_ID_TRACKNUMBER:{
1076 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1080 GST_ERROR_OBJECT (demux, "Invalid TrackNumber 0");
1081 ret = GST_FLOW_ERROR;
1083 } else if (!gst_matroska_demux_tracknumber_unique (demux, num)) {
1084 GST_ERROR_OBJECT (demux, "TrackNumber %" G_GUINT64_FORMAT
1085 " is not unique", num);
1086 ret = GST_FLOW_ERROR;
1090 GST_DEBUG_OBJECT (demux, "TrackNumber: %" G_GUINT64_FORMAT, num);
1094 /* track UID (unique identifier) */
1095 case GST_MATROSKA_ID_TRACKUID:{
1098 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1102 GST_ERROR_OBJECT (demux, "Invalid TrackUID 0");
1103 ret = GST_FLOW_ERROR;
1107 GST_DEBUG_OBJECT (demux, "TrackUID: %" G_GUINT64_FORMAT, num);
1112 /* track type (video, audio, combined, subtitle, etc.) */
1113 case GST_MATROSKA_ID_TRACKTYPE:{
1116 if ((ret = gst_ebml_read_uint (ebml, &id, &track_type)) != GST_FLOW_OK) {
1120 if (context->type != 0 && context->type != track_type) {
1121 GST_WARNING_OBJECT (demux,
1122 "More than one tracktype defined in a TrackEntry - skipping");
1124 } else if (track_type < 1 || track_type > 254) {
1125 GST_WARNING_OBJECT (demux, "Invalid TrackType %" G_GUINT64_FORMAT,
1130 GST_DEBUG_OBJECT (demux, "TrackType: %" G_GUINT64_FORMAT, track_type);
1132 /* ok, so we're actually going to reallocate this thing */
1133 switch (track_type) {
1134 case GST_MATROSKA_TRACK_TYPE_VIDEO:
1135 gst_matroska_track_init_video_context (&context);
1137 case GST_MATROSKA_TRACK_TYPE_AUDIO:
1138 gst_matroska_track_init_audio_context (&context);
1140 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
1141 gst_matroska_track_init_subtitle_context (&context);
1143 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1144 case GST_MATROSKA_TRACK_TYPE_LOGO:
1145 case GST_MATROSKA_TRACK_TYPE_BUTTONS:
1146 case GST_MATROSKA_TRACK_TYPE_CONTROL:
1148 GST_WARNING_OBJECT (demux,
1149 "Unknown or unsupported TrackType %" G_GUINT64_FORMAT,
1154 g_ptr_array_index (demux->src, demux->num_streams - 1) = context;
1158 /* tracktype specific stuff for video */
1159 case GST_MATROSKA_ID_TRACKVIDEO:{
1160 GstMatroskaTrackVideoContext *videocontext;
1162 DEBUG_ELEMENT_START (demux, ebml, "TrackVideo");
1164 if (!gst_matroska_track_init_video_context (&context)) {
1165 GST_WARNING_OBJECT (demux,
1166 "TrackVideo element in non-video track - ignoring track");
1167 ret = GST_FLOW_ERROR;
1169 } else if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
1172 videocontext = (GstMatroskaTrackVideoContext *) context;
1173 g_ptr_array_index (demux->src, demux->num_streams - 1) = context;
1175 while (ret == GST_FLOW_OK) {
1177 gst_ebml_peek_id (ebml, &demux->level_up,
1178 &id)) != GST_FLOW_OK)
1181 if (demux->level_up) {
1187 /* Should be one level up but some broken muxers write it here. */
1188 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
1191 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1195 GST_WARNING_OBJECT (demux, "Invalid TrackDefaultDuration 0");
1199 GST_DEBUG_OBJECT (demux,
1200 "TrackDefaultDuration: %" G_GUINT64_FORMAT, num);
1201 context->default_duration = num;
1205 /* video framerate */
1206 /* NOTE: This one is here only for backward compatibility.
1207 * Use _TRACKDEFAULDURATION one level up. */
1208 case GST_MATROSKA_ID_VIDEOFRAMERATE:{
1211 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
1215 GST_WARNING_OBJECT (demux, "Invalid TrackVideoFPS %lf", num);
1219 GST_DEBUG_OBJECT (demux, "TrackVideoFrameRate: %lf", num);
1220 if (context->default_duration == 0)
1221 context->default_duration =
1222 gst_gdouble_to_guint64 ((gdouble) GST_SECOND * (1.0 / num));
1223 videocontext->default_fps = num;
1227 /* width of the size to display the video at */
1228 case GST_MATROSKA_ID_VIDEODISPLAYWIDTH:{
1231 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1235 GST_WARNING_OBJECT (demux, "Invalid TrackVideoDisplayWidth 0");
1239 GST_DEBUG_OBJECT (demux,
1240 "TrackVideoDisplayWidth: %" G_GUINT64_FORMAT, num);
1241 videocontext->display_width = num;
1245 /* height of the size to display the video at */
1246 case GST_MATROSKA_ID_VIDEODISPLAYHEIGHT:{
1249 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1253 GST_WARNING_OBJECT (demux, "Invalid TrackVideoDisplayHeight 0");
1257 GST_DEBUG_OBJECT (demux,
1258 "TrackVideoDisplayHeight: %" G_GUINT64_FORMAT, num);
1259 videocontext->display_height = num;
1263 /* width of the video in the file */
1264 case GST_MATROSKA_ID_VIDEOPIXELWIDTH:{
1267 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1271 GST_WARNING_OBJECT (demux, "Invalid TrackVideoPixelWidth 0");
1275 GST_DEBUG_OBJECT (demux,
1276 "TrackVideoPixelWidth: %" G_GUINT64_FORMAT, num);
1277 videocontext->pixel_width = num;
1281 /* height of the video in the file */
1282 case GST_MATROSKA_ID_VIDEOPIXELHEIGHT:{
1285 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1289 GST_WARNING_OBJECT (demux, "Invalid TrackVideoPixelHeight 0");
1293 GST_DEBUG_OBJECT (demux,
1294 "TrackVideoPixelHeight: %" G_GUINT64_FORMAT, num);
1295 videocontext->pixel_height = num;
1299 /* whether the video is interlaced */
1300 case GST_MATROSKA_ID_VIDEOFLAGINTERLACED:{
1303 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1307 context->flags |= GST_MATROSKA_VIDEOTRACK_INTERLACED;
1309 context->flags &= ~GST_MATROSKA_VIDEOTRACK_INTERLACED;
1310 GST_DEBUG_OBJECT (demux, "TrackVideoInterlaced: %d",
1311 (context->flags & GST_MATROSKA_VIDEOTRACK_INTERLACED) ? 1 :
1316 /* aspect ratio behaviour */
1317 case GST_MATROSKA_ID_VIDEOASPECTRATIOTYPE:{
1320 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1323 if (num != GST_MATROSKA_ASPECT_RATIO_MODE_FREE &&
1324 num != GST_MATROSKA_ASPECT_RATIO_MODE_KEEP &&
1325 num != GST_MATROSKA_ASPECT_RATIO_MODE_FIXED) {
1326 GST_WARNING_OBJECT (demux,
1327 "Unknown TrackVideoAspectRatioType 0x%x", (guint) num);
1330 GST_DEBUG_OBJECT (demux,
1331 "TrackVideoAspectRatioType: %" G_GUINT64_FORMAT, num);
1332 videocontext->asr_mode = num;
1336 /* colourspace (only matters for raw video) fourcc */
1337 case GST_MATROSKA_ID_VIDEOCOLOURSPACE:{
1342 gst_ebml_read_binary (ebml, &id, &data,
1343 &datalen)) != GST_FLOW_OK)
1348 GST_WARNING_OBJECT (demux,
1349 "Invalid TrackVideoColourSpace length %" G_GUINT64_FORMAT,
1354 memcpy (&videocontext->fourcc, data, 4);
1355 GST_DEBUG_OBJECT (demux,
1356 "TrackVideoColourSpace: %" GST_FOURCC_FORMAT,
1357 GST_FOURCC_ARGS (videocontext->fourcc));
1363 GST_WARNING_OBJECT (demux,
1364 "Unknown TrackVideo subelement 0x%x - ignoring", id);
1366 case GST_MATROSKA_ID_VIDEOSTEREOMODE:
1367 case GST_MATROSKA_ID_VIDEODISPLAYUNIT:
1368 case GST_MATROSKA_ID_VIDEOPIXELCROPBOTTOM:
1369 case GST_MATROSKA_ID_VIDEOPIXELCROPTOP:
1370 case GST_MATROSKA_ID_VIDEOPIXELCROPLEFT:
1371 case GST_MATROSKA_ID_VIDEOPIXELCROPRIGHT:
1372 case GST_MATROSKA_ID_VIDEOGAMMAVALUE:
1373 ret = gst_ebml_read_skip (ebml);
1377 if (demux->level_up) {
1383 DEBUG_ELEMENT_STOP (demux, ebml, "TrackVideo", ret);
1387 /* tracktype specific stuff for audio */
1388 case GST_MATROSKA_ID_TRACKAUDIO:{
1389 GstMatroskaTrackAudioContext *audiocontext;
1391 DEBUG_ELEMENT_START (demux, ebml, "TrackAudio");
1393 if (!gst_matroska_track_init_audio_context (&context)) {
1394 GST_WARNING_OBJECT (demux,
1395 "TrackAudio element in non-audio track - ignoring track");
1396 ret = GST_FLOW_ERROR;
1400 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
1403 audiocontext = (GstMatroskaTrackAudioContext *) context;
1404 g_ptr_array_index (demux->src, demux->num_streams - 1) = context;
1406 while (ret == GST_FLOW_OK) {
1408 gst_ebml_peek_id (ebml, &demux->level_up,
1409 &id)) != GST_FLOW_OK)
1412 if (demux->level_up) {
1419 case GST_MATROSKA_ID_AUDIOSAMPLINGFREQ:{
1422 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
1427 GST_WARNING_OBJECT (demux,
1428 "Invalid TrackAudioSamplingFrequency %lf", num);
1432 GST_DEBUG_OBJECT (demux, "TrackAudioSamplingFrequency: %lf", num);
1433 audiocontext->samplerate = num;
1438 case GST_MATROSKA_ID_AUDIOBITDEPTH:{
1441 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1445 GST_WARNING_OBJECT (demux, "Invalid TrackAudioBitDepth 0");
1449 GST_DEBUG_OBJECT (demux, "TrackAudioBitDepth: %" G_GUINT64_FORMAT,
1451 audiocontext->bitdepth = num;
1456 case GST_MATROSKA_ID_AUDIOCHANNELS:{
1459 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1463 GST_WARNING_OBJECT (demux, "Invalid TrackAudioChannels 0");
1467 GST_DEBUG_OBJECT (demux, "TrackAudioChannels: %" G_GUINT64_FORMAT,
1469 audiocontext->channels = num;
1474 GST_WARNING_OBJECT (demux,
1475 "Unknown TrackAudio subelement 0x%x - ignoring", id);
1477 case GST_MATROSKA_ID_AUDIOCHANNELPOSITIONS:
1478 case GST_MATROSKA_ID_AUDIOOUTPUTSAMPLINGFREQ:
1479 ret = gst_ebml_read_skip (ebml);
1483 if (demux->level_up) {
1489 DEBUG_ELEMENT_STOP (demux, ebml, "TrackAudio", ret);
1494 /* codec identifier */
1495 case GST_MATROSKA_ID_CODECID:{
1498 if ((ret = gst_ebml_read_ascii (ebml, &id, &text)) != GST_FLOW_OK)
1501 GST_DEBUG_OBJECT (demux, "CodecID: %s", GST_STR_NULL (text));
1502 context->codec_id = text;
1506 /* codec private data */
1507 case GST_MATROSKA_ID_CODECPRIVATE:{
1512 gst_ebml_read_binary (ebml, &id, &data, &size)) != GST_FLOW_OK)
1515 context->codec_priv = data;
1516 context->codec_priv_size = size;
1518 GST_DEBUG_OBJECT (demux, "CodecPrivate of size %" G_GUINT64_FORMAT,
1523 /* name of the codec */
1524 case GST_MATROSKA_ID_CODECNAME:{
1527 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1530 GST_DEBUG_OBJECT (demux, "CodecName: %s", GST_STR_NULL (text));
1531 context->codec_name = text;
1535 /* name of this track */
1536 case GST_MATROSKA_ID_TRACKNAME:{
1539 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1542 context->name = text;
1543 GST_DEBUG_OBJECT (demux, "TrackName: %s", GST_STR_NULL (text));
1547 /* language (matters for audio/subtitles, mostly) */
1548 case GST_MATROSKA_ID_TRACKLANGUAGE:{
1551 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1555 context->language = text;
1558 if (strlen (context->language) >= 4 && context->language[3] == '-')
1559 context->language[3] = '\0';
1561 GST_DEBUG_OBJECT (demux, "TrackLanguage: %s",
1562 GST_STR_NULL (context->language));
1566 /* whether this is actually used */
1567 case GST_MATROSKA_ID_TRACKFLAGENABLED:{
1570 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1574 context->flags |= GST_MATROSKA_TRACK_ENABLED;
1576 context->flags &= ~GST_MATROSKA_TRACK_ENABLED;
1578 GST_DEBUG_OBJECT (demux, "TrackEnabled: %d",
1579 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
1583 /* whether it's the default for this track type */
1584 case GST_MATROSKA_ID_TRACKFLAGDEFAULT:{
1587 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1591 context->flags |= GST_MATROSKA_TRACK_DEFAULT;
1593 context->flags &= ~GST_MATROSKA_TRACK_DEFAULT;
1595 GST_DEBUG_OBJECT (demux, "TrackDefault: %d",
1596 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
1600 /* whether the track must be used during playback */
1601 case GST_MATROSKA_ID_TRACKFLAGFORCED:{
1604 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1608 context->flags |= GST_MATROSKA_TRACK_FORCED;
1610 context->flags &= ~GST_MATROSKA_TRACK_FORCED;
1612 GST_DEBUG_OBJECT (demux, "TrackForced: %d",
1613 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
1617 /* lacing (like MPEG, where blocks don't end/start on frame
1619 case GST_MATROSKA_ID_TRACKFLAGLACING:{
1622 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1626 context->flags |= GST_MATROSKA_TRACK_LACING;
1628 context->flags &= ~GST_MATROSKA_TRACK_LACING;
1630 GST_DEBUG_OBJECT (demux, "TrackLacing: %d",
1631 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
1635 /* default length (in time) of one data block in this track */
1636 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
1639 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1644 GST_WARNING_OBJECT (demux, "Invalid TrackDefaultDuration 0");
1648 GST_DEBUG_OBJECT (demux, "TrackDefaultDuration: %" G_GUINT64_FORMAT,
1650 context->default_duration = num;
1654 case GST_MATROSKA_ID_CONTENTENCODINGS:{
1655 ret = gst_matroska_demux_read_track_encodings (demux, context);
1659 case GST_MATROSKA_ID_TRACKTIMECODESCALE:{
1662 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
1666 GST_WARNING_OBJECT (demux, "Invalid TrackTimeCodeScale %lf", num);
1670 GST_DEBUG_OBJECT (demux, "TrackTimeCodeScale: %lf", num);
1671 context->timecodescale = num;
1676 GST_WARNING ("Unknown TrackEntry subelement 0x%x - ignoring", id);
1679 /* we ignore these because they're nothing useful (i.e. crap)
1680 * or simply not implemented yet. */
1681 case GST_MATROSKA_ID_TRACKMINCACHE:
1682 case GST_MATROSKA_ID_TRACKMAXCACHE:
1683 case GST_MATROSKA_ID_MAXBLOCKADDITIONID:
1684 case GST_MATROSKA_ID_TRACKATTACHMENTLINK:
1685 case GST_MATROSKA_ID_TRACKOVERLAY:
1686 case GST_MATROSKA_ID_TRACKTRANSLATE:
1687 case GST_MATROSKA_ID_TRACKOFFSET:
1688 case GST_MATROSKA_ID_CODECSETTINGS:
1689 case GST_MATROSKA_ID_CODECINFOURL:
1690 case GST_MATROSKA_ID_CODECDOWNLOADURL:
1691 case GST_MATROSKA_ID_CODECDECODEALL:
1692 ret = gst_ebml_read_skip (ebml);
1696 if (demux->level_up) {
1702 DEBUG_ELEMENT_STOP (demux, ebml, "TrackEntry", ret);
1704 /* Decode codec private data if necessary */
1705 if (context->encodings && context->encodings->len > 0 && context->codec_priv
1706 && context->codec_priv_size > 0) {
1707 if (!gst_matroska_decode_data (context->encodings,
1708 &context->codec_priv, &context->codec_priv_size,
1709 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
1710 GST_WARNING_OBJECT (demux, "Decoding codec private data failed");
1711 ret = GST_FLOW_ERROR;
1715 if (context->type == 0 || context->codec_id == NULL || (ret != GST_FLOW_OK
1716 && ret != GST_FLOW_UNEXPECTED)) {
1717 if (ret == GST_FLOW_OK || ret == GST_FLOW_UNEXPECTED)
1718 GST_WARNING_OBJECT (ebml, "Unknown stream/codec in track entry header");
1720 demux->num_streams--;
1721 g_ptr_array_remove_index (demux->src, demux->num_streams);
1722 g_assert (demux->src->len == demux->num_streams);
1724 gst_matroska_track_free (context);
1730 /* now create the GStreamer connectivity */
1731 switch (context->type) {
1732 case GST_MATROSKA_TRACK_TYPE_VIDEO:{
1733 GstMatroskaTrackVideoContext *videocontext =
1734 (GstMatroskaTrackVideoContext *) context;
1736 padname = g_strdup_printf ("video_%02d", demux->num_v_streams++);
1737 templ = gst_element_class_get_pad_template (klass, "video_%02d");
1738 caps = gst_matroska_demux_video_caps (videocontext,
1740 (guint8 *) context->codec_priv, context->codec_priv_size, &codec);
1742 list = gst_tag_list_new ();
1743 gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
1744 GST_TAG_VIDEO_CODEC, codec, NULL);
1750 case GST_MATROSKA_TRACK_TYPE_AUDIO:{
1751 GstMatroskaTrackAudioContext *audiocontext =
1752 (GstMatroskaTrackAudioContext *) context;
1754 padname = g_strdup_printf ("audio_%02d", demux->num_a_streams++);
1755 templ = gst_element_class_get_pad_template (klass, "audio_%02d");
1756 caps = gst_matroska_demux_audio_caps (audiocontext,
1758 context->codec_priv, context->codec_priv_size, &codec);
1760 list = gst_tag_list_new ();
1761 gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
1762 GST_TAG_AUDIO_CODEC, codec, NULL);
1768 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:{
1769 GstMatroskaTrackSubtitleContext *subtitlecontext =
1770 (GstMatroskaTrackSubtitleContext *) context;
1772 padname = g_strdup_printf ("subtitle_%02d", demux->num_t_streams++);
1773 templ = gst_element_class_get_pad_template (klass, "subtitle_%02d");
1774 caps = gst_matroska_demux_subtitle_caps (subtitlecontext,
1775 context->codec_id, context->codec_priv, context->codec_priv_size);
1779 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1780 case GST_MATROSKA_TRACK_TYPE_LOGO:
1781 case GST_MATROSKA_TRACK_TYPE_BUTTONS:
1782 case GST_MATROSKA_TRACK_TYPE_CONTROL:
1784 /* we should already have quit by now */
1785 g_assert_not_reached ();
1788 if ((context->language == NULL || *context->language == '\0') &&
1789 (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO ||
1790 context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
1791 GST_LOG ("stream %d: language=eng (assuming default)", context->index);
1792 context->language = g_strdup ("eng");
1795 if (context->language) {
1797 list = gst_tag_list_new ();
1798 gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
1799 GST_TAG_LANGUAGE_CODE, context->language, NULL);
1803 GST_WARNING_OBJECT (demux, "could not determine caps for stream with "
1804 "codec_id='%s'", context->codec_id);
1805 switch (context->type) {
1806 case GST_MATROSKA_TRACK_TYPE_VIDEO:
1807 caps = gst_caps_new_simple ("video/x-unknown", NULL);
1809 case GST_MATROSKA_TRACK_TYPE_AUDIO:
1810 caps = gst_caps_new_simple ("audio/x-unknown", NULL);
1812 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
1813 caps = gst_caps_new_simple ("application/x-subtitle-unknown", NULL);
1815 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1817 caps = gst_caps_new_simple ("application/x-matroska-unknown", NULL);
1820 gst_caps_set_simple (caps, "codec-id", G_TYPE_STRING, context->codec_id,
1824 /* the pad in here */
1825 context->pad = gst_pad_new_from_template (templ, padname);
1826 context->caps = caps;
1828 gst_pad_set_event_function (context->pad,
1829 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_event));
1830 gst_pad_set_query_type_function (context->pad,
1831 GST_DEBUG_FUNCPTR (gst_matroska_demux_get_src_query_types));
1832 gst_pad_set_query_function (context->pad,
1833 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_query));
1835 GST_INFO_OBJECT (demux, "Adding pad '%s' with caps %" GST_PTR_FORMAT,
1838 context->pending_tags = list;
1840 gst_pad_set_element_private (context->pad, context);
1842 gst_pad_use_fixed_caps (context->pad);
1843 gst_pad_set_caps (context->pad, context->caps);
1844 gst_pad_set_active (context->pad, TRUE);
1845 gst_element_add_pad (GST_ELEMENT (demux), context->pad);
1853 static const GstQueryType *
1854 gst_matroska_demux_get_src_query_types (GstPad * pad)
1856 static const GstQueryType query_types[] = {
1867 gst_matroska_demux_query (GstMatroskaDemux * demux, GstPad * pad,
1870 gboolean res = FALSE;
1871 GstMatroskaTrackContext *context = NULL;
1874 context = gst_pad_get_element_private (pad);
1877 switch (GST_QUERY_TYPE (query)) {
1878 case GST_QUERY_POSITION:
1882 gst_query_parse_position (query, &format, NULL);
1884 if (format == GST_FORMAT_TIME) {
1885 GST_OBJECT_LOCK (demux);
1887 gst_query_set_position (query, GST_FORMAT_TIME, context->pos);
1889 gst_query_set_position (query, GST_FORMAT_TIME,
1890 demux->segment.last_stop);
1891 GST_OBJECT_UNLOCK (demux);
1892 } else if (format == GST_FORMAT_DEFAULT && context
1893 && context->default_duration) {
1894 GST_OBJECT_LOCK (demux);
1895 gst_query_set_position (query, GST_FORMAT_DEFAULT,
1896 context->pos / context->default_duration);
1897 GST_OBJECT_UNLOCK (demux);
1899 GST_DEBUG_OBJECT (demux,
1900 "only position query in TIME and DEFAULT format is supported");
1906 case GST_QUERY_DURATION:
1910 gst_query_parse_duration (query, &format, NULL);
1912 if (format == GST_FORMAT_TIME) {
1913 GST_OBJECT_LOCK (demux);
1914 gst_query_set_duration (query, GST_FORMAT_TIME, demux->duration);
1915 GST_OBJECT_UNLOCK (demux);
1916 } else if (format == GST_FORMAT_DEFAULT && context
1917 && context->default_duration) {
1918 GST_OBJECT_LOCK (demux);
1919 gst_query_set_duration (query, GST_FORMAT_DEFAULT,
1920 demux->duration / context->default_duration);
1921 GST_OBJECT_UNLOCK (demux);
1923 GST_DEBUG_OBJECT (demux,
1924 "only duration query in TIME and DEFAULT format is supported");
1931 case GST_QUERY_SEEKING:{
1935 gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
1937 if (fmt != GST_FORMAT_TIME || !demux->index) {
1938 gst_query_set_seeking (query, fmt, FALSE, -1, -1);
1940 gst_query_set_seeking (query, GST_FORMAT_TIME, TRUE, 0,
1947 res = gst_pad_query_default (pad, query);
1955 gst_matroska_demux_element_query (GstElement * element, GstQuery * query)
1957 return gst_matroska_demux_query (GST_MATROSKA_DEMUX (element), NULL, query);
1961 gst_matroska_demux_handle_src_query (GstPad * pad, GstQuery * query)
1964 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (gst_pad_get_parent (pad));
1966 ret = gst_matroska_demux_query (demux, pad, query);
1968 gst_object_unref (demux);
1974 gst_matroska_index_seek_find (GstMatroskaIndex * i1, GstClockTime * time,
1977 if (i1->time < *time)
1979 else if (i1->time > *time)
1985 static GstMatroskaIndex *
1986 gst_matroskademux_do_index_seek (GstMatroskaDemux * demux,
1987 GstMatroskaTrackContext * track, gint64 seek_pos, gint64 segment_stop,
1990 GstMatroskaIndex *entry = NULL;
1993 if (!demux->index || !demux->index->len)
1996 /* find entry just before or at the requested position */
1997 if (track && track->index_table)
1998 index = track->index_table;
2000 index = demux->index;
2003 gst_util_array_binary_search (index->data, index->len,
2004 sizeof (GstMatroskaIndex),
2005 (GCompareDataFunc) gst_matroska_index_seek_find, GST_SEARCH_MODE_BEFORE,
2009 entry = &g_array_index (index, GstMatroskaIndex, 0);
2014 /* takes ownership of the passed event! */
2016 gst_matroska_demux_send_event (GstMatroskaDemux * demux, GstEvent * event)
2018 gboolean ret = TRUE;
2021 g_return_val_if_fail (event != NULL, FALSE);
2023 GST_DEBUG_OBJECT (demux, "Sending event of type %s to all source pads",
2024 GST_EVENT_TYPE_NAME (event));
2026 g_assert (demux->src->len == demux->num_streams);
2027 for (i = 0; i < demux->src->len; i++) {
2028 GstMatroskaTrackContext *stream;
2030 stream = g_ptr_array_index (demux->src, i);
2031 gst_event_ref (event);
2032 gst_pad_push_event (stream->pad, event);
2034 if (stream->pending_tags) {
2035 GST_DEBUG_OBJECT (demux, "Sending pending_tags %p for pad %s:%s",
2036 stream->pending_tags, GST_DEBUG_PAD_NAME (stream->pad));
2037 gst_element_found_tags_for_pad (GST_ELEMENT (demux), stream->pad,
2038 stream->pending_tags);
2039 stream->pending_tags = NULL;
2042 gst_event_unref (event);
2047 gst_matroska_demux_element_send_event (GstElement * element, GstEvent * event)
2049 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
2052 g_return_val_if_fail (event != NULL, FALSE);
2054 if (GST_EVENT_TYPE (event) == GST_EVENT_SEEK) {
2055 res = gst_matroska_demux_handle_seek_event (demux, NULL, event);
2057 GST_WARNING_OBJECT (demux, "Unhandled event of type %s",
2058 GST_EVENT_TYPE_NAME (event));
2061 gst_event_unref (event);
2066 gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
2067 GstPad * pad, GstEvent * event)
2069 GstMatroskaIndex *entry = NULL;
2071 GstSeekType cur_type, stop_type;
2073 gboolean flush, keyunit;
2076 gint64 segment_start, segment_stop;
2078 GstMatroskaTrackContext *track = NULL;
2081 track = gst_pad_get_element_private (pad);
2083 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
2086 /* we can only seek on time */
2087 if (format != GST_FORMAT_TIME) {
2088 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
2092 /* cannot yet do backwards playback */
2094 GST_DEBUG_OBJECT (demux, "Can only seek with positive rate");
2098 /* check sanity before we start flushing and all that */
2099 if (cur_type == GST_SEEK_TYPE_SET) {
2100 GST_OBJECT_LOCK (demux);
2102 gst_matroskademux_do_index_seek (demux, track, cur, -1,
2104 GST_DEBUG_OBJECT (demux, "No matching seek entry in index");
2105 GST_OBJECT_UNLOCK (demux);
2108 GST_DEBUG_OBJECT (demux, "Seek position looks sane");
2109 GST_OBJECT_UNLOCK (demux);
2112 flush = !!(flags & GST_SEEK_FLAG_FLUSH);
2113 keyunit = !!(flags & GST_SEEK_FLAG_KEY_UNIT);
2116 GST_DEBUG_OBJECT (demux, "Starting flush");
2117 gst_pad_push_event (demux->sinkpad, gst_event_new_flush_start ());
2118 gst_matroska_demux_send_event (demux, gst_event_new_flush_start ());
2120 gst_pad_pause_task (demux->sinkpad);
2123 /* now grab the stream lock so that streaming cannot continue, for
2124 * non flushing seeks when the element is in PAUSED this could block
2126 GST_PAD_STREAM_LOCK (demux->sinkpad);
2128 GST_OBJECT_LOCK (demux);
2130 /* if nothing configured, play complete file */
2131 if (!GST_CLOCK_TIME_IS_VALID (cur))
2133 /* prevent some calculations and comparisons involving INVALID */
2134 segment_start = demux->segment.start;
2135 segment_stop = demux->segment.stop;
2136 if (!GST_CLOCK_TIME_IS_VALID (segment_start))
2139 if (cur_type == GST_SEEK_TYPE_SET)
2140 segment_start = cur;
2141 else if (cur_type == GST_SEEK_TYPE_CUR)
2142 segment_start += cur;
2144 if (stop_type == GST_SEEK_TYPE_SET) {
2145 segment_stop = stop;
2146 } else if (stop_type == GST_SEEK_TYPE_CUR) {
2147 if (GST_CLOCK_TIME_IS_VALID (segment_stop)
2148 && GST_CLOCK_TIME_IS_VALID (stop))
2149 segment_stop += stop;
2154 GST_DEBUG_OBJECT (demux,
2155 "New segment positions: %" GST_TIME_FORMAT "-%" GST_TIME_FORMAT,
2156 GST_TIME_ARGS (segment_start), GST_TIME_ARGS (segment_stop));
2159 entry = gst_matroskademux_do_index_seek (demux, track, segment_start,
2160 segment_stop, keyunit);
2163 GST_DEBUG_OBJECT (demux, "No matching seek entry in index");
2167 /* seek (relative to matroska segment) */
2168 if (gst_ebml_read_seek (GST_EBML_READ (demux),
2169 entry->pos + demux->ebml_segment_start) != GST_FLOW_OK) {
2170 GST_DEBUG_OBJECT (demux, "Failed to seek to offset %" G_GUINT64_FORMAT,
2171 entry->pos + demux->ebml_segment_start);
2175 GST_DEBUG_OBJECT (demux, "Seeked to offset %" G_GUINT64_FORMAT, entry->pos +
2176 demux->ebml_segment_start);
2179 GST_DEBUG_OBJECT (demux, "seek to key unit, adjusting segment start to %"
2180 GST_TIME_FORMAT, GST_TIME_ARGS (entry->time));
2181 segment_start = entry->time;
2184 GST_OBJECT_UNLOCK (demux);
2187 GST_DEBUG_OBJECT (demux, "Stopping flush");
2188 gst_pad_push_event (demux->sinkpad, gst_event_new_flush_stop ());
2189 gst_matroska_demux_send_event (demux, gst_event_new_flush_stop ());
2190 } else if (demux->segment_running) {
2191 GST_DEBUG_OBJECT (demux, "Closing currently running segment");
2193 GST_OBJECT_LOCK (demux);
2194 if (demux->close_segment)
2195 gst_event_unref (demux->close_segment);
2197 demux->close_segment = gst_event_new_new_segment (TRUE,
2198 demux->segment.rate, GST_FORMAT_TIME, demux->segment.start,
2199 demux->segment.last_stop, demux->segment.last_stop);
2200 GST_OBJECT_UNLOCK (demux);
2203 GST_OBJECT_LOCK (demux);
2204 GST_DEBUG_OBJECT (demux, "Committing new seek segment");
2206 demux->segment.rate = rate;
2207 demux->segment.flags = flags;
2209 demux->segment.start = segment_start;
2210 demux->segment.stop = segment_stop;
2212 GST_OBJECT_UNLOCK (demux);
2214 /* notify start of new segment */
2215 if (demux->segment.flags & GST_SEEK_FLAG_SEGMENT) {
2218 msg = gst_message_new_segment_start (GST_OBJECT (demux),
2219 GST_FORMAT_TIME, demux->segment.start);
2220 gst_element_post_message (GST_ELEMENT (demux), msg);
2223 GST_OBJECT_LOCK (demux);
2224 if (demux->new_segment)
2225 gst_event_unref (demux->new_segment);
2226 demux->new_segment = gst_event_new_new_segment (FALSE, rate,
2227 GST_FORMAT_TIME, segment_start, segment_stop, segment_start);
2228 GST_OBJECT_UNLOCK (demux);
2230 /* update the time */
2231 g_assert (demux->src->len == demux->num_streams);
2232 for (i = 0; i < demux->src->len; i++) {
2233 GstMatroskaTrackContext *context = g_ptr_array_index (demux->src, i);
2234 context->pos = entry->time;
2235 context->set_discont = TRUE;
2236 context->last_flow = GST_FLOW_OK;
2238 demux->segment.last_stop = entry->time;
2240 /* restart our task since it might have been stopped when we did the
2242 demux->segment_running = TRUE;
2243 gst_pad_start_task (demux->sinkpad, (GstTaskFunction) gst_matroska_demux_loop,
2246 /* streaming can continue now */
2247 GST_PAD_STREAM_UNLOCK (demux->sinkpad);
2253 /* FIXME: shouldn't we either make it a real error or start the task
2254 * function again so that things can continue from where they left off? */
2255 GST_DEBUG_OBJECT (demux, "Got a seek error");
2256 GST_OBJECT_UNLOCK (demux);
2257 GST_PAD_STREAM_UNLOCK (demux->sinkpad);
2263 gst_matroska_demux_handle_src_event (GstPad * pad, GstEvent * event)
2265 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (gst_pad_get_parent (pad));
2266 gboolean res = TRUE;
2268 switch (GST_EVENT_TYPE (event)) {
2269 case GST_EVENT_SEEK:
2270 res = gst_matroska_demux_handle_seek_event (demux, pad, event);
2271 gst_event_unref (event);
2274 /* events we don't need to handle */
2275 case GST_EVENT_NAVIGATION:
2277 gst_event_unref (event);
2281 case GST_EVENT_LATENCY:
2283 res = gst_pad_push_event (demux->sinkpad, event);
2287 gst_object_unref (demux);
2292 static GstFlowReturn
2293 gst_matroska_demux_init_stream (GstMatroskaDemux * demux)
2295 GstEbmlRead *ebml = GST_EBML_READ (demux);
2301 GST_DEBUG_OBJECT (demux, "Init stream");
2303 if ((ret = gst_ebml_read_header (ebml, &doctype, &version)) != GST_FLOW_OK)
2306 if (!doctype || strcmp (doctype, "matroska") != 0) {
2307 GST_ELEMENT_ERROR (demux, STREAM, WRONG_TYPE, (NULL),
2308 ("Input is not a matroska stream (doctype=%s)",
2309 doctype ? doctype : "none"));
2311 return GST_FLOW_ERROR;
2315 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
2316 ("Demuxer version (2) is too old to read stream version %d", version));
2317 return GST_FLOW_ERROR;
2320 /* find segment, must be the next element but search as long as
2321 * we find it anyway */
2325 if ((ret = gst_ebml_peek_id (ebml, &last_level, &id)) != GST_FLOW_OK) {
2326 GST_DEBUG_OBJECT (demux, "gst_ebml_peek_id() failed!");
2330 if (id == GST_MATROSKA_ID_SEGMENT)
2334 GST_WARNING_OBJECT (demux,
2335 "Expected a Segment ID (0x%x), but received 0x%x!",
2336 GST_MATROSKA_ID_SEGMENT, id);
2338 if ((ret = gst_ebml_read_skip (ebml)) != GST_FLOW_OK)
2342 /* we now have a EBML segment */
2343 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2344 GST_DEBUG_OBJECT (demux, "gst_ebml_read_master() failed!");
2348 GST_DEBUG_OBJECT (demux, "Found Segment start at offset %" G_GUINT64_FORMAT,
2350 /* seeks are from the beginning of the segment,
2351 * after the segment ID/length */
2352 demux->ebml_segment_start = ebml->offset;
2357 static GstFlowReturn
2358 gst_matroska_demux_parse_tracks (GstMatroskaDemux * demux)
2360 GstEbmlRead *ebml = GST_EBML_READ (demux);
2361 GstFlowReturn ret = GST_FLOW_OK;
2364 DEBUG_ELEMENT_START (demux, ebml, "Tracks");
2366 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2367 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
2371 while (ret == GST_FLOW_OK) {
2372 if ((ret = gst_ebml_peek_id (ebml, &demux->level_up, &id)) != GST_FLOW_OK)
2375 if (demux->level_up) {
2381 /* one track within the "all-tracks" header */
2382 case GST_MATROSKA_ID_TRACKENTRY:
2383 ret = gst_matroska_demux_add_stream (demux);
2387 GST_WARNING ("Unknown Track subelement 0x%x - ignoring", id);
2388 ret = gst_ebml_read_skip (ebml);
2392 if (demux->level_up) {
2397 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
2399 demux->tracks_parsed = TRUE;
2404 static GstFlowReturn
2405 gst_matroska_demux_parse_index_cuetrack (GstMatroskaDemux * demux,
2408 GstEbmlRead *ebml = GST_EBML_READ (demux);
2411 GstMatroskaIndex idx;
2413 idx.pos = (guint64) - 1;
2415 idx.time = GST_CLOCK_TIME_NONE;
2418 DEBUG_ELEMENT_START (demux, ebml, "CueTrackPositions");
2420 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2421 DEBUG_ELEMENT_STOP (demux, ebml, "CueTrackPositions", ret);
2425 while (ret == GST_FLOW_OK) {
2426 if ((ret = gst_ebml_peek_id (ebml, &demux->level_up, &id)) != GST_FLOW_OK)
2429 if (demux->level_up) {
2436 case GST_MATROSKA_ID_CUETRACK:
2440 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
2445 GST_WARNING_OBJECT (demux, "Invalid CueTrack 0");
2449 GST_DEBUG_OBJECT (demux, "CueTrack: %" G_GUINT64_FORMAT, num);
2454 /* position in file */
2455 case GST_MATROSKA_ID_CUECLUSTERPOSITION:
2459 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
2462 if (num > G_MAXINT64) {
2463 GST_WARNING_OBJECT (demux, "CueClusterPosition %" G_GUINT64_FORMAT
2472 /* number of block in the cluster */
2473 case GST_MATROSKA_ID_CUEBLOCKNUMBER:
2477 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
2481 GST_WARNING_OBJECT (demux, "Invalid CueBlockNumber 0");
2485 GST_DEBUG_OBJECT (demux, "CueBlockNumber: %" G_GUINT64_FORMAT, num);
2491 GST_WARNING ("Unknown CueTrackPositions subelement 0x%x - ignoring",
2495 case GST_MATROSKA_ID_CUECODECSTATE:
2496 case GST_MATROSKA_ID_CUEREFERENCE:
2497 if ((ret = gst_ebml_read_skip (ebml)) != GST_FLOW_OK)
2502 if (demux->level_up) {
2508 DEBUG_ELEMENT_STOP (demux, ebml, "CueTrackPositions", ret);
2510 if ((ret == GST_FLOW_OK || ret == GST_FLOW_UNEXPECTED)
2511 && idx.pos != (guint64) - 1 && idx.track > 0) {
2512 g_array_append_val (demux->index, idx);
2514 } else if (ret == GST_FLOW_OK || ret == GST_FLOW_UNEXPECTED) {
2515 GST_DEBUG_OBJECT (demux, "CueTrackPositions without valid content");
2521 static GstFlowReturn
2522 gst_matroska_demux_parse_index_pointentry (GstMatroskaDemux * demux)
2524 GstEbmlRead *ebml = GST_EBML_READ (demux);
2527 GstClockTime time = GST_CLOCK_TIME_NONE;
2530 DEBUG_ELEMENT_START (demux, ebml, "CuePoint");
2532 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2533 DEBUG_ELEMENT_STOP (demux, ebml, "CuePoint", ret);
2537 while (ret == GST_FLOW_OK) {
2538 if ((ret = gst_ebml_peek_id (ebml, &demux->level_up, &id)) != GST_FLOW_OK)
2541 if (demux->level_up) {
2547 /* one single index entry ('point') */
2548 case GST_MATROSKA_ID_CUETIME:
2550 if ((ret = gst_ebml_read_uint (ebml, &id, &time)) != GST_FLOW_OK)
2553 GST_DEBUG_OBJECT (demux, "CueTime: %" G_GUINT64_FORMAT, time);
2554 time = time * demux->time_scale;
2558 /* position in the file + track to which it belongs */
2559 case GST_MATROSKA_ID_CUETRACKPOSITIONS:
2562 gst_matroska_demux_parse_index_cuetrack (demux,
2563 &nentries)) != GST_FLOW_OK)
2569 GST_WARNING_OBJECT (demux,
2570 "Unknown CuePoint subelement 0x%x - ignoring", id);
2571 if ((ret = gst_ebml_read_skip (ebml)) != GST_FLOW_OK)
2576 if (demux->level_up) {
2582 DEBUG_ELEMENT_STOP (demux, ebml, "CuePoint", ret);
2585 if (time == GST_CLOCK_TIME_NONE) {
2586 GST_WARNING_OBJECT (demux, "CuePoint without valid time");
2587 g_array_remove_range (demux->index, demux->index->len - nentries,
2592 for (i = demux->index->len - nentries; i < demux->index->len; i++) {
2593 GstMatroskaIndex *idx =
2594 &g_array_index (demux->index, GstMatroskaIndex, i);
2597 GST_DEBUG_OBJECT (demux, "Index entry: pos=%" G_GUINT64_FORMAT
2598 ", time=%" GST_TIME_FORMAT ", track=%u, block=%u", idx->pos,
2599 GST_TIME_ARGS (idx->time), (guint) idx->track, (guint) idx->block);
2603 GST_DEBUG_OBJECT (demux, "Empty CuePoint");
2610 gst_matroska_index_compare (GstMatroskaIndex * i1, GstMatroskaIndex * i2)
2612 if (i1->time < i2->time)
2614 else if (i1->time > i2->time)
2616 else if (i1->block < i2->block)
2618 else if (i1->block > i2->block)
2624 static GstFlowReturn
2625 gst_matroska_demux_parse_index (GstMatroskaDemux * demux)
2627 GstEbmlRead *ebml = GST_EBML_READ (demux);
2629 GstFlowReturn ret = GST_FLOW_OK;
2633 g_array_free (demux->index, TRUE);
2635 g_array_sized_new (FALSE, FALSE, sizeof (GstMatroskaIndex), 128);
2637 DEBUG_ELEMENT_START (demux, ebml, "Cues");
2639 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2640 DEBUG_ELEMENT_STOP (demux, ebml, "Cues", ret);
2644 while (ret == GST_FLOW_OK) {
2645 if ((ret = gst_ebml_peek_id (ebml, &demux->level_up, &id)) != GST_FLOW_OK)
2648 if (demux->level_up) {
2654 /* one single index entry ('point') */
2655 case GST_MATROSKA_ID_POINTENTRY:
2656 ret = gst_matroska_demux_parse_index_pointentry (demux);
2660 GST_WARNING ("Unknown Cues subelement 0x%x - ignoring", id);
2661 ret = gst_ebml_read_skip (ebml);
2665 if (demux->level_up) {
2670 DEBUG_ELEMENT_STOP (demux, ebml, "Cues", ret);
2672 /* Sort index by time, smallest time first, for easier searching */
2673 g_array_sort (demux->index, (GCompareFunc) gst_matroska_index_compare);
2675 /* Now sort the track specific index entries into their own arrays */
2676 for (i = 0; i < demux->index->len; i++) {
2677 GstMatroskaIndex *idx = &g_array_index (demux->index, GstMatroskaIndex, i);
2679 GstMatroskaTrackContext *ctx;
2681 if (demux->element_index) {
2684 if (idx->track != 0 &&
2686 gst_matroska_demux_stream_from_num (demux, idx->track)) != -1) {
2687 ctx = g_ptr_array_index (demux->src, track_num);
2689 if (ctx->index_writer_id == -1)
2690 gst_index_get_writer_id (demux->element_index, GST_OBJECT (ctx->pad),
2691 &ctx->index_writer_id);
2692 writer_id = ctx->index_writer_id;
2694 if (demux->element_index_writer_id == -1)
2695 gst_index_get_writer_id (demux->element_index, GST_OBJECT (demux),
2696 &demux->element_index_writer_id);
2697 writer_id = demux->element_index_writer_id;
2700 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
2701 G_GUINT64_FORMAT " for writer id %d", GST_TIME_ARGS (idx->time),
2702 idx->pos, writer_id);
2703 gst_index_add_association (demux->element_index, writer_id,
2704 GST_ASSOCIATION_FLAG_KEY_UNIT, GST_FORMAT_TIME, idx->time,
2705 GST_FORMAT_BYTES, idx->pos + demux->ebml_segment_start, NULL);
2708 if (idx->track == 0)
2711 track_num = gst_matroska_demux_stream_from_num (demux, idx->track);
2712 if (track_num == -1)
2715 ctx = g_ptr_array_index (demux->src, track_num);
2717 if (ctx->index_table == NULL)
2719 g_array_sized_new (FALSE, FALSE, sizeof (GstMatroskaIndex), 128);
2721 g_array_append_vals (ctx->index_table, idx, 1);
2724 demux->index_parsed = TRUE;
2729 static GstFlowReturn
2730 gst_matroska_demux_parse_info (GstMatroskaDemux * demux)
2732 GstEbmlRead *ebml = GST_EBML_READ (demux);
2733 GstFlowReturn ret = GST_FLOW_OK;
2736 DEBUG_ELEMENT_START (demux, ebml, "SegmentInfo");
2738 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2739 DEBUG_ELEMENT_STOP (demux, ebml, "SegmentInfo", ret);
2743 while (ret == GST_FLOW_OK) {
2744 if ((ret = gst_ebml_peek_id (ebml, &demux->level_up, &id)) != GST_FLOW_OK)
2747 if (demux->level_up) {
2753 /* cluster timecode */
2754 case GST_MATROSKA_ID_TIMECODESCALE:{
2757 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
2761 GST_DEBUG_OBJECT (demux, "TimeCodeScale: %" G_GUINT64_FORMAT, num);
2762 demux->time_scale = num;
2766 case GST_MATROSKA_ID_DURATION:{
2770 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
2774 GST_WARNING_OBJECT (demux, "Invalid duration %lf", num);
2778 GST_DEBUG_OBJECT (demux, "Duration: %lf", num);
2780 dur = gst_gdouble_to_guint64 (num *
2781 gst_guint64_to_gdouble (demux->time_scale));
2782 if (GST_CLOCK_TIME_IS_VALID (dur) && dur <= G_MAXINT64)
2783 demux->duration = dur;
2787 case GST_MATROSKA_ID_WRITINGAPP:{
2790 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
2793 GST_DEBUG_OBJECT (demux, "WritingApp: %s", GST_STR_NULL (text));
2794 demux->writing_app = text;
2798 case GST_MATROSKA_ID_MUXINGAPP:{
2801 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
2804 GST_DEBUG_OBJECT (demux, "MuxingApp: %s", GST_STR_NULL (text));
2805 demux->muxing_app = text;
2809 case GST_MATROSKA_ID_DATEUTC:{
2812 if ((ret = gst_ebml_read_date (ebml, &id, &time)) != GST_FLOW_OK)
2815 GST_DEBUG_OBJECT (demux, "DateUTC: %" G_GINT64_FORMAT, time);
2816 demux->created = time;
2820 case GST_MATROSKA_ID_TITLE:{
2822 GstTagList *taglist;
2824 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
2827 GST_DEBUG_OBJECT (demux, "Title: %s", GST_STR_NULL (text));
2828 taglist = gst_tag_list_new ();
2829 gst_tag_list_add (taglist, GST_TAG_MERGE_APPEND, GST_TAG_TITLE, text,
2831 gst_element_found_tags (GST_ELEMENT (ebml), taglist);
2837 GST_WARNING_OBJECT (demux,
2838 "Unknown SegmentInfo subelement 0x%x - ignoring", id);
2841 case GST_MATROSKA_ID_SEGMENTUID:
2842 case GST_MATROSKA_ID_SEGMENTFILENAME:
2843 case GST_MATROSKA_ID_PREVUID:
2844 case GST_MATROSKA_ID_PREVFILENAME:
2845 case GST_MATROSKA_ID_NEXTUID:
2846 case GST_MATROSKA_ID_NEXTFILENAME:
2847 case GST_MATROSKA_ID_SEGMENTFAMILY:
2848 case GST_MATROSKA_ID_CHAPTERTRANSLATE:
2849 ret = gst_ebml_read_skip (ebml);
2853 if (demux->level_up) {
2859 DEBUG_ELEMENT_STOP (demux, ebml, "SegmentInfo", ret);
2861 demux->segmentinfo_parsed = TRUE;
2866 static GstFlowReturn
2867 gst_matroska_demux_parse_metadata_id_simple_tag (GstMatroskaDemux * demux,
2868 GstTagList ** p_taglist)
2870 /* FIXME: check if there are more useful mappings */
2873 gchar *matroska_tagname;
2874 gchar *gstreamer_tagname;
2878 GST_MATROSKA_TAG_ID_TITLE, GST_TAG_TITLE}, {
2879 GST_MATROSKA_TAG_ID_AUTHOR, GST_TAG_ARTIST}, {
2880 GST_MATROSKA_TAG_ID_ALBUM, GST_TAG_ALBUM}, {
2881 GST_MATROSKA_TAG_ID_COMMENTS, GST_TAG_COMMENT}, {
2882 GST_MATROSKA_TAG_ID_BITSPS, GST_TAG_BITRATE}, {
2883 GST_MATROSKA_TAG_ID_BPS, GST_TAG_BITRATE}, {
2884 GST_MATROSKA_TAG_ID_ENCODER, GST_TAG_ENCODER}, {
2885 GST_MATROSKA_TAG_ID_DATE, GST_TAG_DATE}, {
2886 GST_MATROSKA_TAG_ID_ISRC, GST_TAG_ISRC}, {
2887 GST_MATROSKA_TAG_ID_COPYRIGHT, GST_TAG_COPYRIGHT}, {
2888 GST_MATROSKA_TAG_ID_BPM, GST_TAG_BEATS_PER_MINUTE}, {
2889 GST_MATROSKA_TAG_ID_TERMS_OF_USE, GST_TAG_LICENSE}, {
2890 GST_MATROSKA_TAG_ID_COMPOSER, GST_TAG_COMPOSER}, {
2891 GST_MATROSKA_TAG_ID_LEAD_PERFORMER, GST_TAG_PERFORMER}, {
2892 GST_MATROSKA_TAG_ID_GENRE, GST_TAG_GENRE}
2894 GstEbmlRead *ebml = GST_EBML_READ (demux);
2897 gchar *value = NULL;
2900 DEBUG_ELEMENT_START (demux, ebml, "SimpleTag");
2902 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2903 DEBUG_ELEMENT_STOP (demux, ebml, "SimpleTag", ret);
2907 while (ret == GST_FLOW_OK) {
2908 /* read all sub-entries */
2910 if ((ret = gst_ebml_peek_id (ebml, &demux->level_up, &id)) != GST_FLOW_OK)
2913 if (demux->level_up) {
2919 case GST_MATROSKA_ID_TAGNAME:
2922 ret = gst_ebml_read_ascii (ebml, &id, &tag);
2923 GST_DEBUG_OBJECT (demux, "TagName: %s", GST_STR_NULL (tag));
2926 case GST_MATROSKA_ID_TAGSTRING:
2929 ret = gst_ebml_read_utf8 (ebml, &id, &value);
2930 GST_DEBUG_OBJECT (demux, "TagString: %s", GST_STR_NULL (value));
2934 GST_WARNING_OBJECT (demux,
2935 "Unknown SimpleTag subelement 0x%x - ignoring", id);
2938 case GST_MATROSKA_ID_TAGLANGUAGE:
2939 case GST_MATROSKA_ID_TAGDEFAULT:
2940 case GST_MATROSKA_ID_TAGBINARY:
2941 ret = gst_ebml_read_skip (ebml);
2945 if (demux->level_up) {
2951 DEBUG_ELEMENT_STOP (demux, ebml, "SimpleTag", ret);
2956 for (i = 0; i < G_N_ELEMENTS (tag_conv); i++) {
2957 const gchar *tagname_gst = tag_conv[i].gstreamer_tagname;
2959 const gchar *tagname_mkv = tag_conv[i].matroska_tagname;
2961 if (strcmp (tagname_mkv, tag) == 0) {
2962 GValue dest = { 0, };
2963 GType dest_type = gst_tag_get_type (tagname_gst);
2965 g_value_init (&dest, dest_type);
2966 if (gst_value_deserialize (&dest, value)) {
2967 gst_tag_list_add_values (*p_taglist, GST_TAG_MERGE_APPEND,
2968 tagname_gst, &dest, NULL);
2970 GST_WARNING_OBJECT (demux, "Can't transform tag '%s' with "
2971 "value '%s' to target type '%s'", tag, value,
2972 g_type_name (dest_type));
2974 g_value_unset (&dest);
2986 static GstFlowReturn
2987 gst_matroska_demux_parse_metadata_id_tag (GstMatroskaDemux * demux,
2988 GstTagList ** p_taglist)
2990 GstEbmlRead *ebml = GST_EBML_READ (demux);
2994 DEBUG_ELEMENT_START (demux, ebml, "Tag");
2996 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2997 DEBUG_ELEMENT_STOP (demux, ebml, "Tag", ret);
3001 while (ret == GST_FLOW_OK) {
3002 /* read all sub-entries */
3004 if ((ret = gst_ebml_peek_id (ebml, &demux->level_up, &id)) != GST_FLOW_OK)
3007 if (demux->level_up) {
3013 case GST_MATROSKA_ID_SIMPLETAG:
3015 gst_matroska_demux_parse_metadata_id_simple_tag (demux, p_taglist);
3019 GST_WARNING_OBJECT (demux, "Unknown Tag subelement 0x%x - ignoring",
3021 ret = gst_ebml_read_skip (ebml);
3025 if (demux->level_up) {
3031 DEBUG_ELEMENT_STOP (demux, ebml, "Tag", ret);
3036 static GstFlowReturn
3037 gst_matroska_demux_parse_metadata (GstMatroskaDemux * demux)
3039 GstEbmlRead *ebml = GST_EBML_READ (demux);
3040 GstTagList *taglist;
3041 GstFlowReturn ret = GST_FLOW_OK;
3044 GstEbmlLevel *curlevel;
3046 /* Can't be NULL at this point */
3047 g_assert (ebml->level != NULL);
3048 curlevel = ebml->level->data;
3050 /* Make sure we don't parse a tags element twice and
3051 * post it's tags twice */
3052 for (l = demux->tags_parsed; l; l = l->next) {
3053 GstEbmlLevel *level = l->data;
3056 curlevel = ebml->level->data;
3060 if (level->start == curlevel->start && level->length == curlevel->length) {
3061 GST_DEBUG_OBJECT (demux, "Skipping already parsed Tags at offset %"
3062 G_GUINT64_FORMAT, ebml->offset);
3063 ret = gst_ebml_read_skip (ebml);
3068 DEBUG_ELEMENT_START (demux, ebml, "Tags");
3070 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3071 DEBUG_ELEMENT_STOP (demux, ebml, "Tags", ret);
3075 taglist = gst_tag_list_new ();
3077 /* TODO: g_slice_dup() if we depend on GLib 2.14 */
3078 curlevel = g_slice_new (GstEbmlLevel);
3079 memcpy (curlevel, ebml->level->data, sizeof (GstEbmlLevel));
3080 demux->tags_parsed = g_list_prepend (demux->tags_parsed, curlevel);
3082 while (ret == GST_FLOW_OK) {
3083 if ((ret = gst_ebml_peek_id (ebml, &demux->level_up, &id)) != GST_FLOW_OK)
3086 if (demux->level_up) {
3092 case GST_MATROSKA_ID_TAG:
3093 ret = gst_matroska_demux_parse_metadata_id_tag (demux, &taglist);
3097 GST_WARNING_OBJECT (demux, "Unknown Tags subelement 0x%x - ignoring",
3099 /* FIXME: Use to limit the tags to specific pads */
3100 case GST_MATROSKA_ID_TARGETS:
3101 ret = gst_ebml_read_skip (ebml);
3105 if (demux->level_up) {
3111 DEBUG_ELEMENT_STOP (demux, ebml, "Tags", ret);
3113 /* FIXME: tags must be pushed *after* the initial newsegment event */
3114 gst_tag_list_add (taglist, GST_TAG_MERGE_REPLACE, GST_TAG_CONTAINER_FORMAT,
3116 gst_element_found_tags (GST_ELEMENT (ebml), taglist);
3121 static GstFlowReturn
3122 gst_matroska_demux_parse_attached_file (GstMatroskaDemux * demux,
3123 GstTagList * taglist)
3125 GstEbmlRead *ebml = GST_EBML_READ (demux);
3128 gchar *description = NULL;
3129 gchar *filename = NULL;
3130 gchar *mimetype = NULL;
3131 guint8 *data = NULL;
3132 guint64 datalen = 0;
3134 DEBUG_ELEMENT_START (demux, ebml, "AttachedFile");
3136 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3137 DEBUG_ELEMENT_STOP (demux, ebml, "AttachedFile", ret);
3141 while (ret == GST_FLOW_OK) {
3142 /* read all sub-entries */
3144 if ((ret = gst_ebml_peek_id (ebml, &demux->level_up, &id)) != GST_FLOW_OK)
3147 if (demux->level_up) {
3153 case GST_MATROSKA_ID_FILEDESCRIPTION:
3155 GST_WARNING_OBJECT (demux, "FileDescription can only appear once");
3159 ret = gst_ebml_read_utf8 (ebml, &id, &description);
3160 GST_DEBUG_OBJECT (demux, "FileDescription: %s",
3161 GST_STR_NULL (description));
3163 case GST_MATROSKA_ID_FILENAME:
3165 GST_WARNING_OBJECT (demux, "FileName can only appear once");
3169 ret = gst_ebml_read_utf8 (ebml, &id, &filename);
3171 GST_DEBUG_OBJECT (demux, "FileName: %s", GST_STR_NULL (filename));
3173 case GST_MATROSKA_ID_FILEMIMETYPE:
3175 GST_WARNING_OBJECT (demux, "FileMimeType can only appear once");
3179 ret = gst_ebml_read_ascii (ebml, &id, &mimetype);
3180 GST_DEBUG_OBJECT (demux, "FileMimeType: %s", GST_STR_NULL (mimetype));
3182 case GST_MATROSKA_ID_FILEDATA:
3184 GST_WARNING_OBJECT (demux, "FileData can only appear once");
3188 ret = gst_ebml_read_binary (ebml, &id, &data, &datalen);
3189 GST_DEBUG_OBJECT (demux, "FileData of size %" G_GUINT64_FORMAT,
3194 GST_WARNING_OBJECT (demux,
3195 "Unknown AttachedFile subelement 0x%x - ignoring", id);
3197 case GST_MATROSKA_ID_FILEUID:
3198 ret = gst_ebml_read_skip (ebml);
3202 if (demux->level_up) {
3208 DEBUG_ELEMENT_STOP (demux, ebml, "AttachedFile", ret);
3210 if (filename && mimetype && data && datalen > 0) {
3211 GstTagImageType image_type = GST_TAG_IMAGE_TYPE_NONE;
3212 GstBuffer *tagbuffer = NULL;
3214 gchar *filename_lc = g_utf8_strdown (filename, -1);
3216 GST_DEBUG_OBJECT (demux, "Creating tag for attachment with filename '%s', "
3217 "mimetype '%s', description '%s', size %" G_GUINT64_FORMAT, filename,
3218 mimetype, GST_STR_NULL (description), datalen);
3220 /* TODO: better heuristics for different image types */
3221 if (strstr (filename_lc, "cover")) {
3222 if (strstr (filename_lc, "back"))
3223 image_type = GST_TAG_IMAGE_TYPE_BACK_COVER;
3225 image_type = GST_TAG_IMAGE_TYPE_FRONT_COVER;
3226 } else if (g_str_has_prefix (mimetype, "image/") ||
3227 g_str_has_suffix (filename_lc, "png") ||
3228 g_str_has_suffix (filename_lc, "jpg") ||
3229 g_str_has_suffix (filename_lc, "jpeg") ||
3230 g_str_has_suffix (filename_lc, "gif") ||
3231 g_str_has_suffix (filename_lc, "bmp")) {
3232 image_type = GST_TAG_IMAGE_TYPE_UNDEFINED;
3234 g_free (filename_lc);
3236 /* First try to create an image tag buffer from this */
3237 if (image_type != GST_TAG_IMAGE_TYPE_NONE) {
3239 gst_tag_image_data_to_image_buffer (data, datalen, image_type);
3242 image_type = GST_TAG_IMAGE_TYPE_NONE;
3245 /* if this failed create an attachment buffer */
3247 tagbuffer = gst_buffer_new_and_alloc (datalen);
3249 memcpy (GST_BUFFER_DATA (tagbuffer), data, datalen);
3250 GST_BUFFER_SIZE (tagbuffer) = datalen;
3252 caps = gst_type_find_helper_for_buffer (NULL, tagbuffer, NULL);
3254 caps = gst_caps_new_simple (mimetype, NULL);
3255 gst_buffer_set_caps (tagbuffer, caps);
3256 gst_caps_unref (caps);
3259 /* Set filename and description on the caps */
3260 caps = GST_BUFFER_CAPS (tagbuffer);
3261 gst_caps_set_simple (caps, "filename", G_TYPE_STRING, filename, NULL);
3263 gst_caps_set_simple (caps, "description", G_TYPE_STRING, description,
3266 GST_DEBUG_OBJECT (demux,
3267 "Created attachment buffer with caps: %" GST_PTR_FORMAT, caps);
3269 /* and append to the tag list */
3270 if (image_type != GST_TAG_IMAGE_TYPE_NONE)
3271 gst_tag_list_add (taglist, GST_TAG_MERGE_APPEND, GST_TAG_IMAGE, tagbuffer,
3274 gst_tag_list_add (taglist, GST_TAG_MERGE_APPEND, GST_TAG_ATTACHMENT,
3281 g_free (description);
3286 static GstFlowReturn
3287 gst_matroska_demux_parse_attachments (GstMatroskaDemux * demux)
3289 GstEbmlRead *ebml = GST_EBML_READ (demux);
3291 GstFlowReturn ret = GST_FLOW_OK;
3292 GstTagList *taglist;
3294 DEBUG_ELEMENT_START (demux, ebml, "Attachments");
3296 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3297 DEBUG_ELEMENT_STOP (demux, ebml, "Attachments", ret);
3301 taglist = gst_tag_list_new ();
3303 while (ret == GST_FLOW_OK) {
3304 if ((ret = gst_ebml_peek_id (ebml, &demux->level_up, &id)) != GST_FLOW_OK)
3307 if (demux->level_up) {
3313 case GST_MATROSKA_ID_ATTACHEDFILE:
3314 ret = gst_matroska_demux_parse_attached_file (demux, taglist);
3318 GST_WARNING ("Unknown Attachments subelement 0x%x - ignoring", id);
3319 ret = gst_ebml_read_skip (ebml);
3323 if (demux->level_up) {
3328 DEBUG_ELEMENT_STOP (demux, ebml, "Attachments", ret);
3330 if (gst_structure_n_fields (GST_STRUCTURE (taglist)) > 0) {
3331 GST_DEBUG_OBJECT (demux, "Posting attachment tags");
3332 gst_element_found_tags (GST_ELEMENT (ebml), taglist);
3334 GST_DEBUG_OBJECT (demux, "No valid attachments found");
3335 gst_tag_list_free (taglist);
3338 demux->attachments_parsed = TRUE;
3343 static GstFlowReturn
3344 gst_matroska_demux_parse_chapters (GstMatroskaDemux * demux)
3346 GstEbmlRead *ebml = GST_EBML_READ (demux);
3348 GstFlowReturn ret = GST_FLOW_OK;
3350 GST_WARNING_OBJECT (demux, "Parsing of chapters not implemented yet");
3352 /* TODO: implement parsing of chapters */
3354 DEBUG_ELEMENT_START (demux, ebml, "Chapters");
3356 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3357 DEBUG_ELEMENT_STOP (demux, ebml, "Chapters", ret);
3361 while (ret == GST_FLOW_OK) {
3362 if ((ret = gst_ebml_peek_id (ebml, &demux->level_up, &id)) != GST_FLOW_OK)
3365 if (demux->level_up) {
3372 ret = gst_ebml_read_skip (ebml);
3376 if (demux->level_up) {
3382 DEBUG_ELEMENT_STOP (demux, ebml, "Chapters", ret);
3387 * Read signed/unsigned "EBML" numbers.
3388 * Return: number of bytes processed.
3392 gst_matroska_ebmlnum_uint (guint8 * data, guint size, guint64 * num)
3394 gint len_mask = 0x80, read = 1, n = 1, num_ffs = 0;
3402 while (read <= 8 && !(total & len_mask)) {
3409 if ((total &= (len_mask - 1)) == len_mask - 1)
3414 if (data[n] == 0xff)
3416 total = (total << 8) | data[n];
3420 if (read == num_ffs && total != 0)
3429 gst_matroska_ebmlnum_sint (guint8 * data, guint size, gint64 * num)
3434 /* read as unsigned number first */
3435 if ((res = gst_matroska_ebmlnum_uint (data, size, &unum)) < 0)
3439 if (unum == G_MAXUINT64)
3442 *num = unum - ((1 << ((7 * res) - 1)) - 1);
3448 * Mostly used for subtitles. We add void filler data for each
3449 * lagging stream to make sure we don't deadlock.
3453 gst_matroska_demux_sync_streams (GstMatroskaDemux * demux)
3457 GST_LOG_OBJECT (demux, "Sync to %" GST_TIME_FORMAT,
3458 GST_TIME_ARGS (demux->segment.last_stop));
3460 g_assert (demux->num_streams == demux->src->len);
3461 for (stream_nr = 0; stream_nr < demux->src->len; stream_nr++) {
3462 GstMatroskaTrackContext *context;
3464 context = g_ptr_array_index (demux->src, stream_nr);
3466 GST_LOG_OBJECT (demux,
3467 "Checking for resync on stream %d (%" GST_TIME_FORMAT ")", stream_nr,
3468 GST_TIME_ARGS (context->pos));
3470 /* does it lag? 0.5 seconds is a random treshold... */
3471 if (context->pos + (GST_SECOND / 2) < demux->segment.last_stop) {
3472 GST_DEBUG_OBJECT (demux,
3473 "Synchronizing stream %d with others by advancing time " "from %"
3474 GST_TIME_FORMAT " to %" GST_TIME_FORMAT, stream_nr,
3475 GST_TIME_ARGS (context->pos),
3476 GST_TIME_ARGS (demux->segment.last_stop));
3478 context->pos = demux->segment.last_stop;
3480 /* advance stream time */
3481 gst_pad_push_event (context->pad,
3482 gst_event_new_new_segment (TRUE, demux->segment.rate,
3483 GST_FORMAT_TIME, demux->segment.last_stop, -1,
3484 demux->segment.last_stop));
3489 static GstFlowReturn
3490 gst_matroska_demux_push_hdr_buf (GstMatroskaDemux * demux,
3491 GstMatroskaTrackContext * stream, guint8 * data, guint len)
3493 GstFlowReturn ret, cret;
3494 GstBuffer *header_buf = NULL;
3496 ret = gst_pad_alloc_buffer_and_set_caps (stream->pad,
3497 GST_BUFFER_OFFSET_NONE, len, stream->caps, &header_buf);
3499 /* we combine but don't use the combined value to check if we have a buffer
3500 * or not. The combined value is what we return. */
3501 cret = gst_matroska_demux_combine_flows (demux, stream, ret);
3502 if (ret != GST_FLOW_OK)
3505 memcpy (GST_BUFFER_DATA (header_buf), data, len);
3507 if (stream->set_discont) {
3508 GST_BUFFER_FLAG_SET (header_buf, GST_BUFFER_FLAG_DISCONT);
3509 stream->set_discont = FALSE;
3512 ret = gst_pad_push (stream->pad, header_buf);
3515 cret = gst_matroska_demux_combine_flows (demux, stream, ret);
3522 GST_DEBUG_OBJECT (demux, "could not alloc buffer: %s, combined %s",
3523 gst_flow_get_name (ret), gst_flow_get_name (cret));
3528 static GstFlowReturn
3529 gst_matroska_demux_push_flac_codec_priv_data (GstMatroskaDemux * demux,
3530 GstMatroskaTrackContext * stream)
3536 GST_LOG_OBJECT (demux, "priv data size = %u", stream->codec_priv_size);
3538 pdata = (guint8 *) stream->codec_priv;
3540 /* need at least 'fLaC' marker + STREAMINFO metadata block */
3541 if (stream->codec_priv_size < ((4) + (4 + 34))) {
3542 GST_WARNING_OBJECT (demux, "not enough codec priv data for flac headers");
3543 return GST_FLOW_ERROR;
3546 if (memcmp (pdata, "fLaC", 4) != 0) {
3547 GST_WARNING_OBJECT (demux, "no flac marker at start of stream headers");
3548 return GST_FLOW_ERROR;
3551 ret = gst_matroska_demux_push_hdr_buf (demux, stream, pdata, 4);
3552 if (ret != GST_FLOW_OK)
3555 off = 4; /* skip fLaC marker */
3556 while (off < stream->codec_priv_size) {
3557 len = GST_READ_UINT8 (pdata + off + 1) << 16;
3558 len |= GST_READ_UINT8 (pdata + off + 2) << 8;
3559 len |= GST_READ_UINT8 (pdata + off + 3);
3561 GST_DEBUG_OBJECT (demux, "header packet: len=%u bytes, flags=0x%02x",
3562 len, (guint) pdata[off]);
3564 ret = gst_matroska_demux_push_hdr_buf (demux, stream, pdata + off, len);
3565 if (ret != GST_FLOW_OK)
3573 static GstFlowReturn
3574 gst_matroska_demux_push_speex_codec_priv_data (GstMatroskaDemux * demux,
3575 GstMatroskaTrackContext * stream)
3580 GST_LOG_OBJECT (demux, "priv data size = %u", stream->codec_priv_size);
3582 pdata = (guint8 *) stream->codec_priv;
3584 /* need at least 'fLaC' marker + STREAMINFO metadata block */
3585 if (stream->codec_priv_size < 80) {
3586 GST_WARNING_OBJECT (demux, "not enough codec priv data for speex headers");
3587 return GST_FLOW_ERROR;
3590 if (memcmp (pdata, "Speex ", 8) != 0) {
3591 GST_WARNING_OBJECT (demux, "no Speex marker at start of stream headers");
3592 return GST_FLOW_ERROR;
3595 ret = gst_matroska_demux_push_hdr_buf (demux, stream, pdata, 80);
3596 if (ret != GST_FLOW_OK)
3599 if (stream->codec_priv_size == 80)
3602 return gst_matroska_demux_push_hdr_buf (demux, stream, pdata + 80,
3603 stream->codec_priv_size - 80);
3606 static GstFlowReturn
3607 gst_matroska_demux_push_xiph_codec_priv_data (GstMatroskaDemux * demux,
3608 GstMatroskaTrackContext * stream)
3611 guint8 *p = (guint8 *) stream->codec_priv;
3612 gint i, offset, num_packets;
3613 guint *length, last;
3615 /* start of the stream and vorbis audio or theora video, need to
3616 * send the codec_priv data as first three packets */
3617 num_packets = p[0] + 1;
3618 GST_DEBUG_OBJECT (demux, "%u stream headers, total length=%u bytes",
3619 (guint) num_packets, stream->codec_priv_size);
3621 length = g_alloca (num_packets * sizeof (guint));
3625 /* first packets, read length values */
3626 for (i = 0; i < num_packets - 1; i++) {
3628 while (offset < stream->codec_priv_size) {
3629 length[i] += p[offset];
3630 if (p[offset++] != 0xff)
3635 if (offset + last > stream->codec_priv_size)
3636 return GST_FLOW_ERROR;
3638 /* last packet is the remaining size */
3639 length[i] = stream->codec_priv_size - offset - last;
3641 for (i = 0; i < num_packets; i++) {
3642 GST_DEBUG_OBJECT (demux, "buffer %d: length=%u bytes", i,
3644 if (offset + length[i] > stream->codec_priv_size)
3645 return GST_FLOW_ERROR;
3648 gst_matroska_demux_push_hdr_buf (demux, stream, p + offset, length[i]);
3649 if (ret != GST_FLOW_OK)
3652 offset += length[i];
3658 gst_matroska_demux_push_dvd_clut_change_event (GstMatroskaDemux * demux,
3659 GstMatroskaTrackContext * stream)
3663 g_assert (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB));
3665 if (!stream->codec_priv)
3668 /* ideally, VobSub private data should be parsed and stored more convenient
3669 * elsewhere, but for now, only interested in a small part */
3671 /* make sure we have terminating 0 */
3672 buf = g_strndup ((gchar *) stream->codec_priv, stream->codec_priv_size);
3674 /* just locate and parse palette part */
3675 start = strstr ((gchar *) stream->codec_priv, "palette:");
3680 guint8 r, g, b, y, u, v;
3683 while (g_ascii_isspace (*start))
3685 for (i = 0; i < 16; i++) {
3686 if (sscanf (start, "%06x", &col) != 1)
3689 while ((*start == ',') || g_ascii_isspace (*start))
3691 /* sigh, need to convert this from vobsub pseudo-RGB to YUV */
3692 r = (col >> 16) & 0xff;
3693 g = (col >> 8) & 0xff;
3695 y = CLAMP ((0.1494 * r + 0.6061 * g + 0.2445 * b) * 219 / 255 + 16, 0,
3697 u = CLAMP (0.6066 * r - 0.4322 * g - 0.1744 * b + 128, 0, 255);
3698 v = CLAMP (-0.08435 * r - 0.3422 * g + 0.4266 * b + 128, 0, 255);
3699 clut[i] = (y << 16) | (u << 8) | v;
3702 /* got them all without problems; build and send event */
3706 s = gst_structure_new ("application/x-gst-dvd", "event", G_TYPE_STRING,
3707 "dvd-spu-clut-change", "clut00", G_TYPE_INT, clut[0], "clut01",
3708 G_TYPE_INT, clut[1], "clut02", G_TYPE_INT, clut[2], "clut03",
3709 G_TYPE_INT, clut[3], "clut04", G_TYPE_INT, clut[4], "clut05",
3710 G_TYPE_INT, clut[5], "clut06", G_TYPE_INT, clut[6], "clut07",
3711 G_TYPE_INT, clut[7], "clut08", G_TYPE_INT, clut[8], "clut09",
3712 G_TYPE_INT, clut[9], "clut10", G_TYPE_INT, clut[10], "clut11",
3713 G_TYPE_INT, clut[11], "clut12", G_TYPE_INT, clut[12], "clut13",
3714 G_TYPE_INT, clut[13], "clut14", G_TYPE_INT, clut[14], "clut15",
3715 G_TYPE_INT, clut[15], NULL);
3717 gst_pad_push_event (stream->pad,
3718 gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM, s));
3724 static GstFlowReturn
3725 gst_matroska_demux_add_mpeg_seq_header (GstElement * element,
3726 GstMatroskaTrackContext * stream, GstBuffer ** buf)
3728 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
3730 guint seq_header_len;
3733 if (stream->codec_state) {
3734 seq_header = stream->codec_state;
3735 seq_header_len = stream->codec_state_size;
3736 } else if (stream->codec_priv) {
3737 seq_header = stream->codec_priv;
3738 seq_header_len = stream->codec_priv_size;
3743 /* Sequence header only needed for keyframes */
3744 if (GST_BUFFER_FLAG_IS_SET (*buf, GST_BUFFER_FLAG_DELTA_UNIT))
3747 if (GST_BUFFER_SIZE (*buf) < 4)
3750 header = GST_READ_UINT32_BE (GST_BUFFER_DATA (*buf));
3751 /* Sequence start code, if not found prepend */
3752 if (header != 0x000001b3) {
3754 GstFlowReturn ret, cret;
3756 ret = gst_pad_alloc_buffer_and_set_caps (stream->pad,
3757 GST_BUFFER_OFFSET_NONE, GST_BUFFER_SIZE (*buf) + seq_header_len,
3758 stream->caps, &newbuf);
3759 cret = gst_matroska_demux_combine_flows (demux, stream, ret);
3760 if (ret != GST_FLOW_OK) {
3761 GST_WARNING_OBJECT (demux, "Reallocating buffer for sequence header "
3762 "failed: %s, combined flow return: %s", gst_flow_get_name (ret),
3763 gst_flow_get_name (cret));
3767 GST_DEBUG_OBJECT (demux, "Prepending MPEG sequence header");
3768 gst_buffer_copy_metadata (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
3769 GST_BUFFER_COPY_FLAGS);
3770 g_memmove (GST_BUFFER_DATA (newbuf), seq_header, seq_header_len);
3771 g_memmove (GST_BUFFER_DATA (newbuf) + seq_header_len,
3772 GST_BUFFER_DATA (*buf), GST_BUFFER_SIZE (*buf));
3773 gst_buffer_unref (*buf);
3780 static GstFlowReturn
3781 gst_matroska_demux_add_wvpk_header (GstElement * element,
3782 GstMatroskaTrackContext * stream, GstBuffer ** buf)
3784 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
3785 GstMatroskaTrackAudioContext *audiocontext =
3786 (GstMatroskaTrackAudioContext *) stream;
3787 GstBuffer *newbuf = NULL;
3790 GstFlowReturn ret, cret = GST_FLOW_OK;
3798 wvh.version = GST_READ_UINT16_LE (stream->codec_priv);
3801 wvh.total_samples = -1;
3802 wvh.block_index = audiocontext->wvpk_block_index;
3804 if (audiocontext->channels <= 2) {
3805 guint32 block_samples;
3807 block_samples = GST_READ_UINT32_LE (GST_BUFFER_DATA (*buf));
3808 /* we need to reconstruct the header of the wavpack block */
3810 /* -20 because ck_size is the size of the wavpack block -8
3811 * and lace_size is the size of the wavpack block + 12
3812 * (the three guint32 of the header that already are in the buffer) */
3813 wvh.ck_size = GST_BUFFER_SIZE (*buf) + sizeof (Wavpack4Header) - 20;
3815 /* block_samples, flags and crc are already in the buffer */
3816 newlen = GST_BUFFER_SIZE (*buf) + sizeof (Wavpack4Header) - 12;
3818 gst_pad_alloc_buffer_and_set_caps (stream->pad, GST_BUFFER_OFFSET_NONE,
3819 newlen, stream->caps, &newbuf);
3820 cret = gst_matroska_demux_combine_flows (demux, stream, ret);
3821 if (ret != GST_FLOW_OK) {
3822 GST_DEBUG_OBJECT (demux, "pad_alloc failed %s, combined %s",
3823 gst_flow_get_name (ret), gst_flow_get_name (cret));
3827 data = GST_BUFFER_DATA (newbuf);
3832 GST_WRITE_UINT32_LE (data + 4, wvh.ck_size);
3833 GST_WRITE_UINT16_LE (data + 8, wvh.version);
3834 GST_WRITE_UINT8 (data + 10, wvh.track_no);
3835 GST_WRITE_UINT8 (data + 11, wvh.index_no);
3836 GST_WRITE_UINT32_LE (data + 12, wvh.total_samples);
3837 GST_WRITE_UINT32_LE (data + 16, wvh.block_index);
3838 g_memmove (data + 20, GST_BUFFER_DATA (*buf), GST_BUFFER_SIZE (*buf));
3839 gst_buffer_copy_metadata (newbuf, *buf,
3840 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS);
3841 gst_buffer_unref (*buf);
3843 audiocontext->wvpk_block_index += block_samples;
3848 guint32 block_samples, flags, crc, blocksize;
3850 data = GST_BUFFER_DATA (*buf);
3851 size = GST_BUFFER_SIZE (*buf);
3854 GST_ERROR_OBJECT (demux, "Too small wavpack buffer");
3855 return GST_FLOW_ERROR;
3858 block_samples = GST_READ_UINT32_LE (data);
3863 flags = GST_READ_UINT32_LE (data);
3866 crc = GST_READ_UINT32_LE (data);
3869 blocksize = GST_READ_UINT32_LE (data);
3873 if (blocksize == 0 || size < blocksize)
3876 if (newbuf == NULL) {
3877 newbuf = gst_buffer_new_and_alloc (sizeof (Wavpack4Header) + blocksize);
3878 gst_buffer_set_caps (newbuf, stream->caps);
3880 gst_buffer_copy_metadata (newbuf, *buf,
3881 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS);
3884 outdata = GST_BUFFER_DATA (newbuf);
3886 GST_BUFFER_SIZE (newbuf) += sizeof (Wavpack4Header) + blocksize;
3887 GST_BUFFER_DATA (newbuf) =
3888 g_realloc (GST_BUFFER_DATA (newbuf), GST_BUFFER_SIZE (newbuf));
3889 GST_BUFFER_MALLOCDATA (newbuf) = GST_BUFFER_DATA (newbuf);
3890 outdata = GST_BUFFER_DATA (newbuf);
3893 outdata[outpos] = 'w';
3894 outdata[outpos + 1] = 'v';
3895 outdata[outpos + 2] = 'p';
3896 outdata[outpos + 3] = 'k';
3899 GST_WRITE_UINT32_LE (outdata + outpos,
3900 blocksize + sizeof (Wavpack4Header) - 8);
3901 GST_WRITE_UINT16_LE (outdata + outpos + 4, wvh.version);
3902 GST_WRITE_UINT8 (outdata + outpos + 6, wvh.track_no);
3903 GST_WRITE_UINT8 (outdata + outpos + 7, wvh.index_no);
3904 GST_WRITE_UINT32_LE (outdata + outpos + 8, wvh.total_samples);
3905 GST_WRITE_UINT32_LE (outdata + outpos + 12, wvh.block_index);
3906 GST_WRITE_UINT32_LE (outdata + outpos + 16, block_samples);
3907 GST_WRITE_UINT32_LE (outdata + outpos + 20, flags);
3908 GST_WRITE_UINT32_LE (outdata + outpos + 24, crc);
3911 g_memmove (outdata + outpos, data, blocksize);
3912 outpos += blocksize;
3916 gst_buffer_unref (*buf);
3918 audiocontext->wvpk_block_index += block_samples;
3924 static GstFlowReturn
3925 gst_matroska_demux_check_subtitle_buffer (GstElement * element,
3926 GstMatroskaTrackContext * stream, GstBuffer ** buf)
3928 GstMatroskaTrackSubtitleContext *sub_stream;
3929 const gchar *encoding, *data;
3935 sub_stream = (GstMatroskaTrackSubtitleContext *) stream;
3937 data = (const gchar *) GST_BUFFER_DATA (*buf);
3938 size = GST_BUFFER_SIZE (*buf);
3940 if (!sub_stream->invalid_utf8) {
3941 if (g_utf8_validate (data, size, NULL)) {
3944 GST_WARNING_OBJECT (element, "subtitle stream %d is not valid UTF-8, this "
3945 "is broken according to the matroska specification", stream->num);
3946 sub_stream->invalid_utf8 = TRUE;
3949 /* file with broken non-UTF8 subtitle, do the best we can do to fix it */
3950 encoding = g_getenv ("GST_SUBTITLE_ENCODING");
3951 if (encoding == NULL || *encoding == '\0') {
3952 /* if local encoding is UTF-8 and no encoding specified
3953 * via the environment variable, assume ISO-8859-15 */
3954 if (g_get_charset (&encoding)) {
3955 encoding = "ISO-8859-15";
3959 utf8 = g_convert_with_fallback (data, size, "UTF-8", encoding, "*",
3963 GST_LOG_OBJECT (element, "could not convert string from '%s' to UTF-8: %s",
3964 encoding, err->message);
3968 /* invalid input encoding, fall back to ISO-8859-15 (always succeeds) */
3969 encoding = "ISO-8859-15";
3970 utf8 = g_convert_with_fallback (data, size, "UTF-8", encoding, "*",
3974 GST_LOG_OBJECT (element, "converted subtitle text from %s to UTF-8 %s",
3975 encoding, (err) ? "(using ISO-8859-15 as fallback)" : "");
3978 utf8 = g_strdup ("invalid subtitle");
3980 newbuf = gst_buffer_new ();
3981 GST_BUFFER_MALLOCDATA (newbuf) = (guint8 *) utf8;
3982 GST_BUFFER_DATA (newbuf) = (guint8 *) utf8;
3983 GST_BUFFER_SIZE (newbuf) = strlen (utf8);
3984 gst_buffer_copy_metadata (newbuf, *buf,
3985 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS);
3986 gst_buffer_unref (*buf);
3992 static GstFlowReturn
3993 gst_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux,
3994 guint64 cluster_time, guint64 cluster_offset, gboolean is_simpleblock)
3996 GstMatroskaTrackContext *stream = NULL;
3997 GstEbmlRead *ebml = GST_EBML_READ (demux);
3998 GstFlowReturn ret = GST_FLOW_OK;
3999 gboolean readblock = FALSE;
4001 guint64 block_duration = 0;
4002 GstBuffer *buf = NULL;
4003 gint stream_num = -1, n, laces = 0;
4005 gint *lace_size = NULL;
4008 gint64 referenceblock = 0;
4010 while (ret == GST_FLOW_OK) {
4011 if (!is_simpleblock) {
4012 if ((ret = gst_ebml_peek_id (ebml, &demux->level_up, &id)) != GST_FLOW_OK)
4015 if (demux->level_up) {
4020 id = GST_MATROSKA_ID_SIMPLEBLOCK;
4024 /* one block inside the group. Note, block parsing is one
4025 * of the harder things, so this code is a bit complicated.
4026 * See http://www.matroska.org/ for documentation. */
4027 case GST_MATROSKA_ID_SIMPLEBLOCK:
4028 case GST_MATROSKA_ID_BLOCK:
4034 gst_buffer_unref (buf);
4037 if ((ret = gst_ebml_read_buffer (ebml, &id, &buf)) != GST_FLOW_OK)
4040 data = GST_BUFFER_DATA (buf);
4041 size = GST_BUFFER_SIZE (buf);
4043 /* first byte(s): blocknum */
4044 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0) {
4045 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Data error"));
4046 gst_buffer_unref (buf);
4048 ret = GST_FLOW_ERROR;
4054 /* fetch stream from num */
4055 stream_num = gst_matroska_demux_stream_from_num (demux, num);
4056 if (size < 3 || stream_num < 0 || stream_num >= demux->num_streams) {
4057 gst_buffer_unref (buf);
4059 GST_WARNING_OBJECT (demux, "Invalid stream %d or size %u", stream_num,
4061 ret = GST_FLOW_ERROR;
4065 stream = g_ptr_array_index (demux->src, stream_num);
4067 /* time (relative to cluster time) */
4068 time = ((gint16) GST_READ_UINT16_BE (data));
4071 flags = GST_READ_UINT8 (data);
4075 GST_LOG_OBJECT (demux, "time %" G_GUINT64_FORMAT ", flags %d", time,
4078 switch ((flags & 0x06) >> 1) {
4079 case 0x0: /* no lacing */
4081 lace_size = g_new (gint, 1);
4082 lace_size[0] = size;
4085 case 0x1: /* xiph lacing */
4086 case 0x2: /* fixed-size lacing */
4087 case 0x3: /* EBML lacing */
4089 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4090 ("Invalid lacing size"));
4091 ret = GST_FLOW_ERROR;
4094 laces = GST_READ_UINT8 (data) + 1;
4097 lace_size = g_new0 (gint, laces);
4099 switch ((flags & 0x06) >> 1) {
4100 case 0x1: /* xiph lacing */ {
4101 guint temp, total = 0;
4103 for (n = 0; ret == GST_FLOW_OK && n < laces - 1; n++) {
4106 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4107 ("Invalid lacing size"));
4108 ret = GST_FLOW_ERROR;
4111 temp = GST_READ_UINT8 (data);
4112 lace_size[n] += temp;
4118 total += lace_size[n];
4120 lace_size[n] = size - total;
4124 case 0x2: /* fixed-size lacing */
4125 for (n = 0; n < laces; n++)
4126 lace_size[n] = size / laces;
4129 case 0x3: /* EBML lacing */ {
4132 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0) {
4133 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4135 ret = GST_FLOW_ERROR;
4140 total = lace_size[0] = num;
4141 for (n = 1; ret == GST_FLOW_OK && n < laces - 1; n++) {
4145 if ((r = gst_matroska_ebmlnum_sint (data, size, &snum)) < 0) {
4146 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4148 ret = GST_FLOW_ERROR;
4153 lace_size[n] = lace_size[n - 1] + snum;
4154 total += lace_size[n];
4157 lace_size[n] = size - total;
4164 if (stream->send_xiph_headers) {
4165 ret = gst_matroska_demux_push_xiph_codec_priv_data (demux, stream);
4166 stream->send_xiph_headers = FALSE;
4169 if (stream->send_flac_headers) {
4170 ret = gst_matroska_demux_push_flac_codec_priv_data (demux, stream);
4171 stream->send_flac_headers = FALSE;
4174 if (stream->send_speex_headers) {
4175 ret = gst_matroska_demux_push_speex_codec_priv_data (demux, stream);
4176 stream->send_speex_headers = FALSE;
4179 if (stream->send_dvd_event) {
4180 gst_matroska_demux_push_dvd_clut_change_event (demux, stream);
4181 /* FIXME: should we send this event again after (flushing) seek ? */
4182 stream->send_dvd_event = FALSE;
4185 if (ret != GST_FLOW_OK)
4192 case GST_MATROSKA_ID_BLOCKDURATION:{
4193 ret = gst_ebml_read_uint (ebml, &id, &block_duration);
4194 GST_DEBUG_OBJECT (demux, "BlockDuration: %" G_GUINT64_FORMAT,
4199 case GST_MATROSKA_ID_REFERENCEBLOCK:{
4200 ret = gst_ebml_read_sint (ebml, &id, &referenceblock);
4201 GST_DEBUG_OBJECT (demux, "ReferenceBlock: %" G_GINT64_FORMAT,
4206 case GST_MATROSKA_ID_CODECSTATE:{
4208 guint64 data_len = 0;
4211 gst_ebml_read_binary (ebml, &id, &data,
4212 &data_len)) != GST_FLOW_OK)
4215 g_free (stream->codec_state);
4216 stream->codec_state = data;
4217 stream->codec_state_size = data_len;
4219 /* Decode if necessary */
4220 if (stream->encodings && stream->encodings->len > 0
4221 && stream->codec_state && stream->codec_state_size > 0) {
4222 if (!gst_matroska_decode_data (stream->encodings,
4223 &stream->codec_state, &stream->codec_state_size,
4224 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
4225 GST_WARNING_OBJECT (demux, "Decoding codec state failed");
4229 GST_DEBUG_OBJECT (demux, "CodecState of %u bytes",
4230 stream->codec_state_size);
4235 GST_WARNING_OBJECT (demux,
4236 "Unknown BlockGroup subelement 0x%x - ignoring", id);
4239 case GST_MATROSKA_ID_BLOCKVIRTUAL:
4240 case GST_MATROSKA_ID_BLOCKADDITIONS:
4241 case GST_MATROSKA_ID_REFERENCEPRIORITY:
4242 case GST_MATROSKA_ID_REFERENCEVIRTUAL:
4243 case GST_MATROSKA_ID_SLICES:
4244 GST_DEBUG_OBJECT (demux,
4245 "Skipping BlockGroup subelement 0x%x - ignoring", id);
4246 ret = gst_ebml_read_skip (ebml);
4253 if (demux->level_up) {
4259 if (ret == GST_FLOW_OK && readblock) {
4260 guint64 duration = 0;
4261 gint64 lace_time = 0;
4263 stream = g_ptr_array_index (demux->src, stream_num);
4265 if (cluster_time != GST_CLOCK_TIME_NONE) {
4266 /* FIXME: What to do with negative timestamps? Give timestamp 0 or -1?
4267 * Drop unless the lace contains timestamp 0? */
4268 if (time < 0 && (-time) > cluster_time) {
4271 if (stream->timecodescale == 1.0)
4272 lace_time = (cluster_time + time) * demux->time_scale;
4275 gst_util_guint64_to_gdouble ((cluster_time + time) *
4276 demux->time_scale) * stream->timecodescale;
4279 lace_time = GST_CLOCK_TIME_NONE;
4282 if (block_duration) {
4283 if (stream->timecodescale == 1.0)
4284 duration = block_duration * demux->time_scale;
4287 gst_util_gdouble_to_guint64 (gst_util_guint64_to_gdouble
4288 (block_duration * demux->time_scale) * stream->timecodescale);
4289 } else if (stream->default_duration) {
4290 duration = stream->default_duration * laces;
4292 /* else duration is diff between timecode of this and next block */
4293 for (n = 0; n < laces; n++) {
4295 GstClockTimeDiff diff;
4297 sub = gst_buffer_create_sub (buf,
4298 GST_BUFFER_SIZE (buf) - size, lace_size[n]);
4299 GST_WARNING_OBJECT (demux, "created subbuffer %p", sub);
4301 if (stream->encodings != NULL && stream->encodings->len > 0)
4302 sub = gst_matroska_decode_buffer (stream, sub);
4305 GST_WARNING_OBJECT (demux, "Decoding buffer failed");
4309 GST_BUFFER_TIMESTAMP (sub) = lace_time;
4311 if (lace_time != GST_CLOCK_TIME_NONE) {
4312 demux->segment.last_stop = lace_time;
4314 diff = GST_CLOCK_DIFF (stream->pos, lace_time);
4315 if (diff < -GST_SECOND / 2 || diff > GST_SECOND / 2) {
4316 GST_DEBUG_OBJECT (demux, "Gap of %" G_GINT64_FORMAT " ns detected in"
4317 "stream %d. Sending updated NEWSEGMENT event", diff,
4319 gst_pad_push_event (stream->pad, gst_event_new_new_segment (TRUE,
4320 demux->segment.rate, GST_FORMAT_TIME, lace_time, -1,
4325 stream->pos = demux->segment.last_stop;
4327 gst_matroska_demux_sync_streams (demux);
4330 GST_BUFFER_DURATION (sub) = duration / laces;
4331 stream->pos += GST_BUFFER_DURATION (sub);
4332 demux->segment.last_stop += GST_BUFFER_DURATION (sub);
4335 if (is_simpleblock) {
4337 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
4339 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
4341 if (referenceblock) {
4342 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
4344 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
4348 if (GST_BUFFER_FLAG_IS_SET (sub, GST_BUFFER_FLAG_DELTA_UNIT)
4349 && stream->set_discont) {
4350 /* When doing seeks or such, we need to restart on key frames or
4351 * decoders might choke. */
4352 GST_DEBUG_OBJECT (demux, "skipping delta unit");
4353 gst_buffer_unref (sub);
4357 if (stream->set_discont) {
4358 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DISCONT);
4359 stream->set_discont = FALSE;
4362 GST_DEBUG_OBJECT (demux,
4363 "Pushing lace %d, data of size %d for stream %d, time=%"
4364 GST_TIME_FORMAT " and duration=%" GST_TIME_FORMAT, n,
4365 GST_BUFFER_SIZE (sub), stream_num,
4366 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (sub)),
4367 GST_TIME_ARGS (GST_BUFFER_DURATION (sub)));
4369 if (demux->element_index) {
4370 if (stream->index_writer_id == -1)
4371 gst_index_get_writer_id (demux->element_index,
4372 GST_OBJECT (stream->pad), &stream->index_writer_id);
4374 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
4375 G_GUINT64_FORMAT " for writer id %d",
4376 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (sub)), cluster_offset,
4377 stream->index_writer_id);
4378 gst_index_add_association (demux->element_index,
4379 stream->index_writer_id, GST_BUFFER_FLAG_IS_SET (sub,
4380 GST_BUFFER_FLAG_DELTA_UNIT) ? 0 : GST_ASSOCIATION_FLAG_KEY_UNIT,
4381 GST_FORMAT_TIME, GST_BUFFER_TIMESTAMP (sub), GST_FORMAT_BYTES,
4382 cluster_offset, NULL);
4385 gst_buffer_set_caps (sub, GST_PAD_CAPS (stream->pad));
4387 /* Postprocess the buffers depending on the codec used */
4388 if (stream->postprocess_frame) {
4389 GST_LOG_OBJECT (demux, "running post process");
4390 ret = stream->postprocess_frame (GST_ELEMENT (demux), stream, &sub);
4393 ret = gst_pad_push (stream->pad, sub);
4395 ret = gst_matroska_demux_combine_flows (demux, stream, ret);
4398 size -= lace_size[n];
4399 if (lace_time != GST_CLOCK_TIME_NONE && duration)
4400 lace_time += duration / laces;
4402 lace_time = GST_CLOCK_TIME_NONE;
4408 gst_buffer_unref (buf);
4414 static GstFlowReturn
4415 gst_matroska_demux_parse_cluster (GstMatroskaDemux * demux)
4417 GstEbmlRead *ebml = GST_EBML_READ (demux);
4418 GstFlowReturn ret = GST_FLOW_OK;
4419 guint64 cluster_time = GST_CLOCK_TIME_NONE;
4421 guint64 cluster_offset = demux->parent.offset;
4423 DEBUG_ELEMENT_START (demux, ebml, "Cluster");
4425 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
4426 DEBUG_ELEMENT_STOP (demux, ebml, "Cluster", ret);
4430 while (ret == GST_FLOW_OK) {
4431 if ((ret = gst_ebml_peek_id (ebml, &demux->level_up, &id)) != GST_FLOW_OK)
4434 if (demux->level_up) {
4440 /* cluster timecode */
4441 case GST_MATROSKA_ID_CLUSTERTIMECODE:
4445 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
4448 GST_DEBUG_OBJECT (demux, "ClusterTimeCode: %" G_GUINT64_FORMAT, num);
4453 /* a group of blocks inside a cluster */
4454 case GST_MATROSKA_ID_BLOCKGROUP:
4455 DEBUG_ELEMENT_START (demux, ebml, "BlockGroup");
4456 if ((ret = gst_ebml_read_master (ebml, &id)) == GST_FLOW_OK) {
4457 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4458 cluster_time, cluster_offset, FALSE);
4460 DEBUG_ELEMENT_STOP (demux, ebml, "BlockGroup", ret);
4463 case GST_MATROSKA_ID_SIMPLEBLOCK:
4465 DEBUG_ELEMENT_START (demux, ebml, "SimpleBlock");
4466 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4467 cluster_time, cluster_offset, TRUE);
4468 DEBUG_ELEMENT_STOP (demux, ebml, "SimpleBlock", ret);
4473 GST_WARNING ("Unknown Cluster subelement 0x%x - ignoring", id);
4475 case GST_MATROSKA_ID_POSITION:
4476 case GST_MATROSKA_ID_PREVSIZE:
4477 case GST_MATROSKA_ID_ENCRYPTEDBLOCK:
4478 case GST_MATROSKA_ID_SILENTTRACKS:
4479 GST_DEBUG ("Skipping Cluster subelement 0x%x - ignoring", id);
4480 ret = gst_ebml_read_skip (ebml);
4484 if (demux->level_up) {
4490 if (demux->element_index) {
4491 if (demux->element_index_writer_id == -1)
4492 gst_index_get_writer_id (demux->element_index,
4493 GST_OBJECT (demux), &demux->element_index_writer_id);
4495 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
4496 G_GUINT64_FORMAT " for writer id %d",
4497 GST_TIME_ARGS (cluster_time), cluster_offset,
4498 demux->element_index_writer_id);
4499 gst_index_add_association (demux->element_index,
4500 demux->element_index_writer_id, GST_ASSOCIATION_FLAG_KEY_UNIT,
4501 GST_FORMAT_TIME, cluster_time, GST_FORMAT_BYTES, cluster_offset, NULL);
4504 DEBUG_ELEMENT_STOP (demux, ebml, "Cluster", ret);
4509 static GstFlowReturn
4510 gst_matroska_demux_parse_contents_seekentry (GstMatroskaDemux * demux)
4512 GstEbmlRead *ebml = GST_EBML_READ (demux);
4514 guint64 seek_pos = (guint64) - 1;
4515 guint32 seek_id = 0;
4518 DEBUG_ELEMENT_START (demux, ebml, "Seek");
4520 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
4521 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
4525 while (ret == GST_FLOW_OK) {
4526 if ((ret = gst_ebml_peek_id (ebml, &demux->level_up, &id)) != GST_FLOW_OK)
4529 if (demux->level_up) {
4535 case GST_MATROSKA_ID_SEEKID:
4539 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
4542 GST_DEBUG_OBJECT (demux, "SeekID: %" G_GUINT64_FORMAT, t);
4547 case GST_MATROSKA_ID_SEEKPOSITION:
4551 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
4554 if (t > G_MAXINT64) {
4555 GST_WARNING_OBJECT (demux,
4556 "Too large SeekPosition %" G_GUINT64_FORMAT, t);
4560 GST_DEBUG_OBJECT (demux, "SeekPosition: %" G_GUINT64_FORMAT, t);
4566 GST_WARNING_OBJECT (demux,
4567 "Unknown SeekHead subelement 0x%x - ignoring", id);
4568 ret = gst_ebml_read_skip (ebml);
4572 if (demux->level_up) {
4578 if (ret != GST_FLOW_OK && ret != GST_FLOW_UNEXPECTED)
4581 if (!seek_id || seek_pos == (guint64) - 1) {
4582 GST_WARNING_OBJECT (demux, "Incomplete seekhead entry (0x%x/%"
4583 G_GUINT64_FORMAT ")", seek_id, seek_pos);
4588 case GST_MATROSKA_ID_CUES:
4589 case GST_MATROSKA_ID_TAGS:
4590 case GST_MATROSKA_ID_TRACKS:
4591 case GST_MATROSKA_ID_SEEKHEAD:
4592 case GST_MATROSKA_ID_SEGMENTINFO:
4593 case GST_MATROSKA_ID_ATTACHMENTS:
4594 case GST_MATROSKA_ID_CHAPTERS:
4596 guint level_up = demux->level_up;
4597 guint64 before_pos, length;
4598 GstEbmlLevel *level;
4601 length = gst_ebml_read_get_length (ebml);
4602 before_pos = ebml->offset;
4604 /* check for validity */
4605 if (seek_pos + demux->ebml_segment_start + 12 >= length) {
4606 GST_WARNING_OBJECT (demux,
4607 "SeekHead reference lies outside file!" " (%"
4608 G_GUINT64_FORMAT "+%" G_GUINT64_FORMAT "+12 >= %"
4609 G_GUINT64_FORMAT ")", seek_pos, demux->ebml_segment_start, length);
4614 if (gst_ebml_read_seek (ebml, seek_pos + demux->ebml_segment_start) !=
4618 /* we don't want to lose our seekhead level, so we add
4619 * a dummy. This is a crude hack. */
4620 level = g_slice_new (GstEbmlLevel);
4622 level->length = G_MAXUINT64;
4623 ebml->level = g_list_prepend (ebml->level, level);
4626 if ((ret = gst_ebml_peek_id (ebml, &demux->level_up, &id)) != GST_FLOW_OK)
4629 if (id != seek_id) {
4630 GST_WARNING_OBJECT (demux,
4631 "We looked for ID=0x%x but got ID=0x%x (pos=%" G_GUINT64_FORMAT ")",
4632 seek_id, id, seek_pos + demux->ebml_segment_start);
4636 /* read master + parse */
4638 case GST_MATROSKA_ID_CUES:
4639 if (!demux->index_parsed) {
4640 ret = gst_matroska_demux_parse_index (demux);
4643 case GST_MATROSKA_ID_TAGS:
4644 ret = gst_matroska_demux_parse_metadata (demux);
4646 case GST_MATROSKA_ID_TRACKS:
4647 if (!demux->tracks_parsed) {
4648 ret = gst_matroska_demux_parse_tracks (demux);
4652 case GST_MATROSKA_ID_SEGMENTINFO:
4653 if (!demux->segmentinfo_parsed) {
4654 ret = gst_matroska_demux_parse_info (demux);
4657 case GST_MATROSKA_ID_SEEKHEAD:
4661 DEBUG_ELEMENT_START (demux, ebml, "SeekHead");
4662 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
4665 /* Prevent infinite recursion if there's a cycle from
4666 * one seekhead to the same again. Simply break if
4667 * we already had this seekhead, finish will clean up
4669 for (l = ebml->level; l; l = l->next) {
4670 GstEbmlLevel *level = (GstEbmlLevel *) l->data;
4672 if (level->start == ebml->offset && l->prev)
4676 ret = gst_matroska_demux_parse_contents (demux);
4679 case GST_MATROSKA_ID_ATTACHMENTS:
4680 if (!demux->attachments_parsed) {
4681 ret = gst_matroska_demux_parse_attachments (demux);
4684 case GST_MATROSKA_ID_CHAPTERS:
4685 ret = gst_matroska_demux_parse_chapters (demux);
4690 /* remove dummy level */
4691 while (ebml->level) {
4694 level = ebml->level->data;
4695 ebml->level = g_list_delete_link (ebml->level, ebml->level);
4696 length = level->length;
4697 g_slice_free (GstEbmlLevel, level);
4698 if (length == G_MAXUINT64)
4703 (void) gst_ebml_read_seek (ebml, before_pos);
4704 demux->level_up = level_up;
4709 GST_DEBUG_OBJECT (demux, "Ignoring Seek entry for ID=0x%x", seek_id);
4712 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
4717 static GstFlowReturn
4718 gst_matroska_demux_parse_contents (GstMatroskaDemux * demux)
4720 GstEbmlRead *ebml = GST_EBML_READ (demux);
4721 GstFlowReturn ret = GST_FLOW_OK;
4724 while (ret == GST_FLOW_OK) {
4725 if ((ret = gst_ebml_peek_id (ebml, &demux->level_up, &id)) != GST_FLOW_OK)
4728 if (demux->level_up) {
4734 case GST_MATROSKA_ID_SEEKENTRY:
4736 ret = gst_matroska_demux_parse_contents_seekentry (demux);
4737 /* Ignore EOS and errors here */
4738 if (ret != GST_FLOW_OK) {
4739 GST_DEBUG_OBJECT (demux, "Ignoring %s", gst_flow_get_name (ret));
4746 GST_WARNING ("Unknown SeekHead subelement 0x%x - ignoring", id);
4747 ret = gst_ebml_read_skip (ebml);
4751 if (demux->level_up) {
4757 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
4762 /* returns FALSE on error, otherwise TRUE */
4763 static GstFlowReturn
4764 gst_matroska_demux_loop_stream_parse_id (GstMatroskaDemux * demux,
4765 guint32 id, gboolean * p_run_loop)
4767 GstEbmlRead *ebml = GST_EBML_READ (demux);
4768 GstFlowReturn ret = GST_FLOW_OK;
4772 * Can exist more than once but following occurences
4773 * must have the same content so ignore them */
4774 case GST_MATROSKA_ID_SEGMENTINFO:
4775 if (!demux->segmentinfo_parsed) {
4776 if ((ret = gst_matroska_demux_parse_info (demux)) != GST_FLOW_OK)
4779 if ((ret = gst_ebml_read_skip (ebml)) != GST_FLOW_OK)
4784 /* track info headers
4785 * Can exist more than once but following occurences
4786 * must have the same content so ignore them */
4787 case GST_MATROSKA_ID_TRACKS:
4789 if (!demux->tracks_parsed) {
4790 if ((ret = gst_matroska_demux_parse_tracks (demux)) != GST_FLOW_OK)
4793 if ((ret = gst_ebml_read_skip (ebml)) != GST_FLOW_OK)
4799 /* cues - seek table
4800 * Either exists exactly one time or never but ignore
4801 * following occurences for the sake of sanity */
4802 case GST_MATROSKA_ID_CUES:
4804 if (!demux->index_parsed) {
4805 if ((ret = gst_matroska_demux_parse_index (demux)) != GST_FLOW_OK)
4808 if ((ret = gst_ebml_read_skip (ebml)) != GST_FLOW_OK)
4815 * can exist more than one time with different content */
4816 case GST_MATROSKA_ID_TAGS:
4818 if ((ret = gst_matroska_demux_parse_metadata (demux)) != GST_FLOW_OK)
4823 /* file index (if seekable, seek to Cues/Tags/etc to parse it) */
4824 case GST_MATROSKA_ID_SEEKHEAD:
4826 DEBUG_ELEMENT_START (demux, ebml, "SeekHead");
4827 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
4829 if ((ret = gst_matroska_demux_parse_contents (demux)) != GST_FLOW_OK)
4834 /* cluster - contains the payload */
4835 case GST_MATROSKA_ID_CLUSTER:
4837 if (demux->state != GST_MATROSKA_DEMUX_STATE_DATA) {
4838 /* We need a Tracks element first before we can output anything.
4841 if (!demux->tracks_parsed) {
4842 GstEbmlLevel *level;
4847 GST_WARNING_OBJECT (demux,
4848 "Found Cluster element before Tracks, searching Tracks");
4851 level_up = demux->level_up;
4852 before_pos = ebml->offset;
4854 /* we don't want to lose our seekhead level, so we add
4855 * a dummy. This is a crude hack. */
4857 level = g_slice_new (GstEbmlLevel);
4859 level->length = G_MAXUINT64;
4860 ebml->level = g_list_prepend (ebml->level, level);
4862 /* Search Tracks element */
4864 if (gst_ebml_read_skip (ebml) != GST_FLOW_OK)
4867 if (gst_ebml_peek_id (ebml, &demux->level_up, &iid) != GST_FLOW_OK)
4870 if (iid != GST_MATROSKA_ID_TRACKS)
4873 gst_matroska_demux_parse_tracks (demux);
4877 if (!demux->tracks_parsed) {
4878 GST_ERROR_OBJECT (demux, "No Tracks element found");
4879 ret = GST_FLOW_ERROR;
4882 /* remove dummy level */
4883 while (ebml->level) {
4886 level = ebml->level->data;
4887 ebml->level = g_list_delete_link (ebml->level, ebml->level);
4888 length = level->length;
4889 g_slice_free (GstEbmlLevel, level);
4890 if (length == G_MAXUINT64)
4895 gst_ebml_read_seek (ebml, before_pos);
4896 demux->level_up = level_up;
4899 if (ret != GST_FLOW_OK)
4902 demux->state = GST_MATROSKA_DEMUX_STATE_DATA;
4903 /* send initial discont */
4904 gst_matroska_demux_send_event (demux,
4905 gst_event_new_new_segment (FALSE, 1.0,
4907 (demux->segment.duration > 0) ? demux->segment.duration : -1,
4909 GST_DEBUG_OBJECT (demux, "signaling no more pads");
4910 gst_element_no_more_pads (GST_ELEMENT (demux));
4912 /* The idea is that we parse one cluster per loop and
4913 * then break out of the loop here. In the next call
4914 * of the loopfunc, we will get back here with the
4915 * next cluster. If an error occurs, we didn't
4916 * actually push a buffer, but we still want to break
4917 * out of the loop to handle a possible error. We'll
4918 * get back here if it's recoverable. */
4919 if ((ret = gst_matroska_demux_parse_cluster (demux)) != GST_FLOW_OK)
4921 *p_run_loop = FALSE;
4926 /* attachments - contains files attached to the mkv container
4927 * like album art, etc */
4928 case GST_MATROSKA_ID_ATTACHMENTS:{
4929 if (!demux->attachments_parsed) {
4930 if ((ret = gst_matroska_demux_parse_attachments (demux)) != GST_FLOW_OK)
4933 if ((ret = gst_ebml_read_skip (ebml)) != GST_FLOW_OK)
4939 /* chapters - contains meta information about how to group
4940 * the file into chapters, similar to DVD */
4941 case GST_MATROSKA_ID_CHAPTERS:{
4942 if ((ret = gst_matroska_demux_parse_chapters (demux)) != GST_FLOW_OK)
4948 GST_WARNING_OBJECT (demux, "Unknown Segment subelement 0x%x at %"
4949 G_GUINT64_FORMAT " - ignoring", id, GST_EBML_READ (demux)->offset);
4950 if ((ret = gst_ebml_read_skip (ebml)) != GST_FLOW_OK)
4957 static GstFlowReturn
4958 gst_matroska_demux_loop_stream (GstMatroskaDemux * demux)
4960 GstEbmlRead *ebml = GST_EBML_READ (demux);
4961 GstFlowReturn ret = GST_FLOW_OK;
4962 gboolean run_loop = TRUE;
4965 /* we've found our segment, start reading the different contents in here */
4966 while (run_loop && ret == GST_FLOW_OK) {
4967 if ((ret = gst_ebml_peek_id (ebml, &demux->level_up, &id)) != GST_FLOW_OK)
4970 if (demux->level_up) {
4975 ret = gst_matroska_demux_loop_stream_parse_id (demux, id, &run_loop);
4977 if (demux->level_up) {
4986 gst_matroska_demux_loop (GstPad * pad)
4988 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (pad));
4989 GstEbmlRead *ebml = GST_EBML_READ (demux);
4992 /* first, if we're to start, let's actually get starting */
4993 if (demux->state == GST_MATROSKA_DEMUX_STATE_START) {
4994 ret = gst_matroska_demux_init_stream (demux);
4995 if (ret != GST_FLOW_OK) {
4996 GST_WARNING_OBJECT (demux, "init stream failed!");
4999 demux->state = GST_MATROSKA_DEMUX_STATE_HEADER;
5002 /* If we have to close a segment are send a new segment do
5005 if (demux->state == GST_MATROSKA_DEMUX_STATE_DATA) {
5006 if (demux->close_segment) {
5007 gst_matroska_demux_send_event (demux, demux->close_segment);
5008 demux->close_segment = NULL;
5010 if (demux->new_segment) {
5011 gst_matroska_demux_send_event (demux, demux->new_segment);
5012 demux->new_segment = NULL;
5016 ret = gst_matroska_demux_loop_stream (demux);
5017 if (ret != GST_FLOW_OK)
5020 /* check if we're at the end of a configured segment */
5021 if (GST_CLOCK_TIME_IS_VALID (demux->segment.stop)) {
5024 g_assert (demux->num_streams == demux->src->len);
5025 for (i = 0; i < demux->src->len; i++) {
5026 GstMatroskaTrackContext *context = g_ptr_array_index (demux->src, i);
5027 if (context->pos >= demux->segment.stop) {
5028 GST_INFO_OBJECT (demux, "Reached end of segment (%" G_GUINT64_FORMAT
5029 "-%" G_GUINT64_FORMAT ") on pad %s:%s", demux->segment.start,
5030 demux->segment.stop, GST_DEBUG_PAD_NAME (context->pad));
5031 ret = GST_FLOW_UNEXPECTED;
5037 if (ebml->offset == gst_ebml_read_get_length (ebml)) {
5038 GST_LOG_OBJECT (demux, "Reached end of stream, sending EOS");
5039 ret = GST_FLOW_UNEXPECTED;
5048 const gchar *reason = gst_flow_get_name (ret);
5050 GST_LOG_OBJECT (demux, "pausing task, reason %s", reason);
5051 demux->segment_running = FALSE;
5052 gst_pad_pause_task (demux->sinkpad);
5054 if (GST_FLOW_IS_FATAL (ret) || ret == GST_FLOW_NOT_LINKED) {
5055 if (ret == GST_FLOW_UNEXPECTED) {
5056 /* perform EOS logic */
5057 if (demux->segment.flags & GST_SEEK_FLAG_SEGMENT) {
5060 /* for segment playback we need to post when (in stream time)
5061 * we stopped, this is either stop (when set) or the duration. */
5062 if ((stop = demux->segment.stop) == -1)
5063 stop = demux->segment.duration;
5065 GST_LOG_OBJECT (demux, "Sending segment done, at end of segment");
5066 gst_element_post_message (GST_ELEMENT (demux),
5067 gst_message_new_segment_done (GST_OBJECT (demux), GST_FORMAT_TIME,
5070 /* normal playback, send EOS to all linked pads */
5071 GST_LOG_OBJECT (demux, "Sending EOS, at end of stream");
5072 gst_matroska_demux_send_event (demux, gst_event_new_eos ());
5075 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
5076 ("stream stopped, reason %s", reason));
5077 gst_matroska_demux_send_event (demux, gst_event_new_eos ());
5085 gst_matroska_demux_sink_activate (GstPad * sinkpad)
5087 if (gst_pad_check_pull_range (sinkpad))
5088 return gst_pad_activate_pull (sinkpad, TRUE);
5094 gst_matroska_demux_sink_activate_pull (GstPad * sinkpad, gboolean active)
5096 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (sinkpad));
5099 /* if we have a scheduler we can start the task */
5100 demux->segment_running = TRUE;
5101 gst_pad_start_task (sinkpad, (GstTaskFunction) gst_matroska_demux_loop,
5104 demux->segment_running = FALSE;
5105 gst_pad_stop_task (sinkpad);
5112 gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext *
5113 videocontext, const gchar * codec_id, guint8 * data, guint size,
5114 gchar ** codec_name)
5116 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) videocontext;
5117 GstCaps *caps = NULL;
5119 g_assert (videocontext != NULL);
5120 g_assert (codec_name != NULL);
5122 context->send_xiph_headers = FALSE;
5123 context->send_flac_headers = FALSE;
5124 context->send_speex_headers = FALSE;
5126 /* TODO: check if we have all codec types from matroska-ids.h
5127 * check if we have to do more special things with codec_private
5130 * GST_MATROSKA_CODEC_ID_VIDEO_QUICKTIME
5131 * GST_MATROSKA_CODEC_ID_VIDEO_SNOW
5134 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VFW_FOURCC)) {
5135 gst_riff_strf_vids *vids = NULL;
5138 GstBuffer *buf = NULL;
5140 vids = (gst_riff_strf_vids *) data;
5142 /* assure size is big enough */
5144 GST_WARNING ("Too small BITMAPINFOHEADER (%d bytes)", size);
5147 if (size < sizeof (gst_riff_strf_vids)) {
5148 vids = g_new (gst_riff_strf_vids, 1);
5149 memcpy (vids, data, size);
5152 /* little-endian -> byte-order */
5153 vids->size = GUINT32_FROM_LE (vids->size);
5154 vids->width = GUINT32_FROM_LE (vids->width);
5155 vids->height = GUINT32_FROM_LE (vids->height);
5156 vids->planes = GUINT16_FROM_LE (vids->planes);
5157 vids->bit_cnt = GUINT16_FROM_LE (vids->bit_cnt);
5158 vids->compression = GUINT32_FROM_LE (vids->compression);
5159 vids->image_size = GUINT32_FROM_LE (vids->image_size);
5160 vids->xpels_meter = GUINT32_FROM_LE (vids->xpels_meter);
5161 vids->ypels_meter = GUINT32_FROM_LE (vids->ypels_meter);
5162 vids->num_colors = GUINT32_FROM_LE (vids->num_colors);
5163 vids->imp_colors = GUINT32_FROM_LE (vids->imp_colors);
5165 if (size > sizeof (gst_riff_strf_vids)) { /* some extra_data */
5166 buf = gst_buffer_new_and_alloc (size - sizeof (gst_riff_strf_vids));
5167 memcpy (GST_BUFFER_DATA (buf),
5168 (guint8 *) vids + sizeof (gst_riff_strf_vids),
5169 GST_BUFFER_SIZE (buf));
5172 caps = gst_riff_create_video_caps (vids->compression, NULL, vids,
5173 buf, NULL, codec_name);
5176 gst_buffer_unref (buf);
5178 if (vids != (gst_riff_strf_vids *) data)
5181 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_UNCOMPRESSED)) {
5184 switch (videocontext->fourcc) {
5185 case GST_MAKE_FOURCC ('I', '4', '2', '0'):
5186 *codec_name = g_strdup ("Raw planar YUV 4:2:0");
5187 fourcc = videocontext->fourcc;
5189 case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
5190 *codec_name = g_strdup ("Raw packed YUV 4:2:2");
5191 fourcc = videocontext->fourcc;
5193 case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
5194 *codec_name = g_strdup ("Raw packed YUV 4:2:0");
5195 fourcc = videocontext->fourcc;
5197 case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
5198 *codec_name = g_strdup ("Raw packed YUV 4:2:2");
5199 fourcc = videocontext->fourcc;
5201 case GST_MAKE_FOURCC ('A', 'Y', 'U', 'V'):
5202 *codec_name = g_strdup ("Raw packed YUV 4:4:4 with alpha channel");
5203 fourcc = videocontext->fourcc;
5207 GST_DEBUG ("Unknown fourcc %" GST_FOURCC_FORMAT,
5208 GST_FOURCC_ARGS (videocontext->fourcc));
5212 caps = gst_caps_new_simple ("video/x-raw-yuv",
5213 "format", GST_TYPE_FOURCC, fourcc, NULL);
5214 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_SP)) {
5215 caps = gst_caps_new_simple ("video/x-divx",
5216 "divxversion", G_TYPE_INT, 4, NULL);
5217 *codec_name = g_strdup ("MPEG-4 simple profile");
5218 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP) ||
5219 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AP)) {
5221 caps = gst_caps_new_full (gst_structure_new ("video/x-divx",
5222 "divxversion", G_TYPE_INT, 5, NULL),
5223 gst_structure_new ("video/x-xvid", NULL),
5224 gst_structure_new ("video/mpeg",
5225 "mpegversion", G_TYPE_INT, 4,
5226 "systemstream", G_TYPE_BOOLEAN, FALSE, NULL), NULL);
5228 caps = gst_caps_new_simple ("video/mpeg",
5229 "mpegversion", G_TYPE_INT, 4,
5230 "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
5232 GstBuffer *priv = gst_buffer_new_and_alloc (size);
5234 memcpy (GST_BUFFER_DATA (priv), data, size);
5235 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5236 gst_buffer_unref (priv);
5238 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP))
5239 *codec_name = g_strdup ("MPEG-4 advanced simple profile");
5241 *codec_name = g_strdup ("MPEG-4 advanced profile");
5242 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MSMPEG4V3)) {
5244 caps = gst_caps_new_full (gst_structure_new ("video/x-divx",
5245 "divxversion", G_TYPE_INT, 3, NULL),
5246 gst_structure_new ("video/x-msmpeg",
5247 "msmpegversion", G_TYPE_INT, 43, NULL), NULL);
5249 caps = gst_caps_new_simple ("video/x-msmpeg",
5250 "msmpegversion", G_TYPE_INT, 43, NULL);
5251 *codec_name = g_strdup ("Microsoft MPEG-4 v.3");
5252 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1) ||
5253 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG2)) {
5254 gint mpegversion = -1;
5256 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1))
5258 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG2))
5261 g_assert_not_reached ();
5263 caps = gst_caps_new_simple ("video/mpeg",
5264 "systemstream", G_TYPE_BOOLEAN, FALSE,
5265 "mpegversion", G_TYPE_INT, mpegversion, NULL);
5266 *codec_name = g_strdup_printf ("MPEG-%d video", mpegversion);
5267 context->postprocess_frame = gst_matroska_demux_add_mpeg_seq_header;
5268 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MJPEG)) {
5269 caps = gst_caps_new_simple ("image/jpeg", NULL);
5270 *codec_name = g_strdup ("Motion-JPEG");
5271 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AVC)) {
5272 caps = gst_caps_new_simple ("video/x-h264", NULL);
5274 GstBuffer *priv = gst_buffer_new_and_alloc (size);
5276 memcpy (GST_BUFFER_DATA (priv), data, size);
5277 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5278 gst_buffer_unref (priv);
5281 *codec_name = g_strdup ("H264");
5282 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1)) ||
5283 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2)) ||
5284 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3)) ||
5285 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))) {
5286 gint rmversion = -1;
5288 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1))
5290 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2))
5292 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3))
5294 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))
5297 caps = gst_caps_new_simple ("video/x-pn-realvideo",
5298 "rmversion", G_TYPE_INT, rmversion, NULL);
5299 GST_DEBUG ("data:%p, size:0x%x", data, size);
5300 /* We need to extract the extradata ! */
5301 if (data && (size >= 0x22)) {
5306 subformat = GST_READ_UINT32_BE (data + 0x1a);
5307 rformat = GST_READ_UINT32_BE (data + 0x1e);
5309 priv = gst_buffer_new_and_alloc (size - 0x1a);
5311 memcpy (GST_BUFFER_DATA (priv), data + 0x1a, size - 0x1a);
5312 gst_caps_set_simple (caps,
5313 "codec_data", GST_TYPE_BUFFER, priv,
5314 "format", G_TYPE_INT, rformat,
5315 "subformat", G_TYPE_INT, subformat, NULL);
5316 gst_buffer_unref (priv);
5319 *codec_name = g_strdup_printf ("RealVideo %d.0", rmversion);
5320 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_THEORA)) {
5321 caps = gst_caps_new_simple ("video/x-theora", NULL);
5322 context->send_xiph_headers = TRUE;
5323 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_DIRAC)) {
5324 caps = gst_caps_new_simple ("video/x-dirac", NULL);
5325 context->send_xiph_headers = FALSE;
5327 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
5333 GstStructure *structure;
5335 for (i = 0; i < gst_caps_get_size (caps); i++) {
5336 structure = gst_caps_get_structure (caps, i);
5338 /* FIXME: use the real unit here! */
5339 GST_DEBUG ("video size %dx%d, target display size %dx%d (any unit)",
5340 videocontext->pixel_width,
5341 videocontext->pixel_height,
5342 videocontext->display_width, videocontext->display_height);
5344 /* pixel width and height are the w and h of the video in pixels */
5345 if (videocontext->pixel_width > 0 && videocontext->pixel_height > 0) {
5346 gint w = videocontext->pixel_width;
5348 gint h = videocontext->pixel_height;
5350 gst_structure_set (structure,
5351 "width", G_TYPE_INT, w, "height", G_TYPE_INT, h, NULL);
5354 if (videocontext->display_width > 0 && videocontext->display_height > 0) {
5357 /* calculate the pixel aspect ratio using the display and pixel w/h */
5358 n = videocontext->display_width * videocontext->pixel_height;
5359 d = videocontext->display_height * videocontext->pixel_width;
5360 GST_DEBUG ("setting PAR to %d/%d", n, d);
5361 gst_structure_set (structure, "pixel-aspect-ratio",
5363 videocontext->display_width * videocontext->pixel_height,
5364 videocontext->display_height * videocontext->pixel_width, NULL);
5367 if (videocontext->default_fps > 0.0) {
5368 GValue fps_double = { 0, };
5369 GValue fps_fraction = { 0, };
5371 g_value_init (&fps_double, G_TYPE_DOUBLE);
5372 g_value_init (&fps_fraction, GST_TYPE_FRACTION);
5373 g_value_set_double (&fps_double, videocontext->default_fps);
5374 g_value_transform (&fps_double, &fps_fraction);
5376 GST_DEBUG ("using default fps %f", videocontext->default_fps);
5378 gst_structure_set_value (structure, "framerate", &fps_fraction);
5379 g_value_unset (&fps_double);
5380 g_value_unset (&fps_fraction);
5381 } else if (context->default_duration > 0) {
5382 GValue fps_double = { 0, };
5383 GValue fps_fraction = { 0, };
5385 g_value_init (&fps_double, G_TYPE_DOUBLE);
5386 g_value_init (&fps_fraction, GST_TYPE_FRACTION);
5387 g_value_set_double (&fps_double, (gdouble) GST_SECOND /
5388 gst_guint64_to_gdouble (context->default_duration));
5389 g_value_transform (&fps_double, &fps_fraction);
5391 GST_DEBUG ("using default duration %" G_GUINT64_FORMAT,
5392 context->default_duration);
5394 gst_structure_set_value (structure, "framerate", &fps_fraction);
5395 g_value_unset (&fps_double);
5396 g_value_unset (&fps_fraction);
5398 /* sort of a hack to get most codecs to support,
5399 * even if the default_duration is missing */
5400 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
5405 gst_caps_do_simplify (caps);
5412 * Some AAC specific code... *sigh*
5413 * FIXME: maybe we should use '15' and code the sample rate explicitly
5414 * if the sample rate doesn't match the predefined rates exactly? (tpm)
5418 aac_rate_idx (gint rate)
5422 else if (75132 <= rate)
5424 else if (55426 <= rate)
5426 else if (46009 <= rate)
5428 else if (37566 <= rate)
5430 else if (27713 <= rate)
5432 else if (23004 <= rate)
5434 else if (18783 <= rate)
5436 else if (13856 <= rate)
5438 else if (11502 <= rate)
5440 else if (9391 <= rate)
5447 aac_profile_idx (const gchar * codec_id)
5451 if (strlen (codec_id) <= 12)
5453 else if (!strncmp (&codec_id[12], "MAIN", 4))
5455 else if (!strncmp (&codec_id[12], "LC", 2))
5457 else if (!strncmp (&codec_id[12], "SSR", 3))
5465 #define AAC_SYNC_EXTENSION_TYPE 0x02b7
5468 gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext *
5469 audiocontext, const gchar * codec_id, guint8 * data, guint size,
5470 gchar ** codec_name)
5472 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) audiocontext;
5473 GstCaps *caps = NULL;
5475 g_assert (audiocontext != NULL);
5476 g_assert (codec_name != NULL);
5478 context->send_xiph_headers = FALSE;
5479 context->send_flac_headers = FALSE;
5480 context->send_speex_headers = FALSE;
5482 /* TODO: check if we have all codec types from matroska-ids.h
5483 * check if we have to do more special things with codec_private
5484 * check if we need bitdepth in different places too
5485 * implement channel position magic
5487 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID9
5488 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID10
5489 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDMC
5490 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDM2
5493 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1) ||
5494 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2) ||
5495 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L3)) {
5498 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1))
5500 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2))
5502 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L3))
5505 g_assert_not_reached ();
5507 caps = gst_caps_new_simple ("audio/mpeg",
5508 "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, layer, NULL);
5509 *codec_name = g_strdup_printf ("MPEG-1 layer %d", layer);
5510 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE) ||
5511 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_LE)) {
5512 gint endianness = -1;
5514 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE))
5515 endianness = G_BIG_ENDIAN;
5516 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_LE))
5517 endianness = G_LITTLE_ENDIAN;
5519 g_assert_not_reached ();
5521 caps = gst_caps_new_simple ("audio/x-raw-int",
5522 "width", G_TYPE_INT, audiocontext->bitdepth,
5523 "depth", G_TYPE_INT, audiocontext->bitdepth,
5524 "signed", G_TYPE_BOOLEAN, audiocontext->bitdepth != 8,
5525 "endianness", G_TYPE_INT, endianness, NULL);
5527 *codec_name = g_strdup_printf ("Raw %d-bit PCM audio",
5528 audiocontext->bitdepth);
5529 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_FLOAT)) {
5530 caps = gst_caps_new_simple ("audio/x-raw-float",
5531 "endianness", G_TYPE_INT, G_LITTLE_ENDIAN,
5532 "width", G_TYPE_INT, audiocontext->bitdepth, NULL);
5533 *codec_name = g_strdup_printf ("Raw %d-bit floating-point audio",
5534 audiocontext->bitdepth);
5535 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AC3,
5536 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AC3))) {
5537 caps = gst_caps_new_simple ("audio/x-ac3", NULL);
5538 *codec_name = g_strdup ("AC-3 audio");
5539 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_EAC3,
5540 strlen (GST_MATROSKA_CODEC_ID_AUDIO_EAC3))) {
5541 caps = gst_caps_new_simple ("audio/x-eac3", NULL);
5542 *codec_name = g_strdup ("E-AC-3 audio");
5543 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_DTS)) {
5544 caps = gst_caps_new_simple ("audio/x-dts", NULL);
5545 *codec_name = g_strdup ("DTS audio");
5546 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_VORBIS)) {
5547 caps = gst_caps_new_simple ("audio/x-vorbis", NULL);
5548 context->send_xiph_headers = TRUE;
5549 /* vorbis decoder does tags */
5550 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_FLAC)) {
5551 caps = gst_caps_new_simple ("audio/x-flac", NULL);
5552 context->send_flac_headers = TRUE;
5553 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_SPEEX)) {
5554 caps = gst_caps_new_simple ("audio/x-speex", NULL);
5555 context->send_speex_headers = TRUE;
5556 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_ACM)) {
5557 gst_riff_strf_auds auds;
5560 GstBuffer *codec_data = gst_buffer_new ();
5562 /* little-endian -> byte-order */
5563 auds.format = GST_READ_UINT16_LE (data);
5564 auds.channels = GST_READ_UINT16_LE (data + 2);
5565 auds.rate = GST_READ_UINT32_LE (data + 4);
5566 auds.av_bps = GST_READ_UINT32_LE (data + 8);
5567 auds.blockalign = GST_READ_UINT16_LE (data + 12);
5568 auds.size = GST_READ_UINT16_LE (data + 16);
5570 /* 18 is the waveformatex size */
5571 gst_buffer_set_data (codec_data, data + 18, auds.size);
5573 caps = gst_riff_create_audio_caps (auds.format, NULL, &auds, NULL,
5574 codec_data, codec_name);
5575 gst_buffer_unref (codec_data);
5577 } else if (g_str_has_prefix (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC)) {
5578 GstBuffer *priv = NULL;
5579 gint mpegversion = -1;
5580 gint rate_idx, profile;
5581 guint8 *data = NULL;
5583 /* unspecified AAC profile with opaque private codec data */
5584 if (strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC) == 0) {
5585 if (context->codec_priv_size >= 2) {
5586 guint obj_type, freq_index, explicit_freq_bytes = 0;
5588 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
5589 freq_index = (GST_READ_UINT16_BE (context->codec_priv) & 0x780) >> 7;
5590 obj_type = (GST_READ_UINT16_BE (context->codec_priv) & 0xF800) >> 11;
5591 if (freq_index == 15)
5592 explicit_freq_bytes = 3;
5593 GST_DEBUG ("obj_type = %u, freq_index = %u", obj_type, freq_index);
5594 priv = gst_buffer_new_and_alloc (context->codec_priv_size);
5595 memcpy (GST_BUFFER_DATA (priv), context->codec_priv,
5596 context->codec_priv_size);
5597 /* assume SBR if samplerate <= 24kHz */
5598 if (obj_type == 5 || (freq_index >= 6 && freq_index != 15) ||
5599 (context->codec_priv_size == (5 + explicit_freq_bytes))) {
5600 audiocontext->samplerate *= 2;
5603 GST_WARNING ("Opaque A_AAC codec ID, but no codec private data");
5604 /* just try this and see what happens ... */
5605 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
5609 /* make up decoder-specific data if it is not supplied */
5611 priv = gst_buffer_new_and_alloc (5);
5612 data = GST_BUFFER_DATA (priv);
5613 rate_idx = aac_rate_idx (audiocontext->samplerate);
5614 profile = aac_profile_idx (codec_id);
5616 data[0] = ((profile + 1) << 3) | ((rate_idx & 0xE) >> 1);
5617 data[1] = ((rate_idx & 0x1) << 7) | (audiocontext->channels << 3);
5618 GST_BUFFER_SIZE (priv) = 2;
5621 if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2,
5622 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2))) {
5624 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4,
5625 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4))) {
5628 if (g_strrstr (codec_id, "SBR")) {
5629 /* HE-AAC (aka SBR AAC) */
5630 audiocontext->samplerate *= 2;
5631 rate_idx = aac_rate_idx (audiocontext->samplerate);
5632 data[2] = AAC_SYNC_EXTENSION_TYPE >> 3;
5633 data[3] = ((AAC_SYNC_EXTENSION_TYPE & 0x07) << 5) | 5;
5634 data[4] = (1 << 7) | (rate_idx << 3);
5635 GST_BUFFER_SIZE (priv) = 5;
5638 g_assert_not_reached ();
5641 caps = gst_caps_new_simple ("audio/mpeg",
5642 "mpegversion", G_TYPE_INT, mpegversion,
5643 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5645 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5647 *codec_name = g_strdup_printf ("MPEG-%d AAC audio", mpegversion);
5648 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TTA)) {
5649 caps = gst_caps_new_simple ("audio/x-tta",
5650 "width", G_TYPE_INT, audiocontext->bitdepth, NULL);
5651 *codec_name = g_strdup ("TTA audio");
5652 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_WAVPACK4)) {
5653 caps = gst_caps_new_simple ("audio/x-wavpack",
5654 "width", G_TYPE_INT, audiocontext->bitdepth,
5655 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5656 *codec_name = g_strdup ("Wavpack audio");
5657 context->postprocess_frame = gst_matroska_demux_add_wvpk_header;
5658 audiocontext->wvpk_block_index = 0;
5659 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4)) ||
5660 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4)) ||
5661 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))) {
5662 gint raversion = -1;
5664 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4))
5666 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))
5671 caps = gst_caps_new_simple ("audio/x-pn-realaudio",
5672 "raversion", G_TYPE_INT, raversion, NULL);
5673 /* Extract extra information from caps, mapping varies based on codec */
5674 if (data && (size >= 0x50)) {
5681 guint extra_data_size;
5683 GST_ERROR ("real audio raversion:%d", raversion);
5684 if (raversion == 8) {
5686 flavor = GST_READ_UINT16_BE (data + 22);
5687 packet_size = GST_READ_UINT32_BE (data + 24);
5688 height = GST_READ_UINT16_BE (data + 40);
5689 leaf_size = GST_READ_UINT16_BE (data + 44);
5690 sample_width = GST_READ_UINT16_BE (data + 58);
5691 extra_data_size = GST_READ_UINT32_BE (data + 74);
5694 ("flavor:%d, packet_size:%d, height:%d, leaf_size:%d, sample_width:%d, extra_data_size:%d",
5695 flavor, packet_size, height, leaf_size, sample_width,
5697 gst_caps_set_simple (caps, "flavor", G_TYPE_INT, flavor, "packet_size",
5698 G_TYPE_INT, packet_size, "height", G_TYPE_INT, height, "leaf_size",
5699 G_TYPE_INT, leaf_size, "width", G_TYPE_INT, sample_width, NULL);
5701 if ((size - 78) >= extra_data_size) {
5702 priv = gst_buffer_new_and_alloc (extra_data_size);
5703 memcpy (GST_BUFFER_DATA (priv), data + 78, extra_data_size);
5704 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5705 gst_buffer_unref (priv);
5710 *codec_name = g_strdup_printf ("RealAudio %d.0", raversion);
5711 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_SIPR)) {
5712 caps = gst_caps_new_simple ("audio/x-sipro", NULL);
5713 *codec_name = g_strdup ("Sipro/ACELP.NET Voice Codec");
5714 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_RALF)) {
5715 caps = gst_caps_new_simple ("audio/x-ralf-mpeg4-generic", NULL);
5716 *codec_name = g_strdup ("Real Audio Lossless");
5717 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_ATRC)) {
5718 caps = gst_caps_new_simple ("audio/x-vnd.sony.atrac3", NULL);
5719 *codec_name = g_strdup ("Sony ATRAC3");
5721 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
5726 if (audiocontext->samplerate > 0 && audiocontext->channels > 0) {
5729 for (i = 0; i < gst_caps_get_size (caps); i++) {
5730 gst_structure_set (gst_caps_get_structure (caps, i),
5731 "channels", G_TYPE_INT, audiocontext->channels,
5732 "rate", G_TYPE_INT, audiocontext->samplerate, NULL);
5736 gst_caps_do_simplify (caps);
5743 gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
5744 subtitlecontext, const gchar * codec_id, gpointer data, guint size)
5746 GstCaps *caps = NULL;
5747 GstMatroskaTrackContext *context =
5748 (GstMatroskaTrackContext *) subtitlecontext;
5750 /* for backwards compatibility */
5751 if (!g_ascii_strcasecmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASCII))
5752 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8;
5753 else if (!g_ascii_strcasecmp (codec_id, "S_SSA"))
5754 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_SSA;
5755 else if (!g_ascii_strcasecmp (codec_id, "S_ASS"))
5756 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_ASS;
5757 else if (!g_ascii_strcasecmp (codec_id, "S_USF"))
5758 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_USF;
5760 /* TODO: Add GST_MATROSKA_CODEC_ID_SUBTITLE_BMP support
5761 * Check if we have to do something with codec_private */
5762 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8)) {
5763 caps = gst_caps_new_simple ("text/plain", NULL);
5764 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5765 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_SSA)) {
5766 caps = gst_caps_new_simple ("application/x-ssa", NULL);
5767 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5768 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASS)) {
5769 caps = gst_caps_new_simple ("application/x-ass", NULL);
5770 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5771 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_USF)) {
5772 caps = gst_caps_new_simple ("application/x-usf", NULL);
5773 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5774 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB)) {
5775 caps = gst_caps_new_simple ("video/x-dvd-subpicture", NULL);
5776 ((GstMatroskaTrackContext *) subtitlecontext)->send_dvd_event = TRUE;
5777 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_HDMVPGS)) {
5778 caps = gst_caps_new_simple ("subpicture/x-pgs", NULL);
5779 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_KATE)) {
5780 caps = gst_caps_new_simple ("subtitle/x-kate", NULL);
5781 context->send_xiph_headers = TRUE;
5783 GST_DEBUG ("Unknown subtitle stream: codec_id='%s'", codec_id);
5784 caps = gst_caps_new_simple ("application/x-subtitle-unknown", NULL);
5787 if (data != NULL && size > 0) {
5790 buf = gst_buffer_new_and_alloc (size);
5791 memcpy (GST_BUFFER_DATA (buf), data, size);
5792 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, buf, NULL);
5793 gst_buffer_unref (buf);
5800 gst_matroska_demux_set_index (GstElement * element, GstIndex * index)
5802 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5804 GST_OBJECT_LOCK (demux);
5805 if (demux->element_index)
5806 gst_object_unref (demux->element_index);
5807 demux->element_index = gst_object_ref (index);
5808 GST_OBJECT_UNLOCK (demux);
5809 GST_DEBUG_OBJECT (demux, "Set index %" GST_PTR_FORMAT, demux->element_index);
5813 gst_matroska_demux_get_index (GstElement * element)
5815 GstIndex *result = NULL;
5816 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5818 GST_OBJECT_LOCK (demux);
5819 if (demux->element_index)
5820 result = gst_object_ref (demux->element_index);
5821 GST_OBJECT_UNLOCK (demux);
5823 GST_DEBUG_OBJECT (demux, "Returning index %" GST_PTR_FORMAT, result);
5828 static GstStateChangeReturn
5829 gst_matroska_demux_change_state (GstElement * element,
5830 GstStateChange transition)
5832 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5833 GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
5835 /* handle upwards state changes here */
5836 switch (transition) {
5841 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
5843 /* handle downwards state changes */
5844 switch (transition) {
5845 case GST_STATE_CHANGE_PAUSED_TO_READY:
5846 gst_matroska_demux_reset (GST_ELEMENT (demux));
5856 gst_matroska_demux_plugin_init (GstPlugin * plugin)
5860 /* create an elementfactory for the matroska_demux element */
5861 if (!gst_element_register (plugin, "matroskademux",
5862 GST_RANK_PRIMARY, GST_TYPE_MATROSKA_DEMUX))