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.
53 #include <glib/gprintf.h>
55 /* For AVI compatibility mode
56 and for fourcc stuff */
57 #include <gst/riff/riff-read.h>
58 #include <gst/riff/riff-ids.h>
59 #include <gst/riff/riff-media.h>
61 #include <gst/tag/tag.h>
63 #include <gst/base/gsttypefindhelper.h>
75 #include "matroska-demux.h"
76 #include "matroska-ids.h"
78 GST_DEBUG_CATEGORY_STATIC (matroskademux_debug);
79 #define GST_CAT_DEFAULT matroskademux_debug
81 #define DEBUG_ELEMENT_START(demux, ebml, element) \
82 GST_DEBUG_OBJECT (demux, "Parsing " element " element at offset %" \
83 G_GUINT64_FORMAT, ebml->offset)
85 #define DEBUG_ELEMENT_STOP(demux, ebml, element, ret) \
86 GST_DEBUG_OBJECT (demux, "Parsing " element " element at offset %" \
87 G_GUINT64_FORMAT " finished with '%s'", ebml->offset, \
88 gst_flow_get_name (ret))
97 static GstStaticPadTemplate sink_templ = GST_STATIC_PAD_TEMPLATE ("sink",
100 GST_STATIC_CAPS ("video/x-matroska; video/webm")
103 /* TODO: fill in caps! */
105 static GstStaticPadTemplate audio_src_templ =
106 GST_STATIC_PAD_TEMPLATE ("audio_%02d",
109 GST_STATIC_CAPS ("ANY")
112 static GstStaticPadTemplate video_src_templ =
113 GST_STATIC_PAD_TEMPLATE ("video_%02d",
116 GST_STATIC_CAPS ("ANY")
119 static GstStaticPadTemplate subtitle_src_templ =
120 GST_STATIC_PAD_TEMPLATE ("subtitle_%02d",
123 GST_STATIC_CAPS ("text/plain; application/x-ssa; application/x-ass; "
124 "application/x-usf; video/x-dvd-subpicture; "
125 "subpicture/x-pgs; subtitle/x-kate; " "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 gboolean gst_matroska_demux_handle_sink_event (GstPad * pad,
155 static GstFlowReturn gst_matroska_demux_chain (GstPad * pad,
158 static GstStateChangeReturn
159 gst_matroska_demux_change_state (GstElement * element,
160 GstStateChange transition);
162 gst_matroska_demux_set_index (GstElement * element, GstIndex * index);
163 static GstIndex *gst_matroska_demux_get_index (GstElement * element);
166 static GstCaps *gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext
168 const gchar * codec_id, guint8 * data, guint size, gchar ** codec_name);
169 static GstCaps *gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext
171 const gchar * codec_id, guint8 * data, guint size, gchar ** codec_name);
173 * gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
174 subtitlecontext, const gchar * codec_id, gpointer data, guint size);
177 static void gst_matroska_demux_reset (GstElement * element);
178 static gboolean perform_seek_to_offset (GstMatroskaDemux * demux,
181 GType gst_matroska_demux_get_type (void);
182 GST_BOILERPLATE (GstMatroskaDemux, gst_matroska_demux, GstEbmlRead,
186 gst_matroska_demux_base_init (gpointer klass)
188 GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
190 gst_element_class_add_pad_template (element_class,
191 gst_static_pad_template_get (&video_src_templ));
192 gst_element_class_add_pad_template (element_class,
193 gst_static_pad_template_get (&audio_src_templ));
194 gst_element_class_add_pad_template (element_class,
195 gst_static_pad_template_get (&subtitle_src_templ));
196 gst_element_class_add_pad_template (element_class,
197 gst_static_pad_template_get (&sink_templ));
199 gst_element_class_set_details_simple (element_class, "Matroska demuxer",
201 "Demuxes a Matroska Stream into video/audio/subtitles",
202 "GStreamer maintainers <gstreamer-devel@lists.sourceforge.net>");
206 gst_matroska_demux_finalize (GObject * object)
208 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (object);
211 g_ptr_array_free (demux->src, TRUE);
215 if (demux->global_tags) {
216 gst_tag_list_free (demux->global_tags);
217 demux->global_tags = NULL;
220 g_object_unref (demux->adapter);
222 G_OBJECT_CLASS (parent_class)->finalize (object);
226 gst_matroska_demux_class_init (GstMatroskaDemuxClass * klass)
228 GObjectClass *gobject_class = (GObjectClass *) klass;
229 GstElementClass *gstelement_class = (GstElementClass *) klass;
231 GST_DEBUG_CATEGORY_INIT (matroskademux_debug, "matroskademux", 0,
234 gobject_class->finalize = gst_matroska_demux_finalize;
236 gstelement_class->change_state =
237 GST_DEBUG_FUNCPTR (gst_matroska_demux_change_state);
238 gstelement_class->send_event =
239 GST_DEBUG_FUNCPTR (gst_matroska_demux_element_send_event);
240 gstelement_class->query =
241 GST_DEBUG_FUNCPTR (gst_matroska_demux_element_query);
243 gstelement_class->set_index =
244 GST_DEBUG_FUNCPTR (gst_matroska_demux_set_index);
245 gstelement_class->get_index =
246 GST_DEBUG_FUNCPTR (gst_matroska_demux_get_index);
250 gst_matroska_demux_init (GstMatroskaDemux * demux,
251 GstMatroskaDemuxClass * klass)
253 demux->sinkpad = gst_pad_new_from_static_template (&sink_templ, "sink");
254 gst_pad_set_activate_function (demux->sinkpad,
255 GST_DEBUG_FUNCPTR (gst_matroska_demux_sink_activate));
256 gst_pad_set_activatepull_function (demux->sinkpad,
257 GST_DEBUG_FUNCPTR (gst_matroska_demux_sink_activate_pull));
258 gst_pad_set_chain_function (demux->sinkpad,
259 GST_DEBUG_FUNCPTR (gst_matroska_demux_chain));
260 gst_pad_set_event_function (demux->sinkpad,
261 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_sink_event));
262 gst_element_add_pad (GST_ELEMENT (demux), demux->sinkpad);
263 GST_EBML_READ (demux)->sinkpad = demux->sinkpad;
265 /* initial stream no. */
268 demux->writing_app = NULL;
269 demux->muxing_app = NULL;
271 demux->global_tags = NULL;
273 demux->adapter = gst_adapter_new ();
276 gst_matroska_demux_reset (GST_ELEMENT (demux));
280 gst_matroska_track_free (GstMatroskaTrackContext * track)
282 g_free (track->codec_id);
283 g_free (track->codec_name);
284 g_free (track->name);
285 g_free (track->language);
286 g_free (track->codec_priv);
287 g_free (track->codec_state);
289 if (track->encodings != NULL) {
292 for (i = 0; i < track->encodings->len; ++i) {
293 GstMatroskaTrackEncoding *enc = &g_array_index (track->encodings,
294 GstMatroskaTrackEncoding,
297 g_free (enc->comp_settings);
299 g_array_free (track->encodings, TRUE);
302 if (track->pending_tags)
303 gst_tag_list_free (track->pending_tags);
305 if (track->index_table)
306 g_array_free (track->index_table, TRUE);
312 * Returns the aggregated GstFlowReturn.
315 gst_matroska_demux_combine_flows (GstMatroskaDemux * demux,
316 GstMatroskaTrackContext * track, GstFlowReturn ret)
320 /* store the value */
321 track->last_flow = ret;
323 /* any other error that is not-linked can be returned right away */
324 if (ret != GST_FLOW_NOT_LINKED)
327 /* only return NOT_LINKED if all other pads returned NOT_LINKED */
328 g_assert (demux->src->len == demux->num_streams);
329 for (i = 0; i < demux->src->len; i++) {
330 GstMatroskaTrackContext *ostream = g_ptr_array_index (demux->src, i);
335 ret = ostream->last_flow;
336 /* some other return value (must be SUCCESS but we can return
337 * other values as well) */
338 if (ret != GST_FLOW_NOT_LINKED)
341 /* if we get here, all other pads were unlinked and we return
344 GST_LOG_OBJECT (demux, "combined return %s", gst_flow_get_name (ret));
349 gst_matroska_demux_reset (GstElement * element)
351 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
354 GST_DEBUG_OBJECT (demux, "Resetting state");
357 demux->state = GST_MATROSKA_DEMUX_STATE_START;
359 /* clean up existing streams */
361 g_assert (demux->src->len == demux->num_streams);
362 for (i = 0; i < demux->src->len; i++) {
363 GstMatroskaTrackContext *context = g_ptr_array_index (demux->src, i);
365 if (context->pad != NULL)
366 gst_element_remove_pad (GST_ELEMENT (demux), context->pad);
368 gst_caps_replace (&context->caps, NULL);
369 gst_matroska_track_free (context);
371 g_ptr_array_free (demux->src, TRUE);
373 demux->src = g_ptr_array_new ();
375 demux->num_streams = 0;
376 demux->num_a_streams = 0;
377 demux->num_t_streams = 0;
378 demux->num_v_streams = 0;
380 /* reset media info */
381 g_free (demux->writing_app);
382 demux->writing_app = NULL;
383 g_free (demux->muxing_app);
384 demux->muxing_app = NULL;
388 g_array_free (demux->index, TRUE);
394 demux->time_scale = 1000000;
395 demux->created = G_MININT64;
397 demux->index_parsed = FALSE;
398 demux->tracks_parsed = FALSE;
399 demux->segmentinfo_parsed = FALSE;
400 demux->attachments_parsed = FALSE;
402 g_list_foreach (demux->tags_parsed, (GFunc) gst_ebml_level_free, NULL);
403 g_list_free (demux->tags_parsed);
404 demux->tags_parsed = NULL;
406 gst_segment_init (&demux->segment, GST_FORMAT_TIME);
407 demux->last_stop_end = GST_CLOCK_TIME_NONE;
408 demux->seek_block = 0;
411 demux->cluster_time = GST_CLOCK_TIME_NONE;
412 demux->cluster_offset = 0;
413 demux->index_offset = 0;
414 demux->seekable = FALSE;
415 demux->need_newsegment = FALSE;
416 demux->building_index = FALSE;
417 if (demux->seek_event) {
418 gst_event_unref (demux->seek_event);
419 demux->seek_event = NULL;
422 demux->from_offset = -1;
423 demux->to_offset = G_MAXINT64;
424 demux->seek_index = NULL;
425 demux->seek_entry = 0;
427 if (demux->close_segment) {
428 gst_event_unref (demux->close_segment);
429 demux->close_segment = NULL;
432 if (demux->new_segment) {
433 gst_event_unref (demux->new_segment);
434 demux->new_segment = NULL;
437 if (demux->element_index) {
438 gst_object_unref (demux->element_index);
439 demux->element_index = NULL;
441 demux->element_index_writer_id = -1;
443 if (demux->global_tags) {
444 gst_tag_list_free (demux->global_tags);
446 demux->global_tags = gst_tag_list_new ();
450 gst_matroska_demux_stream_from_num (GstMatroskaDemux * demux, guint track_num)
454 g_assert (demux->src->len == demux->num_streams);
455 for (n = 0; n < demux->src->len; n++) {
456 GstMatroskaTrackContext *context = g_ptr_array_index (demux->src, n);
458 if (context->num == track_num) {
463 if (n == demux->num_streams)
464 GST_WARNING_OBJECT (demux,
465 "Failed to find corresponding pad for tracknum %d", track_num);
471 gst_matroska_demux_encoding_cmp (GstMatroskaTrackEncoding * a,
472 GstMatroskaTrackEncoding * b)
474 if (b->order > a->order)
476 else if (b->order < a->order)
483 gst_matroska_demux_encoding_order_unique (GArray * encodings, guint64 order)
487 if (encodings == NULL || encodings->len == 0)
490 for (i = 0; i < encodings->len; i++)
491 if (g_array_index (encodings, GstMatroskaTrackEncoding, i).order == order)
498 gst_matroska_demux_read_track_encoding (GstMatroskaDemux * demux,
499 GstMatroskaTrackContext * context)
501 GstMatroskaTrackEncoding enc = { 0, };
502 GstEbmlRead *ebml = GST_EBML_READ (demux);
506 DEBUG_ELEMENT_START (demux, ebml, "ContentEncoding");
507 /* Set default values */
509 /* All other default values are 0 */
511 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
512 DEBUG_ELEMENT_STOP (demux, ebml, "ContentEncoding", ret);
516 while (ret == GST_FLOW_OK) {
517 if ((ret = gst_ebml_peek_id (ebml, &demux->level_up, &id)) != GST_FLOW_OK)
520 if (demux->level_up) {
526 case GST_MATROSKA_ID_CONTENTENCODINGORDER:{
529 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
532 if (!gst_matroska_demux_encoding_order_unique (context->encodings, num)) {
533 GST_ERROR_OBJECT (demux, "ContentEncodingOrder %" G_GUINT64_FORMAT
534 "is not unique for track %d", num, context->num);
535 ret = GST_FLOW_ERROR;
539 GST_DEBUG_OBJECT (demux, "ContentEncodingOrder: %" G_GUINT64_FORMAT,
544 case GST_MATROSKA_ID_CONTENTENCODINGSCOPE:{
547 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
550 if (num > 7 && num == 0) {
551 GST_ERROR_OBJECT (demux, "Invalid ContentEncodingScope %"
552 G_GUINT64_FORMAT, num);
553 ret = GST_FLOW_ERROR;
557 GST_DEBUG_OBJECT (demux, "ContentEncodingScope: %" G_GUINT64_FORMAT,
563 case GST_MATROSKA_ID_CONTENTENCODINGTYPE:{
566 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
570 GST_ERROR_OBJECT (demux, "Invalid ContentEncodingType %"
571 G_GUINT64_FORMAT, num);
572 ret = GST_FLOW_ERROR;
574 } else if (num != 0) {
575 GST_ERROR_OBJECT (demux, "Encrypted tracks are not supported yet");
576 ret = GST_FLOW_ERROR;
579 GST_DEBUG_OBJECT (demux, "ContentEncodingType: %" G_GUINT64_FORMAT,
584 case GST_MATROSKA_ID_CONTENTCOMPRESSION:{
586 DEBUG_ELEMENT_START (demux, ebml, "ContentCompression");
588 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
591 while (ret == GST_FLOW_OK) {
592 if ((ret = gst_ebml_peek_id (ebml, &demux->level_up,
593 &id)) != GST_FLOW_OK)
596 if (demux->level_up) {
602 case GST_MATROSKA_ID_CONTENTCOMPALGO:{
605 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK) {
609 GST_ERROR_OBJECT (demux, "Invalid ContentCompAlgo %"
610 G_GUINT64_FORMAT, num);
611 ret = GST_FLOW_ERROR;
614 GST_DEBUG_OBJECT (demux, "ContentCompAlgo: %" G_GUINT64_FORMAT,
620 case GST_MATROSKA_ID_CONTENTCOMPSETTINGS:{
625 gst_ebml_read_binary (ebml, &id, &data,
626 &size)) != GST_FLOW_OK) {
629 enc.comp_settings = data;
630 enc.comp_settings_length = size;
631 GST_DEBUG_OBJECT (demux,
632 "ContentCompSettings of size %" G_GUINT64_FORMAT, size);
636 GST_WARNING_OBJECT (demux,
637 "Unknown ContentCompression subelement 0x%x - ignoring", id);
638 ret = gst_ebml_read_skip (ebml);
642 if (demux->level_up) {
647 DEBUG_ELEMENT_STOP (demux, ebml, "ContentCompression", ret);
651 case GST_MATROSKA_ID_CONTENTENCRYPTION:
652 GST_ERROR_OBJECT (demux, "Encrypted tracks not yet supported");
653 gst_ebml_read_skip (ebml);
654 ret = GST_FLOW_ERROR;
657 GST_WARNING_OBJECT (demux,
658 "Unknown ContentEncoding subelement 0x%x - ignoring", id);
659 ret = gst_ebml_read_skip (ebml);
663 if (demux->level_up) {
669 DEBUG_ELEMENT_STOP (demux, ebml, "ContentEncoding", ret);
670 if (ret != GST_FLOW_OK && ret != GST_FLOW_UNEXPECTED)
673 /* TODO: Check if the combination of values is valid */
675 g_array_append_val (context->encodings, enc);
681 gst_matroska_decompress_data (GstMatroskaTrackEncoding * enc,
682 guint8 ** data_out, guint * size_out,
683 GstMatroskaTrackCompressionAlgorithm algo)
685 guint8 *new_data = NULL;
688 guint8 *data = *data_out;
689 guint size = *size_out;
693 if (algo == GST_MATROSKA_TRACK_COMPRESSION_ALGORITHM_ZLIB) {
695 /* zlib encoded data */
701 zstream.zalloc = (alloc_func) 0;
702 zstream.zfree = (free_func) 0;
703 zstream.opaque = (voidpf) 0;
704 if (inflateInit (&zstream) != Z_OK) {
705 GST_WARNING ("zlib initialization failed.");
709 zstream.next_in = (Bytef *) data;
710 zstream.avail_in = orig_size;
711 new_size = orig_size;
712 new_data = g_malloc (new_size);
713 zstream.avail_out = new_size;
714 zstream.next_out = (Bytef *) new_data;
717 result = inflate (&zstream, Z_NO_FLUSH);
718 if (result != Z_OK && result != Z_STREAM_END) {
719 GST_WARNING ("zlib decompression failed.");
721 inflateEnd (&zstream);
725 new_data = g_realloc (new_data, new_size);
726 zstream.next_out = (Bytef *) (new_data + zstream.total_out);
727 zstream.avail_out += 4000;
728 } while (zstream.avail_in != 0 && result != Z_STREAM_END);
730 if (result != Z_STREAM_END) {
734 new_size = zstream.total_out;
735 inflateEnd (&zstream);
738 GST_WARNING ("zlib encoded tracks not supported.");
742 } else if (algo == GST_MATROSKA_TRACK_COMPRESSION_ALGORITHM_BZLIB) {
744 /* bzip2 encoded data */
749 bzstream.bzalloc = NULL;
750 bzstream.bzfree = NULL;
751 bzstream.opaque = NULL;
754 if (BZ2_bzDecompressInit (&bzstream, 0, 0) != BZ_OK) {
755 GST_WARNING ("bzip2 initialization failed.");
760 bzstream.next_in = (char *) data;
761 bzstream.avail_in = orig_size;
762 new_size = orig_size;
763 new_data = g_malloc (new_size);
764 bzstream.avail_out = new_size;
765 bzstream.next_out = (char *) new_data;
768 result = BZ2_bzDecompress (&bzstream);
769 if (result != BZ_OK && result != BZ_STREAM_END) {
770 GST_WARNING ("bzip2 decompression failed.");
772 BZ2_bzDecompressEnd (&bzstream);
776 new_data = g_realloc (new_data, new_size);
777 bzstream.next_out = (char *) (new_data + bzstream.total_out_lo32);
778 bzstream.avail_out += 4000;
779 } while (bzstream.avail_in != 0 && result != BZ_STREAM_END);
781 if (result != BZ_STREAM_END) {
785 new_size = bzstream.total_out_lo32;
786 BZ2_bzDecompressEnd (&bzstream);
789 GST_WARNING ("bzip2 encoded tracks not supported.");
793 } else if (algo == GST_MATROSKA_TRACK_COMPRESSION_ALGORITHM_LZO1X) {
794 /* lzo encoded data */
796 int orig_size, out_size;
801 new_data = g_malloc (new_size);
807 result = lzo1x_decode (new_data, &out_size, data, &orig_size);
811 new_data = g_realloc (new_data, new_size);
813 } while (orig_size > 0 && result == LZO_OUTPUT_FULL);
815 new_size -= out_size;
817 if (result != LZO_OUTPUT_FULL) {
818 GST_WARNING ("lzo decompression failed");
825 } else if (algo == GST_MATROSKA_TRACK_COMPRESSION_ALGORITHM_HEADERSTRIP) {
826 /* header stripped encoded data */
827 if (enc->comp_settings_length > 0) {
828 new_data = g_malloc (size + enc->comp_settings_length);
829 new_size = size + enc->comp_settings_length;
831 memcpy (new_data, enc->comp_settings, enc->comp_settings_length);
832 memcpy (new_data + enc->comp_settings_length, data, size);
835 g_assert_not_reached ();
844 *data_out = new_data;
845 *size_out = new_size;
852 gst_matroska_decode_data (GArray * encodings, guint8 ** data_out,
853 guint * size_out, GstMatroskaTrackEncodingScope scope, gboolean free)
860 g_return_val_if_fail (encodings != NULL, FALSE);
861 g_return_val_if_fail (data_out != NULL && *data_out != NULL, FALSE);
862 g_return_val_if_fail (size_out != NULL, FALSE);
867 for (i = 0; i < encodings->len; i++) {
868 GstMatroskaTrackEncoding *enc =
869 &g_array_index (encodings, GstMatroskaTrackEncoding, i);
870 guint8 *new_data = NULL;
873 if ((enc->scope & scope) == 0)
876 /* Encryption not supported yet */
877 if (enc->type != 0) {
886 gst_matroska_decompress_data (enc, &new_data, &new_size,
892 if ((data == *data_out && free) || (data != *data_out))
900 if ((data == *data_out && free) || (data != *data_out))
914 gst_matroska_decode_buffer (GstMatroskaTrackContext * context, GstBuffer * buf)
920 g_return_val_if_fail (GST_IS_BUFFER (buf), NULL);
922 GST_DEBUG ("decoding buffer %p", buf);
924 data = GST_BUFFER_DATA (buf);
925 size = GST_BUFFER_SIZE (buf);
927 g_return_val_if_fail (data != NULL && size > 0, buf);
929 if (gst_matroska_decode_data (context->encodings, &data, &size,
930 GST_MATROSKA_TRACK_ENCODING_SCOPE_FRAME, FALSE)) {
931 new_buf = gst_buffer_new ();
932 GST_BUFFER_MALLOCDATA (new_buf) = (guint8 *) data;
933 GST_BUFFER_DATA (new_buf) = (guint8 *) data;
934 GST_BUFFER_SIZE (new_buf) = size;
936 gst_buffer_unref (buf);
941 GST_DEBUG ("decode data failed");
942 gst_buffer_unref (buf);
948 gst_matroska_decode_content_encodings (GArray * encodings)
952 if (encodings == NULL)
955 for (i = 0; i < encodings->len; i++) {
956 GstMatroskaTrackEncoding *enc =
957 &g_array_index (encodings, GstMatroskaTrackEncoding, i);
958 GstMatroskaTrackEncoding *enc2;
962 if ((enc->scope & GST_MATROSKA_TRACK_ENCODING_SCOPE_NEXT_CONTENT_ENCODING)
966 /* Encryption not supported yet */
968 return GST_FLOW_ERROR;
970 if (i + 1 >= encodings->len)
971 return GST_FLOW_ERROR;
973 enc2 = &g_array_index (encodings, GstMatroskaTrackEncoding, i + 1);
975 if (enc->comp_settings_length == 0)
978 data = enc->comp_settings;
979 size = enc->comp_settings_length;
981 if (!gst_matroska_decompress_data (enc, &data, &size, enc->comp_algo))
982 return GST_FLOW_ERROR;
984 g_free (enc->comp_settings);
986 enc->comp_settings = data;
987 enc->comp_settings_length = size;
994 gst_matroska_demux_read_track_encodings (GstMatroskaDemux * demux,
995 GstMatroskaTrackContext * context)
998 GstEbmlRead *ebml = GST_EBML_READ (demux);
1001 DEBUG_ELEMENT_START (demux, ebml, "ContentEncodings");
1003 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
1004 DEBUG_ELEMENT_STOP (demux, ebml, "ContentEncodings", ret);
1008 context->encodings =
1009 g_array_sized_new (FALSE, FALSE, sizeof (GstMatroskaTrackEncoding), 1);
1011 while (ret == GST_FLOW_OK) {
1012 if ((ret = gst_ebml_peek_id (ebml, &demux->level_up, &id)) != GST_FLOW_OK)
1015 if (demux->level_up) {
1021 case GST_MATROSKA_ID_CONTENTENCODING:
1022 ret = gst_matroska_demux_read_track_encoding (demux, context);
1025 GST_WARNING_OBJECT (demux,
1026 "Unknown ContentEncodings subelement 0x%x - ignoring", id);
1027 ret = gst_ebml_read_skip (ebml);
1031 if (demux->level_up) {
1037 DEBUG_ELEMENT_STOP (demux, ebml, "ContentEncodings", ret);
1038 if (ret != GST_FLOW_OK && ret != GST_FLOW_UNEXPECTED)
1041 /* Sort encodings according to their order */
1042 g_array_sort (context->encodings,
1043 (GCompareFunc) gst_matroska_demux_encoding_cmp);
1045 return gst_matroska_decode_content_encodings (context->encodings);
1049 gst_matroska_demux_tracknumber_unique (GstMatroskaDemux * demux, guint64 num)
1053 g_assert (demux->src->len == demux->num_streams);
1054 for (i = 0; i < demux->src->len; i++) {
1055 GstMatroskaTrackContext *context = g_ptr_array_index (demux->src, i);
1057 if (context->num == num)
1064 static GstFlowReturn
1065 gst_matroska_demux_add_stream (GstMatroskaDemux * demux)
1067 GstElementClass *klass = GST_ELEMENT_GET_CLASS (demux);
1068 GstEbmlRead *ebml = GST_EBML_READ (demux);
1069 GstMatroskaTrackContext *context;
1070 GstPadTemplate *templ = NULL;
1071 GstCaps *caps = NULL;
1072 gchar *padname = NULL;
1075 GstTagList *list = NULL;
1076 gchar *codec = NULL;
1078 DEBUG_ELEMENT_START (demux, ebml, "TrackEntry");
1080 /* start with the master */
1081 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
1082 DEBUG_ELEMENT_STOP (demux, ebml, "TrackEntry", ret);
1086 /* allocate generic... if we know the type, we'll g_renew()
1087 * with the precise type */
1088 context = g_new0 (GstMatroskaTrackContext, 1);
1089 g_ptr_array_add (demux->src, context);
1090 context->index = demux->num_streams;
1091 context->index_writer_id = -1;
1092 context->type = 0; /* no type yet */
1093 context->default_duration = 0;
1095 context->set_discont = TRUE;
1096 context->timecodescale = 1.0;
1098 GST_MATROSKA_TRACK_ENABLED | GST_MATROSKA_TRACK_DEFAULT |
1099 GST_MATROSKA_TRACK_LACING;
1100 context->last_flow = GST_FLOW_OK;
1101 demux->num_streams++;
1102 g_assert (demux->src->len == demux->num_streams);
1104 GST_DEBUG_OBJECT (demux, "Stream number %d", context->index);
1106 /* try reading the trackentry headers */
1107 while (ret == GST_FLOW_OK) {
1108 if ((ret = gst_ebml_peek_id (ebml, &demux->level_up, &id)) != GST_FLOW_OK)
1111 if (demux->level_up) {
1117 /* track number (unique stream ID) */
1118 case GST_MATROSKA_ID_TRACKNUMBER:{
1121 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1125 GST_ERROR_OBJECT (demux, "Invalid TrackNumber 0");
1126 ret = GST_FLOW_ERROR;
1128 } else if (!gst_matroska_demux_tracknumber_unique (demux, num)) {
1129 GST_ERROR_OBJECT (demux, "TrackNumber %" G_GUINT64_FORMAT
1130 " is not unique", num);
1131 ret = GST_FLOW_ERROR;
1135 GST_DEBUG_OBJECT (demux, "TrackNumber: %" G_GUINT64_FORMAT, num);
1139 /* track UID (unique identifier) */
1140 case GST_MATROSKA_ID_TRACKUID:{
1143 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1147 GST_ERROR_OBJECT (demux, "Invalid TrackUID 0");
1148 ret = GST_FLOW_ERROR;
1152 GST_DEBUG_OBJECT (demux, "TrackUID: %" G_GUINT64_FORMAT, num);
1157 /* track type (video, audio, combined, subtitle, etc.) */
1158 case GST_MATROSKA_ID_TRACKTYPE:{
1161 if ((ret = gst_ebml_read_uint (ebml, &id, &track_type)) != GST_FLOW_OK) {
1165 if (context->type != 0 && context->type != track_type) {
1166 GST_WARNING_OBJECT (demux,
1167 "More than one tracktype defined in a TrackEntry - skipping");
1169 } else if (track_type < 1 || track_type > 254) {
1170 GST_WARNING_OBJECT (demux, "Invalid TrackType %" G_GUINT64_FORMAT,
1175 GST_DEBUG_OBJECT (demux, "TrackType: %" G_GUINT64_FORMAT, track_type);
1177 /* ok, so we're actually going to reallocate this thing */
1178 switch (track_type) {
1179 case GST_MATROSKA_TRACK_TYPE_VIDEO:
1180 gst_matroska_track_init_video_context (&context);
1182 case GST_MATROSKA_TRACK_TYPE_AUDIO:
1183 gst_matroska_track_init_audio_context (&context);
1185 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
1186 gst_matroska_track_init_subtitle_context (&context);
1188 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1189 case GST_MATROSKA_TRACK_TYPE_LOGO:
1190 case GST_MATROSKA_TRACK_TYPE_BUTTONS:
1191 case GST_MATROSKA_TRACK_TYPE_CONTROL:
1193 GST_WARNING_OBJECT (demux,
1194 "Unknown or unsupported TrackType %" G_GUINT64_FORMAT,
1199 g_ptr_array_index (demux->src, demux->num_streams - 1) = context;
1203 /* tracktype specific stuff for video */
1204 case GST_MATROSKA_ID_TRACKVIDEO:{
1205 GstMatroskaTrackVideoContext *videocontext;
1207 DEBUG_ELEMENT_START (demux, ebml, "TrackVideo");
1209 if (!gst_matroska_track_init_video_context (&context)) {
1210 GST_WARNING_OBJECT (demux,
1211 "TrackVideo element in non-video track - ignoring track");
1212 ret = GST_FLOW_ERROR;
1214 } else if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
1217 videocontext = (GstMatroskaTrackVideoContext *) context;
1218 g_ptr_array_index (demux->src, demux->num_streams - 1) = context;
1220 while (ret == GST_FLOW_OK) {
1222 gst_ebml_peek_id (ebml, &demux->level_up,
1223 &id)) != GST_FLOW_OK)
1226 if (demux->level_up) {
1232 /* Should be one level up but some broken muxers write it here. */
1233 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
1236 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1240 GST_WARNING_OBJECT (demux, "Invalid TrackDefaultDuration 0");
1244 GST_DEBUG_OBJECT (demux,
1245 "TrackDefaultDuration: %" G_GUINT64_FORMAT, num);
1246 context->default_duration = num;
1250 /* video framerate */
1251 /* NOTE: This one is here only for backward compatibility.
1252 * Use _TRACKDEFAULDURATION one level up. */
1253 case GST_MATROSKA_ID_VIDEOFRAMERATE:{
1256 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
1260 GST_WARNING_OBJECT (demux, "Invalid TrackVideoFPS %lf", num);
1264 GST_DEBUG_OBJECT (demux, "TrackVideoFrameRate: %lf", num);
1265 if (context->default_duration == 0)
1266 context->default_duration =
1267 gst_gdouble_to_guint64 ((gdouble) GST_SECOND * (1.0 / num));
1268 videocontext->default_fps = num;
1272 /* width of the size to display the video at */
1273 case GST_MATROSKA_ID_VIDEODISPLAYWIDTH:{
1276 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1280 GST_WARNING_OBJECT (demux, "Invalid TrackVideoDisplayWidth 0");
1284 GST_DEBUG_OBJECT (demux,
1285 "TrackVideoDisplayWidth: %" G_GUINT64_FORMAT, num);
1286 videocontext->display_width = num;
1290 /* height of the size to display the video at */
1291 case GST_MATROSKA_ID_VIDEODISPLAYHEIGHT:{
1294 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1298 GST_WARNING_OBJECT (demux, "Invalid TrackVideoDisplayHeight 0");
1302 GST_DEBUG_OBJECT (demux,
1303 "TrackVideoDisplayHeight: %" G_GUINT64_FORMAT, num);
1304 videocontext->display_height = num;
1308 /* width of the video in the file */
1309 case GST_MATROSKA_ID_VIDEOPIXELWIDTH:{
1312 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1316 GST_WARNING_OBJECT (demux, "Invalid TrackVideoPixelWidth 0");
1320 GST_DEBUG_OBJECT (demux,
1321 "TrackVideoPixelWidth: %" G_GUINT64_FORMAT, num);
1322 videocontext->pixel_width = num;
1326 /* height of the video in the file */
1327 case GST_MATROSKA_ID_VIDEOPIXELHEIGHT:{
1330 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1334 GST_WARNING_OBJECT (demux, "Invalid TrackVideoPixelHeight 0");
1338 GST_DEBUG_OBJECT (demux,
1339 "TrackVideoPixelHeight: %" G_GUINT64_FORMAT, num);
1340 videocontext->pixel_height = num;
1344 /* whether the video is interlaced */
1345 case GST_MATROSKA_ID_VIDEOFLAGINTERLACED:{
1348 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1352 context->flags |= GST_MATROSKA_VIDEOTRACK_INTERLACED;
1354 context->flags &= ~GST_MATROSKA_VIDEOTRACK_INTERLACED;
1355 GST_DEBUG_OBJECT (demux, "TrackVideoInterlaced: %d",
1356 (context->flags & GST_MATROSKA_VIDEOTRACK_INTERLACED) ? 1 :
1361 /* aspect ratio behaviour */
1362 case GST_MATROSKA_ID_VIDEOASPECTRATIOTYPE:{
1365 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1368 if (num != GST_MATROSKA_ASPECT_RATIO_MODE_FREE &&
1369 num != GST_MATROSKA_ASPECT_RATIO_MODE_KEEP &&
1370 num != GST_MATROSKA_ASPECT_RATIO_MODE_FIXED) {
1371 GST_WARNING_OBJECT (demux,
1372 "Unknown TrackVideoAspectRatioType 0x%x", (guint) num);
1375 GST_DEBUG_OBJECT (demux,
1376 "TrackVideoAspectRatioType: %" G_GUINT64_FORMAT, num);
1377 videocontext->asr_mode = num;
1381 /* colourspace (only matters for raw video) fourcc */
1382 case GST_MATROSKA_ID_VIDEOCOLOURSPACE:{
1387 gst_ebml_read_binary (ebml, &id, &data,
1388 &datalen)) != GST_FLOW_OK)
1393 GST_WARNING_OBJECT (demux,
1394 "Invalid TrackVideoColourSpace length %" G_GUINT64_FORMAT,
1399 memcpy (&videocontext->fourcc, data, 4);
1400 GST_DEBUG_OBJECT (demux,
1401 "TrackVideoColourSpace: %" GST_FOURCC_FORMAT,
1402 GST_FOURCC_ARGS (videocontext->fourcc));
1408 GST_WARNING_OBJECT (demux,
1409 "Unknown TrackVideo subelement 0x%x - ignoring", id);
1411 case GST_MATROSKA_ID_VIDEOSTEREOMODE:
1412 case GST_MATROSKA_ID_VIDEODISPLAYUNIT:
1413 case GST_MATROSKA_ID_VIDEOPIXELCROPBOTTOM:
1414 case GST_MATROSKA_ID_VIDEOPIXELCROPTOP:
1415 case GST_MATROSKA_ID_VIDEOPIXELCROPLEFT:
1416 case GST_MATROSKA_ID_VIDEOPIXELCROPRIGHT:
1417 case GST_MATROSKA_ID_VIDEOGAMMAVALUE:
1418 ret = gst_ebml_read_skip (ebml);
1422 if (demux->level_up) {
1428 DEBUG_ELEMENT_STOP (demux, ebml, "TrackVideo", ret);
1432 /* tracktype specific stuff for audio */
1433 case GST_MATROSKA_ID_TRACKAUDIO:{
1434 GstMatroskaTrackAudioContext *audiocontext;
1436 DEBUG_ELEMENT_START (demux, ebml, "TrackAudio");
1438 if (!gst_matroska_track_init_audio_context (&context)) {
1439 GST_WARNING_OBJECT (demux,
1440 "TrackAudio element in non-audio track - ignoring track");
1441 ret = GST_FLOW_ERROR;
1445 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
1448 audiocontext = (GstMatroskaTrackAudioContext *) context;
1449 g_ptr_array_index (demux->src, demux->num_streams - 1) = context;
1451 while (ret == GST_FLOW_OK) {
1453 gst_ebml_peek_id (ebml, &demux->level_up,
1454 &id)) != GST_FLOW_OK)
1457 if (demux->level_up) {
1464 case GST_MATROSKA_ID_AUDIOSAMPLINGFREQ:{
1467 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
1472 GST_WARNING_OBJECT (demux,
1473 "Invalid TrackAudioSamplingFrequency %lf", num);
1477 GST_DEBUG_OBJECT (demux, "TrackAudioSamplingFrequency: %lf", num);
1478 audiocontext->samplerate = num;
1483 case GST_MATROSKA_ID_AUDIOBITDEPTH:{
1486 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1490 GST_WARNING_OBJECT (demux, "Invalid TrackAudioBitDepth 0");
1494 GST_DEBUG_OBJECT (demux, "TrackAudioBitDepth: %" G_GUINT64_FORMAT,
1496 audiocontext->bitdepth = num;
1501 case GST_MATROSKA_ID_AUDIOCHANNELS:{
1504 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1508 GST_WARNING_OBJECT (demux, "Invalid TrackAudioChannels 0");
1512 GST_DEBUG_OBJECT (demux, "TrackAudioChannels: %" G_GUINT64_FORMAT,
1514 audiocontext->channels = num;
1519 GST_WARNING_OBJECT (demux,
1520 "Unknown TrackAudio subelement 0x%x - ignoring", id);
1522 case GST_MATROSKA_ID_AUDIOCHANNELPOSITIONS:
1523 case GST_MATROSKA_ID_AUDIOOUTPUTSAMPLINGFREQ:
1524 ret = gst_ebml_read_skip (ebml);
1528 if (demux->level_up) {
1534 DEBUG_ELEMENT_STOP (demux, ebml, "TrackAudio", ret);
1539 /* codec identifier */
1540 case GST_MATROSKA_ID_CODECID:{
1543 if ((ret = gst_ebml_read_ascii (ebml, &id, &text)) != GST_FLOW_OK)
1546 GST_DEBUG_OBJECT (demux, "CodecID: %s", GST_STR_NULL (text));
1547 context->codec_id = text;
1551 /* codec private data */
1552 case GST_MATROSKA_ID_CODECPRIVATE:{
1557 gst_ebml_read_binary (ebml, &id, &data, &size)) != GST_FLOW_OK)
1560 context->codec_priv = data;
1561 context->codec_priv_size = size;
1563 GST_DEBUG_OBJECT (demux, "CodecPrivate of size %" G_GUINT64_FORMAT,
1568 /* name of the codec */
1569 case GST_MATROSKA_ID_CODECNAME:{
1572 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1575 GST_DEBUG_OBJECT (demux, "CodecName: %s", GST_STR_NULL (text));
1576 context->codec_name = text;
1580 /* name of this track */
1581 case GST_MATROSKA_ID_TRACKNAME:{
1584 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1587 context->name = text;
1588 GST_DEBUG_OBJECT (demux, "TrackName: %s", GST_STR_NULL (text));
1592 /* language (matters for audio/subtitles, mostly) */
1593 case GST_MATROSKA_ID_TRACKLANGUAGE:{
1596 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1600 context->language = text;
1603 if (strlen (context->language) >= 4 && context->language[3] == '-')
1604 context->language[3] = '\0';
1606 GST_DEBUG_OBJECT (demux, "TrackLanguage: %s",
1607 GST_STR_NULL (context->language));
1611 /* whether this is actually used */
1612 case GST_MATROSKA_ID_TRACKFLAGENABLED:{
1615 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1619 context->flags |= GST_MATROSKA_TRACK_ENABLED;
1621 context->flags &= ~GST_MATROSKA_TRACK_ENABLED;
1623 GST_DEBUG_OBJECT (demux, "TrackEnabled: %d",
1624 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
1628 /* whether it's the default for this track type */
1629 case GST_MATROSKA_ID_TRACKFLAGDEFAULT:{
1632 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1636 context->flags |= GST_MATROSKA_TRACK_DEFAULT;
1638 context->flags &= ~GST_MATROSKA_TRACK_DEFAULT;
1640 GST_DEBUG_OBJECT (demux, "TrackDefault: %d",
1641 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
1645 /* whether the track must be used during playback */
1646 case GST_MATROSKA_ID_TRACKFLAGFORCED:{
1649 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1653 context->flags |= GST_MATROSKA_TRACK_FORCED;
1655 context->flags &= ~GST_MATROSKA_TRACK_FORCED;
1657 GST_DEBUG_OBJECT (demux, "TrackForced: %d",
1658 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
1662 /* lacing (like MPEG, where blocks don't end/start on frame
1664 case GST_MATROSKA_ID_TRACKFLAGLACING:{
1667 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1671 context->flags |= GST_MATROSKA_TRACK_LACING;
1673 context->flags &= ~GST_MATROSKA_TRACK_LACING;
1675 GST_DEBUG_OBJECT (demux, "TrackLacing: %d",
1676 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
1680 /* default length (in time) of one data block in this track */
1681 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
1684 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1689 GST_WARNING_OBJECT (demux, "Invalid TrackDefaultDuration 0");
1693 GST_DEBUG_OBJECT (demux, "TrackDefaultDuration: %" G_GUINT64_FORMAT,
1695 context->default_duration = num;
1699 case GST_MATROSKA_ID_CONTENTENCODINGS:{
1700 ret = gst_matroska_demux_read_track_encodings (demux, context);
1704 case GST_MATROSKA_ID_TRACKTIMECODESCALE:{
1707 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
1711 GST_WARNING_OBJECT (demux, "Invalid TrackTimeCodeScale %lf", num);
1715 GST_DEBUG_OBJECT (demux, "TrackTimeCodeScale: %lf", num);
1716 context->timecodescale = num;
1721 GST_WARNING ("Unknown TrackEntry subelement 0x%x - ignoring", id);
1724 /* we ignore these because they're nothing useful (i.e. crap)
1725 * or simply not implemented yet. */
1726 case GST_MATROSKA_ID_TRACKMINCACHE:
1727 case GST_MATROSKA_ID_TRACKMAXCACHE:
1728 case GST_MATROSKA_ID_MAXBLOCKADDITIONID:
1729 case GST_MATROSKA_ID_TRACKATTACHMENTLINK:
1730 case GST_MATROSKA_ID_TRACKOVERLAY:
1731 case GST_MATROSKA_ID_TRACKTRANSLATE:
1732 case GST_MATROSKA_ID_TRACKOFFSET:
1733 case GST_MATROSKA_ID_CODECSETTINGS:
1734 case GST_MATROSKA_ID_CODECINFOURL:
1735 case GST_MATROSKA_ID_CODECDOWNLOADURL:
1736 case GST_MATROSKA_ID_CODECDECODEALL:
1737 ret = gst_ebml_read_skip (ebml);
1741 if (demux->level_up) {
1747 DEBUG_ELEMENT_STOP (demux, ebml, "TrackEntry", ret);
1749 /* Decode codec private data if necessary */
1750 if (context->encodings && context->encodings->len > 0 && context->codec_priv
1751 && context->codec_priv_size > 0) {
1752 if (!gst_matroska_decode_data (context->encodings,
1753 &context->codec_priv, &context->codec_priv_size,
1754 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
1755 GST_WARNING_OBJECT (demux, "Decoding codec private data failed");
1756 ret = GST_FLOW_ERROR;
1760 if (context->type == 0 || context->codec_id == NULL || (ret != GST_FLOW_OK
1761 && ret != GST_FLOW_UNEXPECTED)) {
1762 if (ret == GST_FLOW_OK || ret == GST_FLOW_UNEXPECTED)
1763 GST_WARNING_OBJECT (ebml, "Unknown stream/codec in track entry header");
1765 demux->num_streams--;
1766 g_ptr_array_remove_index (demux->src, demux->num_streams);
1767 g_assert (demux->src->len == demux->num_streams);
1769 gst_matroska_track_free (context);
1775 /* now create the GStreamer connectivity */
1776 switch (context->type) {
1777 case GST_MATROSKA_TRACK_TYPE_VIDEO:{
1778 GstMatroskaTrackVideoContext *videocontext =
1779 (GstMatroskaTrackVideoContext *) context;
1781 padname = g_strdup_printf ("video_%02d", demux->num_v_streams++);
1782 templ = gst_element_class_get_pad_template (klass, "video_%02d");
1783 caps = gst_matroska_demux_video_caps (videocontext,
1785 (guint8 *) context->codec_priv, context->codec_priv_size, &codec);
1787 list = gst_tag_list_new ();
1788 gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
1789 GST_TAG_VIDEO_CODEC, codec, NULL);
1795 case GST_MATROSKA_TRACK_TYPE_AUDIO:{
1796 GstMatroskaTrackAudioContext *audiocontext =
1797 (GstMatroskaTrackAudioContext *) context;
1799 padname = g_strdup_printf ("audio_%02d", demux->num_a_streams++);
1800 templ = gst_element_class_get_pad_template (klass, "audio_%02d");
1801 caps = gst_matroska_demux_audio_caps (audiocontext,
1803 context->codec_priv, context->codec_priv_size, &codec);
1805 list = gst_tag_list_new ();
1806 gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
1807 GST_TAG_AUDIO_CODEC, codec, NULL);
1813 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:{
1814 GstMatroskaTrackSubtitleContext *subtitlecontext =
1815 (GstMatroskaTrackSubtitleContext *) context;
1817 padname = g_strdup_printf ("subtitle_%02d", demux->num_t_streams++);
1818 templ = gst_element_class_get_pad_template (klass, "subtitle_%02d");
1819 caps = gst_matroska_demux_subtitle_caps (subtitlecontext,
1820 context->codec_id, context->codec_priv, context->codec_priv_size);
1824 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1825 case GST_MATROSKA_TRACK_TYPE_LOGO:
1826 case GST_MATROSKA_TRACK_TYPE_BUTTONS:
1827 case GST_MATROSKA_TRACK_TYPE_CONTROL:
1829 /* we should already have quit by now */
1830 g_assert_not_reached ();
1833 if ((context->language == NULL || *context->language == '\0') &&
1834 (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO ||
1835 context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
1836 GST_LOG ("stream %d: language=eng (assuming default)", context->index);
1837 context->language = g_strdup ("eng");
1840 if (context->language) {
1844 list = gst_tag_list_new ();
1846 /* Matroska contains ISO 639-2B codes, we want ISO 639-1 */
1847 lang = gst_tag_get_language_code (context->language);
1848 gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
1849 GST_TAG_LANGUAGE_CODE, (lang) ? lang : context->language, NULL);
1853 GST_WARNING_OBJECT (demux, "could not determine caps for stream with "
1854 "codec_id='%s'", context->codec_id);
1855 switch (context->type) {
1856 case GST_MATROSKA_TRACK_TYPE_VIDEO:
1857 caps = gst_caps_new_simple ("video/x-unknown", NULL);
1859 case GST_MATROSKA_TRACK_TYPE_AUDIO:
1860 caps = gst_caps_new_simple ("audio/x-unknown", NULL);
1862 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
1863 caps = gst_caps_new_simple ("application/x-subtitle-unknown", NULL);
1865 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1867 caps = gst_caps_new_simple ("application/x-matroska-unknown", NULL);
1870 gst_caps_set_simple (caps, "codec-id", G_TYPE_STRING, context->codec_id,
1874 /* the pad in here */
1875 context->pad = gst_pad_new_from_template (templ, padname);
1876 context->caps = caps;
1878 gst_pad_set_event_function (context->pad,
1879 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_event));
1880 gst_pad_set_query_type_function (context->pad,
1881 GST_DEBUG_FUNCPTR (gst_matroska_demux_get_src_query_types));
1882 gst_pad_set_query_function (context->pad,
1883 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_query));
1885 GST_INFO_OBJECT (demux, "Adding pad '%s' with caps %" GST_PTR_FORMAT,
1888 context->pending_tags = list;
1890 gst_pad_set_element_private (context->pad, context);
1892 gst_pad_use_fixed_caps (context->pad);
1893 gst_pad_set_caps (context->pad, context->caps);
1894 gst_pad_set_active (context->pad, TRUE);
1895 gst_element_add_pad (GST_ELEMENT (demux), context->pad);
1903 static const GstQueryType *
1904 gst_matroska_demux_get_src_query_types (GstPad * pad)
1906 static const GstQueryType query_types[] = {
1917 gst_matroska_demux_query (GstMatroskaDemux * demux, GstPad * pad,
1920 gboolean res = FALSE;
1921 GstMatroskaTrackContext *context = NULL;
1924 context = gst_pad_get_element_private (pad);
1927 switch (GST_QUERY_TYPE (query)) {
1928 case GST_QUERY_POSITION:
1932 gst_query_parse_position (query, &format, NULL);
1934 if (format == GST_FORMAT_TIME) {
1935 GST_OBJECT_LOCK (demux);
1937 gst_query_set_position (query, GST_FORMAT_TIME, context->pos);
1939 gst_query_set_position (query, GST_FORMAT_TIME,
1940 demux->segment.last_stop);
1941 GST_OBJECT_UNLOCK (demux);
1942 } else if (format == GST_FORMAT_DEFAULT && context
1943 && context->default_duration) {
1944 GST_OBJECT_LOCK (demux);
1945 gst_query_set_position (query, GST_FORMAT_DEFAULT,
1946 context->pos / context->default_duration);
1947 GST_OBJECT_UNLOCK (demux);
1949 GST_DEBUG_OBJECT (demux,
1950 "only position query in TIME and DEFAULT format is supported");
1956 case GST_QUERY_DURATION:
1960 gst_query_parse_duration (query, &format, NULL);
1962 if (format == GST_FORMAT_TIME) {
1963 GST_OBJECT_LOCK (demux);
1964 gst_query_set_duration (query, GST_FORMAT_TIME,
1965 demux->segment.duration);
1966 GST_OBJECT_UNLOCK (demux);
1967 } else if (format == GST_FORMAT_DEFAULT && context
1968 && context->default_duration) {
1969 GST_OBJECT_LOCK (demux);
1970 gst_query_set_duration (query, GST_FORMAT_DEFAULT,
1971 demux->segment.duration / context->default_duration);
1972 GST_OBJECT_UNLOCK (demux);
1974 GST_DEBUG_OBJECT (demux,
1975 "only duration query in TIME and DEFAULT format is supported");
1982 case GST_QUERY_SEEKING:
1986 gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
1987 if (fmt == GST_FORMAT_TIME) {
1990 if (demux->streaming) {
1991 /* assuming we'll be able to get an index ... */
1992 seekable = demux->seekable;
1994 seekable = !!demux->index;
1997 gst_query_set_seeking (query, GST_FORMAT_TIME, seekable,
1998 0, demux->segment.duration);
2004 res = gst_pad_query_default (pad, query);
2012 gst_matroska_demux_element_query (GstElement * element, GstQuery * query)
2014 return gst_matroska_demux_query (GST_MATROSKA_DEMUX (element), NULL, query);
2018 gst_matroska_demux_handle_src_query (GstPad * pad, GstQuery * query)
2021 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (gst_pad_get_parent (pad));
2023 ret = gst_matroska_demux_query (demux, pad, query);
2025 gst_object_unref (demux);
2031 gst_matroska_index_seek_find (GstMatroskaIndex * i1, GstClockTime * time,
2034 if (i1->time < *time)
2036 else if (i1->time > *time)
2042 static GstMatroskaIndex *
2043 gst_matroskademux_do_index_seek (GstMatroskaDemux * demux,
2044 GstMatroskaTrackContext * track, gint64 seek_pos, GArray ** _index,
2045 gint * _entry_index)
2047 GstMatroskaIndex *entry = NULL;
2050 if (!demux->index || !demux->index->len)
2053 /* find entry just before or at the requested position */
2054 if (track && track->index_table)
2055 index = track->index_table;
2057 index = demux->index;
2060 gst_util_array_binary_search (index->data, index->len,
2061 sizeof (GstMatroskaIndex),
2062 (GCompareDataFunc) gst_matroska_index_seek_find, GST_SEARCH_MODE_BEFORE,
2066 entry = &g_array_index (index, GstMatroskaIndex, 0);
2071 *_entry_index = entry - (GstMatroskaIndex *) index->data;
2076 /* takes ownership of taglist */
2078 gst_matroska_demux_found_global_tag (GstMatroskaDemux * demux,
2079 GstTagList * taglist)
2081 if (demux->global_tags) {
2082 /* nothing sent yet, add to cache */
2083 gst_tag_list_insert (demux->global_tags, taglist, GST_TAG_MERGE_APPEND);
2084 gst_tag_list_free (taglist);
2086 /* hm, already sent, no need to cache and wait anymore */
2087 GST_DEBUG_OBJECT (demux, "Sending late global tags %" GST_PTR_FORMAT,
2089 gst_element_found_tags (GST_ELEMENT (demux), taglist);
2093 /* returns FALSE if there are no pads to deliver event to,
2094 * otherwise TRUE (whatever the outcome of event sending),
2095 * takes ownership of the passed event! */
2097 gst_matroska_demux_send_event (GstMatroskaDemux * demux, GstEvent * event)
2099 gboolean is_newsegment;
2100 gboolean ret = FALSE;
2103 g_return_val_if_fail (event != NULL, FALSE);
2105 GST_DEBUG_OBJECT (demux, "Sending event of type %s to all source pads",
2106 GST_EVENT_TYPE_NAME (event));
2108 is_newsegment = (GST_EVENT_TYPE (event) == GST_EVENT_NEWSEGMENT);
2110 g_assert (demux->src->len == demux->num_streams);
2111 for (i = 0; i < demux->src->len; i++) {
2112 GstMatroskaTrackContext *stream;
2114 stream = g_ptr_array_index (demux->src, i);
2115 gst_event_ref (event);
2116 gst_pad_push_event (stream->pad, event);
2119 /* FIXME: send global tags before stream tags */
2120 if (G_UNLIKELY (is_newsegment && stream->pending_tags != NULL)) {
2121 GST_DEBUG_OBJECT (demux, "Sending pending_tags %p for pad %s:%s : %"
2122 GST_PTR_FORMAT, stream->pending_tags,
2123 GST_DEBUG_PAD_NAME (stream->pad), stream->pending_tags);
2124 gst_element_found_tags_for_pad (GST_ELEMENT (demux), stream->pad,
2125 stream->pending_tags);
2126 stream->pending_tags = NULL;
2130 if (G_UNLIKELY (is_newsegment && demux->global_tags != NULL)) {
2131 gst_tag_list_add (demux->global_tags, GST_TAG_MERGE_REPLACE,
2132 GST_TAG_CONTAINER_FORMAT, "Matroska", NULL);
2133 GST_DEBUG_OBJECT (demux, "Sending global_tags %p : %" GST_PTR_FORMAT,
2134 demux->global_tags, demux->global_tags);
2135 gst_element_found_tags (GST_ELEMENT (demux), demux->global_tags);
2136 demux->global_tags = NULL;
2139 gst_event_unref (event);
2144 gst_matroska_demux_element_send_event (GstElement * element, GstEvent * event)
2146 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
2149 g_return_val_if_fail (event != NULL, FALSE);
2151 if (GST_EVENT_TYPE (event) == GST_EVENT_SEEK) {
2152 res = gst_matroska_demux_handle_seek_event (demux, NULL, event);
2154 GST_WARNING_OBJECT (demux, "Unhandled event of type %s",
2155 GST_EVENT_TYPE_NAME (event));
2158 gst_event_unref (event);
2162 /* determine track to seek in */
2163 static GstMatroskaTrackContext *
2164 gst_matroska_demux_get_seek_track (GstMatroskaDemux * demux,
2165 GstMatroskaTrackContext * track)
2169 if (track && track->type == GST_MATROSKA_TRACK_TYPE_VIDEO)
2172 for (i = 0; i < demux->src->len; i++) {
2173 GstMatroskaTrackContext *stream;
2175 stream = g_ptr_array_index (demux->src, i);
2176 if (stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO && stream->index_table)
2184 gst_matroska_demux_reset_streams (GstMatroskaDemux * demux, GstClockTime time,
2189 GST_DEBUG_OBJECT (demux, "resetting stream state");
2191 g_assert (demux->src->len == demux->num_streams);
2192 for (i = 0; i < demux->src->len; i++) {
2193 GstMatroskaTrackContext *context = g_ptr_array_index (demux->src, i);
2194 context->pos = time;
2195 context->set_discont = TRUE;
2196 context->eos = FALSE;
2197 context->from_time = GST_CLOCK_TIME_NONE;
2199 context->last_flow = GST_FLOW_OK;
2204 gst_matroska_demux_move_to_entry (GstMatroskaDemux * demux,
2205 GstMatroskaIndex * entry, gboolean reset)
2207 GST_OBJECT_LOCK (demux);
2209 /* seek (relative to matroska segment) */
2210 if (gst_ebml_read_seek (GST_EBML_READ (demux),
2211 entry->pos + demux->ebml_segment_start) != GST_FLOW_OK) {
2212 GST_DEBUG_OBJECT (demux, "Failed to seek to offset %" G_GUINT64_FORMAT,
2213 entry->pos + demux->ebml_segment_start);
2217 GST_DEBUG_OBJECT (demux, "Seeked to offset %" G_GUINT64_FORMAT ", block %d, "
2218 "time %" GST_TIME_FORMAT, entry->pos + demux->ebml_segment_start,
2219 entry->block, GST_TIME_ARGS (entry->time));
2221 /* update the time */
2222 gst_matroska_demux_reset_streams (demux, entry->time, TRUE);
2223 demux->segment.last_stop = entry->time;
2224 demux->seek_block = entry->block;
2225 demux->last_stop_end = GST_CLOCK_TIME_NONE;
2228 demux->from_offset = -1;
2229 demux->to_offset = G_MAXINT64;
2232 GST_OBJECT_UNLOCK (demux);
2238 GST_OBJECT_UNLOCK (demux);
2239 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Got a seek error"));
2245 gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
2246 GstPad * pad, GstEvent * event)
2248 GstMatroskaIndex *entry = NULL;
2250 GstSeekType cur_type, stop_type;
2252 gboolean flush, keyunit;
2255 GstMatroskaTrackContext *track = NULL;
2256 GstSegment seeksegment = { 0, };
2260 track = gst_pad_get_element_private (pad);
2262 track = gst_matroska_demux_get_seek_track (demux, track);
2264 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
2267 /* we can only seek on time */
2268 if (format != GST_FORMAT_TIME) {
2269 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
2273 /* copy segment, we need this because we still need the old
2274 * segment when we close the current segment. */
2275 memcpy (&seeksegment, &demux->segment, sizeof (GstSegment));
2278 GST_DEBUG_OBJECT (demux, "configuring seek");
2279 gst_segment_set_seek (&seeksegment, rate, format, flags,
2280 cur_type, cur, stop_type, stop, &update);
2283 GST_DEBUG_OBJECT (demux, "New segment %" GST_SEGMENT_FORMAT, &seeksegment);
2285 /* check sanity before we start flushing and all that */
2286 GST_OBJECT_LOCK (demux);
2287 if ((entry = gst_matroskademux_do_index_seek (demux, track,
2288 seeksegment.last_stop, &demux->seek_index, &demux->seek_entry)) ==
2290 GST_DEBUG_OBJECT (demux, "No matching seek entry in index");
2291 GST_OBJECT_UNLOCK (demux);
2294 GST_DEBUG_OBJECT (demux, "Seek position looks sane");
2295 GST_OBJECT_UNLOCK (demux);
2297 if (demux->streaming) {
2298 /* need to seek to cluster start to pick up cluster time */
2299 /* upstream takes care of flushing and all that
2300 * ... and newsegment event handling takes care of the rest */
2301 return perform_seek_to_offset (demux,
2302 entry->pos + demux->ebml_segment_start);
2305 flush = !!(flags & GST_SEEK_FLAG_FLUSH);
2306 keyunit = !!(flags & GST_SEEK_FLAG_KEY_UNIT);
2309 GST_DEBUG_OBJECT (demux, "Starting flush");
2310 gst_pad_push_event (demux->sinkpad, gst_event_new_flush_start ());
2311 gst_matroska_demux_send_event (demux, gst_event_new_flush_start ());
2313 GST_DEBUG_OBJECT (demux, "Non-flushing seek, pausing task");
2314 gst_pad_pause_task (demux->sinkpad);
2317 /* now grab the stream lock so that streaming cannot continue, for
2318 * non flushing seeks when the element is in PAUSED this could block
2320 GST_DEBUG_OBJECT (demux, "Waiting for streaming to stop");
2321 GST_PAD_STREAM_LOCK (demux->sinkpad);
2324 GST_DEBUG_OBJECT (demux, "seek to key unit, adjusting segment start to %"
2325 GST_TIME_FORMAT, GST_TIME_ARGS (entry->time));
2326 seeksegment.start = entry->time;
2327 seeksegment.last_stop = entry->time;
2328 seeksegment.time = entry->time;
2332 GST_DEBUG_OBJECT (demux, "Stopping flush");
2333 gst_pad_push_event (demux->sinkpad, gst_event_new_flush_stop ());
2334 gst_matroska_demux_send_event (demux, gst_event_new_flush_stop ());
2335 } else if (demux->segment_running) {
2336 GST_DEBUG_OBJECT (demux, "Closing currently running segment");
2338 GST_OBJECT_LOCK (demux);
2339 if (demux->close_segment)
2340 gst_event_unref (demux->close_segment);
2342 demux->close_segment = gst_event_new_new_segment (TRUE,
2343 demux->segment.rate, GST_FORMAT_TIME, demux->segment.start,
2344 demux->segment.last_stop, demux->segment.time);
2345 GST_OBJECT_UNLOCK (demux);
2348 GST_OBJECT_LOCK (demux);
2349 /* now update the real segment info */
2350 GST_DEBUG_OBJECT (demux, "Committing new seek segment");
2351 memcpy (&demux->segment, &seeksegment, sizeof (GstSegment));
2352 GST_OBJECT_UNLOCK (demux);
2354 /* update some (segment) state */
2355 if (!gst_matroska_demux_move_to_entry (demux, entry, TRUE))
2358 /* notify start of new segment */
2359 if (demux->segment.flags & GST_SEEK_FLAG_SEGMENT) {
2362 msg = gst_message_new_segment_start (GST_OBJECT (demux),
2363 GST_FORMAT_TIME, demux->segment.start);
2364 gst_element_post_message (GST_ELEMENT (demux), msg);
2367 GST_OBJECT_LOCK (demux);
2368 if (demux->new_segment)
2369 gst_event_unref (demux->new_segment);
2370 demux->new_segment = gst_event_new_new_segment_full (FALSE,
2371 demux->segment.rate, demux->segment.applied_rate, demux->segment.format,
2372 demux->segment.start, demux->segment.stop, demux->segment.time);
2373 GST_OBJECT_UNLOCK (demux);
2375 /* restart our task since it might have been stopped when we did the
2377 demux->segment_running = TRUE;
2378 gst_pad_start_task (demux->sinkpad, (GstTaskFunction) gst_matroska_demux_loop,
2381 /* streaming can continue now */
2382 GST_PAD_STREAM_UNLOCK (demux->sinkpad);
2388 GST_OBJECT_UNLOCK (demux);
2389 GST_PAD_STREAM_UNLOCK (demux->sinkpad);
2390 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Got a seek error"));
2396 * Handle whether we can perform the seek event or if we have to let the chain
2397 * function handle seeks to build the seek indexes first.
2400 gst_matroska_demux_handle_seek_push (GstMatroskaDemux * demux, GstPad * pad,
2404 GstSeekType cur_type, stop_type;
2409 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
2414 /* we can only seek on time */
2415 if (format != GST_FORMAT_TIME) {
2416 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
2420 if (stop_type != GST_SEEK_TYPE_NONE && stop != GST_CLOCK_TIME_NONE) {
2421 GST_DEBUG_OBJECT (demux, "Seek end-time not supported in streaming mode");
2425 if (!(flags & GST_SEEK_FLAG_FLUSH)) {
2426 GST_DEBUG_OBJECT (demux,
2427 "Non-flushing seek not supported in streaming mode");
2431 if (flags & GST_SEEK_FLAG_SEGMENT) {
2432 GST_DEBUG_OBJECT (demux, "Segment seek not supported in streaming mode");
2436 /* check for having parsed index already */
2437 if (!demux->index_parsed) {
2438 gboolean building_index;
2441 if (!demux->index_offset) {
2442 GST_DEBUG_OBJECT (demux, "no index (location); no seek in push mode");
2446 GST_OBJECT_LOCK (demux);
2447 /* handle the seek event in the chain function */
2448 demux->state = GST_MATROSKA_DEMUX_STATE_SEEK;
2449 /* no more seek can be issued until state reset to _DATA */
2451 /* copy the event */
2452 if (demux->seek_event)
2453 gst_event_unref (demux->seek_event);
2454 demux->seek_event = gst_event_ref (event);
2456 /* set the building_index flag so that only one thread can setup the
2457 * structures for index seeking. */
2458 building_index = demux->building_index;
2459 if (!building_index) {
2460 demux->building_index = TRUE;
2461 offset = demux->index_offset;
2463 GST_OBJECT_UNLOCK (demux);
2465 if (!building_index) {
2466 /* seek to the first subindex or legacy index */
2467 GST_INFO_OBJECT (demux, "Seeking to Cues at %" G_GUINT64_FORMAT, offset);
2468 return perform_seek_to_offset (demux, offset);
2471 /* well, we are handling it already */
2475 /* delegate to tweaked regular seek */
2476 return gst_matroska_demux_handle_seek_event (demux, pad, event);
2480 gst_matroska_demux_handle_src_event (GstPad * pad, GstEvent * event)
2482 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (gst_pad_get_parent (pad));
2483 gboolean res = TRUE;
2485 switch (GST_EVENT_TYPE (event)) {
2486 case GST_EVENT_SEEK:
2487 /* no seeking until we are (safely) ready */
2488 if (demux->state != GST_MATROSKA_DEMUX_STATE_DATA) {
2489 GST_DEBUG_OBJECT (demux, "not ready for seeking yet");
2492 if (!demux->streaming)
2493 res = gst_matroska_demux_handle_seek_event (demux, pad, event);
2495 res = gst_matroska_demux_handle_seek_push (demux, pad, event);
2496 gst_event_unref (event);
2499 /* events we don't need to handle */
2500 case GST_EVENT_NAVIGATION:
2502 gst_event_unref (event);
2506 case GST_EVENT_LATENCY:
2508 res = gst_pad_push_event (demux->sinkpad, event);
2512 gst_object_unref (demux);
2517 static GstFlowReturn
2518 gst_matroska_demux_seek_to_previous_keyframe (GstMatroskaDemux * demux)
2520 GstFlowReturn ret = GST_FLOW_UNEXPECTED;
2521 gboolean done = TRUE;
2524 g_return_val_if_fail (demux->seek_index, GST_FLOW_UNEXPECTED);
2525 g_return_val_if_fail (demux->seek_entry < demux->seek_index->len,
2526 GST_FLOW_UNEXPECTED);
2528 GST_DEBUG_OBJECT (demux, "locating previous keyframe");
2530 if (!demux->seek_entry) {
2531 GST_DEBUG_OBJECT (demux, "no earlier index entry");
2535 for (i = 0; i < demux->src->len; i++) {
2536 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->src, i);
2538 GST_DEBUG_OBJECT (demux, "segment start %" GST_TIME_FORMAT
2539 ", stream %d at %" GST_TIME_FORMAT,
2540 GST_TIME_ARGS (demux->segment.start), stream->index,
2541 GST_TIME_ARGS (stream->from_time));
2542 if (GST_CLOCK_TIME_IS_VALID (stream->from_time)) {
2543 if (stream->from_time > demux->segment.start) {
2544 GST_DEBUG_OBJECT (demux, "stream %d not finished yet", stream->index);
2551 GstMatroskaIndex *entry;
2553 entry = &g_array_index (demux->seek_index, GstMatroskaIndex,
2554 --demux->seek_entry);
2555 if (!gst_matroska_demux_move_to_entry (demux, entry, FALSE))
2557 demux->to_offset = demux->from_offset;
2558 demux->from_offset = -1;
2566 static GstFlowReturn
2567 gst_matroska_demux_parse_header (GstMatroskaDemux * demux)
2569 GstEbmlRead *ebml = GST_EBML_READ (demux);
2574 if ((ret = gst_ebml_read_header (ebml, &doctype, &version)) != GST_FLOW_OK)
2577 ret = GST_FLOW_ERROR;
2579 GEnumClass *doctype_class;
2580 GEnumValue *doctype_value;
2581 doctype_class = g_type_class_ref (GST_TYPE_MATROSKA_DOCTYPE);
2582 doctype_value = g_enum_get_value_by_nick (doctype_class, doctype);
2583 if (doctype_value) {
2585 GST_INFO_OBJECT (demux, "Input is %s version %d", doctype, version);
2588 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
2589 ("Demuxer version (2) is too old to read %s version %d",
2593 GST_ELEMENT_ERROR (demux, STREAM, WRONG_TYPE, (NULL),
2594 ("Input is not a matroska stream (doctype=%s)", doctype));
2596 g_type_class_unref (doctype_class);
2599 GST_ELEMENT_ERROR (demux, STREAM, WRONG_TYPE, (NULL),
2600 ("Input is not a matroska stream"));
2606 static GstFlowReturn
2607 gst_matroska_demux_init_stream (GstMatroskaDemux * demux)
2609 GstEbmlRead *ebml = GST_EBML_READ (demux);
2613 GST_DEBUG_OBJECT (demux, "Init stream");
2615 if ((ret = gst_matroska_demux_parse_header (demux)) != GST_FLOW_OK)
2618 /* find segment, must be the next element but search as long as
2619 * we find it anyway */
2623 if ((ret = gst_ebml_peek_id (ebml, &last_level, &id)) != GST_FLOW_OK) {
2624 GST_DEBUG_OBJECT (demux, "gst_ebml_peek_id() failed!");
2628 if (id == GST_MATROSKA_ID_SEGMENT)
2632 GST_WARNING_OBJECT (demux,
2633 "Expected a Segment ID (0x%x), but received 0x%x!",
2634 GST_MATROSKA_ID_SEGMENT, id);
2636 if ((ret = gst_ebml_read_skip (ebml)) != GST_FLOW_OK)
2640 /* we now have a EBML segment */
2641 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2642 GST_DEBUG_OBJECT (demux, "gst_ebml_read_master() failed!");
2646 GST_DEBUG_OBJECT (demux, "Found Segment start at offset %" G_GUINT64_FORMAT,
2648 /* seeks are from the beginning of the segment,
2649 * after the segment ID/length */
2650 demux->ebml_segment_start = ebml->offset;
2655 static GstFlowReturn
2656 gst_matroska_demux_parse_tracks (GstMatroskaDemux * demux)
2658 GstEbmlRead *ebml = GST_EBML_READ (demux);
2659 GstFlowReturn ret = GST_FLOW_OK;
2662 DEBUG_ELEMENT_START (demux, ebml, "Tracks");
2664 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2665 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
2669 while (ret == GST_FLOW_OK) {
2670 if ((ret = gst_ebml_peek_id (ebml, &demux->level_up, &id)) != GST_FLOW_OK)
2673 if (demux->level_up) {
2679 /* one track within the "all-tracks" header */
2680 case GST_MATROSKA_ID_TRACKENTRY:
2681 ret = gst_matroska_demux_add_stream (demux);
2685 GST_WARNING ("Unknown Track subelement 0x%x - ignoring", id);
2686 ret = gst_ebml_read_skip (ebml);
2690 if (demux->level_up) {
2695 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
2697 demux->tracks_parsed = TRUE;
2702 static GstFlowReturn
2703 gst_matroska_demux_parse_index_cuetrack (GstMatroskaDemux * demux,
2706 GstEbmlRead *ebml = GST_EBML_READ (demux);
2709 GstMatroskaIndex idx;
2711 idx.pos = (guint64) - 1;
2713 idx.time = GST_CLOCK_TIME_NONE;
2716 DEBUG_ELEMENT_START (demux, ebml, "CueTrackPositions");
2718 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2719 DEBUG_ELEMENT_STOP (demux, ebml, "CueTrackPositions", ret);
2723 while (ret == GST_FLOW_OK) {
2724 if ((ret = gst_ebml_peek_id (ebml, &demux->level_up, &id)) != GST_FLOW_OK)
2727 if (demux->level_up) {
2734 case GST_MATROSKA_ID_CUETRACK:
2738 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
2743 GST_WARNING_OBJECT (demux, "Invalid CueTrack 0");
2747 GST_DEBUG_OBJECT (demux, "CueTrack: %" G_GUINT64_FORMAT, num);
2752 /* position in file */
2753 case GST_MATROSKA_ID_CUECLUSTERPOSITION:
2757 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
2760 if (num > G_MAXINT64) {
2761 GST_WARNING_OBJECT (demux, "CueClusterPosition %" G_GUINT64_FORMAT
2770 /* number of block in the cluster */
2771 case GST_MATROSKA_ID_CUEBLOCKNUMBER:
2775 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
2779 GST_WARNING_OBJECT (demux, "Invalid CueBlockNumber 0");
2783 GST_DEBUG_OBJECT (demux, "CueBlockNumber: %" G_GUINT64_FORMAT, num);
2786 /* mild sanity check, disregard strange cases ... */
2787 if (idx.block > G_MAXUINT16) {
2788 GST_DEBUG_OBJECT (demux, "... looks suspicious, ignoring");
2795 GST_WARNING ("Unknown CueTrackPositions subelement 0x%x - ignoring",
2799 case GST_MATROSKA_ID_CUECODECSTATE:
2800 case GST_MATROSKA_ID_CUEREFERENCE:
2801 if ((ret = gst_ebml_read_skip (ebml)) != GST_FLOW_OK)
2806 if (demux->level_up) {
2812 DEBUG_ELEMENT_STOP (demux, ebml, "CueTrackPositions", ret);
2814 if ((ret == GST_FLOW_OK || ret == GST_FLOW_UNEXPECTED)
2815 && idx.pos != (guint64) - 1 && idx.track > 0) {
2816 g_array_append_val (demux->index, idx);
2818 } else if (ret == GST_FLOW_OK || ret == GST_FLOW_UNEXPECTED) {
2819 GST_DEBUG_OBJECT (demux, "CueTrackPositions without valid content");
2825 static GstFlowReturn
2826 gst_matroska_demux_parse_index_pointentry (GstMatroskaDemux * demux)
2828 GstEbmlRead *ebml = GST_EBML_READ (demux);
2831 GstClockTime time = GST_CLOCK_TIME_NONE;
2834 DEBUG_ELEMENT_START (demux, ebml, "CuePoint");
2836 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2837 DEBUG_ELEMENT_STOP (demux, ebml, "CuePoint", ret);
2841 while (ret == GST_FLOW_OK) {
2842 if ((ret = gst_ebml_peek_id (ebml, &demux->level_up, &id)) != GST_FLOW_OK)
2845 if (demux->level_up) {
2851 /* one single index entry ('point') */
2852 case GST_MATROSKA_ID_CUETIME:
2854 if ((ret = gst_ebml_read_uint (ebml, &id, &time)) != GST_FLOW_OK)
2857 GST_DEBUG_OBJECT (demux, "CueTime: %" G_GUINT64_FORMAT, time);
2858 time = time * demux->time_scale;
2862 /* position in the file + track to which it belongs */
2863 case GST_MATROSKA_ID_CUETRACKPOSITIONS:
2866 gst_matroska_demux_parse_index_cuetrack (demux,
2867 &nentries)) != GST_FLOW_OK)
2873 GST_WARNING_OBJECT (demux,
2874 "Unknown CuePoint subelement 0x%x - ignoring", id);
2875 if ((ret = gst_ebml_read_skip (ebml)) != GST_FLOW_OK)
2880 if (demux->level_up) {
2886 DEBUG_ELEMENT_STOP (demux, ebml, "CuePoint", ret);
2889 if (time == GST_CLOCK_TIME_NONE) {
2890 GST_WARNING_OBJECT (demux, "CuePoint without valid time");
2891 g_array_remove_range (demux->index, demux->index->len - nentries,
2896 for (i = demux->index->len - nentries; i < demux->index->len; i++) {
2897 GstMatroskaIndex *idx =
2898 &g_array_index (demux->index, GstMatroskaIndex, i);
2901 GST_DEBUG_OBJECT (demux, "Index entry: pos=%" G_GUINT64_FORMAT
2902 ", time=%" GST_TIME_FORMAT ", track=%u, block=%u", idx->pos,
2903 GST_TIME_ARGS (idx->time), (guint) idx->track, (guint) idx->block);
2907 GST_DEBUG_OBJECT (demux, "Empty CuePoint");
2914 gst_matroska_index_compare (GstMatroskaIndex * i1, GstMatroskaIndex * i2)
2916 if (i1->time < i2->time)
2918 else if (i1->time > i2->time)
2920 else if (i1->block < i2->block)
2922 else if (i1->block > i2->block)
2928 static GstFlowReturn
2929 gst_matroska_demux_parse_index (GstMatroskaDemux * demux)
2931 GstEbmlRead *ebml = GST_EBML_READ (demux);
2933 GstFlowReturn ret = GST_FLOW_OK;
2937 g_array_free (demux->index, TRUE);
2939 g_array_sized_new (FALSE, FALSE, sizeof (GstMatroskaIndex), 128);
2941 DEBUG_ELEMENT_START (demux, ebml, "Cues");
2943 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2944 DEBUG_ELEMENT_STOP (demux, ebml, "Cues", ret);
2948 while (ret == GST_FLOW_OK) {
2949 if ((ret = gst_ebml_peek_id (ebml, &demux->level_up, &id)) != GST_FLOW_OK)
2952 if (demux->level_up) {
2958 /* one single index entry ('point') */
2959 case GST_MATROSKA_ID_POINTENTRY:
2960 ret = gst_matroska_demux_parse_index_pointentry (demux);
2964 GST_WARNING ("Unknown Cues subelement 0x%x - ignoring", id);
2965 ret = gst_ebml_read_skip (ebml);
2969 if (demux->level_up) {
2974 DEBUG_ELEMENT_STOP (demux, ebml, "Cues", ret);
2976 /* Sort index by time, smallest time first, for easier searching */
2977 g_array_sort (demux->index, (GCompareFunc) gst_matroska_index_compare);
2979 /* Now sort the track specific index entries into their own arrays */
2980 for (i = 0; i < demux->index->len; i++) {
2981 GstMatroskaIndex *idx = &g_array_index (demux->index, GstMatroskaIndex, i);
2983 GstMatroskaTrackContext *ctx;
2985 if (demux->element_index) {
2988 if (idx->track != 0 &&
2990 gst_matroska_demux_stream_from_num (demux, idx->track)) != -1) {
2991 ctx = g_ptr_array_index (demux->src, track_num);
2993 if (ctx->index_writer_id == -1)
2994 gst_index_get_writer_id (demux->element_index, GST_OBJECT (ctx->pad),
2995 &ctx->index_writer_id);
2996 writer_id = ctx->index_writer_id;
2998 if (demux->element_index_writer_id == -1)
2999 gst_index_get_writer_id (demux->element_index, GST_OBJECT (demux),
3000 &demux->element_index_writer_id);
3001 writer_id = demux->element_index_writer_id;
3004 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
3005 G_GUINT64_FORMAT " for writer id %d", GST_TIME_ARGS (idx->time),
3006 idx->pos, writer_id);
3007 gst_index_add_association (demux->element_index, writer_id,
3008 GST_ASSOCIATION_FLAG_KEY_UNIT, GST_FORMAT_TIME, idx->time,
3009 GST_FORMAT_BYTES, idx->pos + demux->ebml_segment_start, NULL);
3012 if (idx->track == 0)
3015 track_num = gst_matroska_demux_stream_from_num (demux, idx->track);
3016 if (track_num == -1)
3019 ctx = g_ptr_array_index (demux->src, track_num);
3021 if (ctx->index_table == NULL)
3023 g_array_sized_new (FALSE, FALSE, sizeof (GstMatroskaIndex), 128);
3025 g_array_append_vals (ctx->index_table, idx, 1);
3028 demux->index_parsed = TRUE;
3033 static GstFlowReturn
3034 gst_matroska_demux_parse_info (GstMatroskaDemux * demux)
3036 GstEbmlRead *ebml = GST_EBML_READ (demux);
3037 GstFlowReturn ret = GST_FLOW_OK;
3040 DEBUG_ELEMENT_START (demux, ebml, "SegmentInfo");
3042 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3043 DEBUG_ELEMENT_STOP (demux, ebml, "SegmentInfo", ret);
3047 while (ret == GST_FLOW_OK) {
3048 if ((ret = gst_ebml_peek_id (ebml, &demux->level_up, &id)) != GST_FLOW_OK)
3051 if (demux->level_up) {
3057 /* cluster timecode */
3058 case GST_MATROSKA_ID_TIMECODESCALE:{
3061 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
3065 GST_DEBUG_OBJECT (demux, "TimeCodeScale: %" G_GUINT64_FORMAT, num);
3066 demux->time_scale = num;
3070 case GST_MATROSKA_ID_DURATION:{
3074 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
3078 GST_WARNING_OBJECT (demux, "Invalid duration %lf", num);
3082 GST_DEBUG_OBJECT (demux, "Duration: %lf", num);
3084 dur = gst_gdouble_to_guint64 (num *
3085 gst_guint64_to_gdouble (demux->time_scale));
3086 if (GST_CLOCK_TIME_IS_VALID (dur) && dur <= G_MAXINT64)
3087 gst_segment_set_duration (&demux->segment, GST_FORMAT_TIME, dur);
3091 case GST_MATROSKA_ID_WRITINGAPP:{
3094 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
3097 GST_DEBUG_OBJECT (demux, "WritingApp: %s", GST_STR_NULL (text));
3098 demux->writing_app = text;
3102 case GST_MATROSKA_ID_MUXINGAPP:{
3105 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
3108 GST_DEBUG_OBJECT (demux, "MuxingApp: %s", GST_STR_NULL (text));
3109 demux->muxing_app = text;
3113 case GST_MATROSKA_ID_DATEUTC:{
3116 if ((ret = gst_ebml_read_date (ebml, &id, &time)) != GST_FLOW_OK)
3119 GST_DEBUG_OBJECT (demux, "DateUTC: %" G_GINT64_FORMAT, time);
3120 demux->created = time;
3124 case GST_MATROSKA_ID_TITLE:{
3126 GstTagList *taglist;
3128 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
3131 GST_DEBUG_OBJECT (demux, "Title: %s", GST_STR_NULL (text));
3132 taglist = gst_tag_list_new ();
3133 gst_tag_list_add (taglist, GST_TAG_MERGE_APPEND, GST_TAG_TITLE, text,
3135 gst_matroska_demux_found_global_tag (demux, taglist);
3141 GST_WARNING_OBJECT (demux,
3142 "Unknown SegmentInfo subelement 0x%x - ignoring", id);
3145 case GST_MATROSKA_ID_SEGMENTUID:
3146 case GST_MATROSKA_ID_SEGMENTFILENAME:
3147 case GST_MATROSKA_ID_PREVUID:
3148 case GST_MATROSKA_ID_PREVFILENAME:
3149 case GST_MATROSKA_ID_NEXTUID:
3150 case GST_MATROSKA_ID_NEXTFILENAME:
3151 case GST_MATROSKA_ID_SEGMENTFAMILY:
3152 case GST_MATROSKA_ID_CHAPTERTRANSLATE:
3153 ret = gst_ebml_read_skip (ebml);
3157 if (demux->level_up) {
3163 DEBUG_ELEMENT_STOP (demux, ebml, "SegmentInfo", ret);
3165 demux->segmentinfo_parsed = TRUE;
3170 static GstFlowReturn
3171 gst_matroska_demux_parse_metadata_id_simple_tag (GstMatroskaDemux * demux,
3172 GstTagList ** p_taglist)
3174 /* FIXME: check if there are more useful mappings */
3177 const gchar *matroska_tagname;
3178 const gchar *gstreamer_tagname;
3182 GST_MATROSKA_TAG_ID_TITLE, GST_TAG_TITLE}, {
3183 GST_MATROSKA_TAG_ID_AUTHOR, GST_TAG_ARTIST}, {
3184 GST_MATROSKA_TAG_ID_ALBUM, GST_TAG_ALBUM}, {
3185 GST_MATROSKA_TAG_ID_COMMENTS, GST_TAG_COMMENT}, {
3186 GST_MATROSKA_TAG_ID_BITSPS, GST_TAG_BITRATE}, {
3187 GST_MATROSKA_TAG_ID_BPS, GST_TAG_BITRATE}, {
3188 GST_MATROSKA_TAG_ID_ENCODER, GST_TAG_ENCODER}, {
3189 GST_MATROSKA_TAG_ID_DATE, GST_TAG_DATE}, {
3190 GST_MATROSKA_TAG_ID_ISRC, GST_TAG_ISRC}, {
3191 GST_MATROSKA_TAG_ID_COPYRIGHT, GST_TAG_COPYRIGHT}, {
3192 GST_MATROSKA_TAG_ID_BPM, GST_TAG_BEATS_PER_MINUTE}, {
3193 GST_MATROSKA_TAG_ID_TERMS_OF_USE, GST_TAG_LICENSE}, {
3194 GST_MATROSKA_TAG_ID_COMPOSER, GST_TAG_COMPOSER}, {
3195 GST_MATROSKA_TAG_ID_LEAD_PERFORMER, GST_TAG_PERFORMER}, {
3196 GST_MATROSKA_TAG_ID_GENRE, GST_TAG_GENRE}
3198 GstEbmlRead *ebml = GST_EBML_READ (demux);
3201 gchar *value = NULL;
3204 DEBUG_ELEMENT_START (demux, ebml, "SimpleTag");
3206 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3207 DEBUG_ELEMENT_STOP (demux, ebml, "SimpleTag", ret);
3211 while (ret == GST_FLOW_OK) {
3212 /* read all sub-entries */
3214 if ((ret = gst_ebml_peek_id (ebml, &demux->level_up, &id)) != GST_FLOW_OK)
3217 if (demux->level_up) {
3223 case GST_MATROSKA_ID_TAGNAME:
3226 ret = gst_ebml_read_ascii (ebml, &id, &tag);
3227 GST_DEBUG_OBJECT (demux, "TagName: %s", GST_STR_NULL (tag));
3230 case GST_MATROSKA_ID_TAGSTRING:
3233 ret = gst_ebml_read_utf8 (ebml, &id, &value);
3234 GST_DEBUG_OBJECT (demux, "TagString: %s", GST_STR_NULL (value));
3238 GST_WARNING_OBJECT (demux,
3239 "Unknown SimpleTag subelement 0x%x - ignoring", id);
3242 case GST_MATROSKA_ID_TAGLANGUAGE:
3243 case GST_MATROSKA_ID_TAGDEFAULT:
3244 case GST_MATROSKA_ID_TAGBINARY:
3245 ret = gst_ebml_read_skip (ebml);
3249 if (demux->level_up) {
3255 DEBUG_ELEMENT_STOP (demux, ebml, "SimpleTag", ret);
3260 for (i = 0; i < G_N_ELEMENTS (tag_conv); i++) {
3261 const gchar *tagname_gst = tag_conv[i].gstreamer_tagname;
3263 const gchar *tagname_mkv = tag_conv[i].matroska_tagname;
3265 if (strcmp (tagname_mkv, tag) == 0) {
3266 GValue dest = { 0, };
3267 GType dest_type = gst_tag_get_type (tagname_gst);
3269 g_value_init (&dest, dest_type);
3270 if (gst_value_deserialize (&dest, value)) {
3271 gst_tag_list_add_values (*p_taglist, GST_TAG_MERGE_APPEND,
3272 tagname_gst, &dest, NULL);
3274 GST_WARNING_OBJECT (demux, "Can't transform tag '%s' with "
3275 "value '%s' to target type '%s'", tag, value,
3276 g_type_name (dest_type));
3278 g_value_unset (&dest);
3290 static GstFlowReturn
3291 gst_matroska_demux_parse_metadata_id_tag (GstMatroskaDemux * demux,
3292 GstTagList ** p_taglist)
3294 GstEbmlRead *ebml = GST_EBML_READ (demux);
3298 DEBUG_ELEMENT_START (demux, ebml, "Tag");
3300 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3301 DEBUG_ELEMENT_STOP (demux, ebml, "Tag", ret);
3305 while (ret == GST_FLOW_OK) {
3306 /* read all sub-entries */
3308 if ((ret = gst_ebml_peek_id (ebml, &demux->level_up, &id)) != GST_FLOW_OK)
3311 if (demux->level_up) {
3317 case GST_MATROSKA_ID_SIMPLETAG:
3319 gst_matroska_demux_parse_metadata_id_simple_tag (demux, p_taglist);
3323 GST_WARNING_OBJECT (demux, "Unknown Tag subelement 0x%x - ignoring",
3325 ret = gst_ebml_read_skip (ebml);
3329 if (demux->level_up) {
3335 DEBUG_ELEMENT_STOP (demux, ebml, "Tag", ret);
3340 static GstFlowReturn
3341 gst_matroska_demux_parse_metadata (GstMatroskaDemux * demux)
3343 GstEbmlRead *ebml = GST_EBML_READ (demux);
3344 GstTagList *taglist;
3345 GstFlowReturn ret = GST_FLOW_OK;
3348 GstEbmlLevel *curlevel;
3350 if (ebml->level == NULL) {
3351 GST_ERROR_OBJECT (demux, "Unexpected metadata, bailing");
3352 return GST_FLOW_ERROR;
3354 curlevel = ebml->level->data;
3356 /* Make sure we don't parse a tags element twice and
3357 * post it's tags twice */
3358 for (l = demux->tags_parsed; l; l = l->next) {
3359 GstEbmlLevel *level = l->data;
3362 curlevel = ebml->level->data;
3366 if (level->start == curlevel->start && level->length == curlevel->length) {
3367 GST_DEBUG_OBJECT (demux, "Skipping already parsed Tags at offset %"
3368 G_GUINT64_FORMAT, ebml->offset);
3369 ret = gst_ebml_read_skip (ebml);
3374 DEBUG_ELEMENT_START (demux, ebml, "Tags");
3376 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3377 DEBUG_ELEMENT_STOP (demux, ebml, "Tags", ret);
3381 taglist = gst_tag_list_new ();
3383 /* TODO: g_slice_dup() if we depend on GLib 2.14 */
3384 curlevel = g_slice_new (GstEbmlLevel);
3385 memcpy (curlevel, ebml->level->data, sizeof (GstEbmlLevel));
3386 demux->tags_parsed = g_list_prepend (demux->tags_parsed, curlevel);
3388 while (ret == GST_FLOW_OK) {
3389 if ((ret = gst_ebml_peek_id (ebml, &demux->level_up, &id)) != GST_FLOW_OK)
3392 if (demux->level_up) {
3398 case GST_MATROSKA_ID_TAG:
3399 ret = gst_matroska_demux_parse_metadata_id_tag (demux, &taglist);
3403 GST_WARNING_OBJECT (demux, "Unknown Tags subelement 0x%x - ignoring",
3405 /* FIXME: Use to limit the tags to specific pads */
3406 case GST_MATROSKA_ID_TARGETS:
3407 ret = gst_ebml_read_skip (ebml);
3411 if (demux->level_up) {
3417 DEBUG_ELEMENT_STOP (demux, ebml, "Tags", ret);
3419 gst_matroska_demux_found_global_tag (demux, taglist);
3424 static GstFlowReturn
3425 gst_matroska_demux_parse_attached_file (GstMatroskaDemux * demux,
3426 GstTagList * taglist)
3428 GstEbmlRead *ebml = GST_EBML_READ (demux);
3431 gchar *description = NULL;
3432 gchar *filename = NULL;
3433 gchar *mimetype = NULL;
3434 guint8 *data = NULL;
3435 guint64 datalen = 0;
3437 DEBUG_ELEMENT_START (demux, ebml, "AttachedFile");
3439 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3440 DEBUG_ELEMENT_STOP (demux, ebml, "AttachedFile", ret);
3444 while (ret == GST_FLOW_OK) {
3445 /* read all sub-entries */
3447 if ((ret = gst_ebml_peek_id (ebml, &demux->level_up, &id)) != GST_FLOW_OK)
3450 if (demux->level_up) {
3456 case GST_MATROSKA_ID_FILEDESCRIPTION:
3458 GST_WARNING_OBJECT (demux, "FileDescription can only appear once");
3462 ret = gst_ebml_read_utf8 (ebml, &id, &description);
3463 GST_DEBUG_OBJECT (demux, "FileDescription: %s",
3464 GST_STR_NULL (description));
3466 case GST_MATROSKA_ID_FILENAME:
3468 GST_WARNING_OBJECT (demux, "FileName can only appear once");
3472 ret = gst_ebml_read_utf8 (ebml, &id, &filename);
3474 GST_DEBUG_OBJECT (demux, "FileName: %s", GST_STR_NULL (filename));
3476 case GST_MATROSKA_ID_FILEMIMETYPE:
3478 GST_WARNING_OBJECT (demux, "FileMimeType can only appear once");
3482 ret = gst_ebml_read_ascii (ebml, &id, &mimetype);
3483 GST_DEBUG_OBJECT (demux, "FileMimeType: %s", GST_STR_NULL (mimetype));
3485 case GST_MATROSKA_ID_FILEDATA:
3487 GST_WARNING_OBJECT (demux, "FileData can only appear once");
3491 ret = gst_ebml_read_binary (ebml, &id, &data, &datalen);
3492 GST_DEBUG_OBJECT (demux, "FileData of size %" G_GUINT64_FORMAT,
3497 GST_WARNING_OBJECT (demux,
3498 "Unknown AttachedFile subelement 0x%x - ignoring", id);
3500 case GST_MATROSKA_ID_FILEUID:
3501 ret = gst_ebml_read_skip (ebml);
3505 if (demux->level_up) {
3511 DEBUG_ELEMENT_STOP (demux, ebml, "AttachedFile", ret);
3513 if (filename && mimetype && data && datalen > 0) {
3514 GstTagImageType image_type = GST_TAG_IMAGE_TYPE_NONE;
3515 GstBuffer *tagbuffer = NULL;
3517 gchar *filename_lc = g_utf8_strdown (filename, -1);
3519 GST_DEBUG_OBJECT (demux, "Creating tag for attachment with filename '%s', "
3520 "mimetype '%s', description '%s', size %" G_GUINT64_FORMAT, filename,
3521 mimetype, GST_STR_NULL (description), datalen);
3523 /* TODO: better heuristics for different image types */
3524 if (strstr (filename_lc, "cover")) {
3525 if (strstr (filename_lc, "back"))
3526 image_type = GST_TAG_IMAGE_TYPE_BACK_COVER;
3528 image_type = GST_TAG_IMAGE_TYPE_FRONT_COVER;
3529 } else if (g_str_has_prefix (mimetype, "image/") ||
3530 g_str_has_suffix (filename_lc, "png") ||
3531 g_str_has_suffix (filename_lc, "jpg") ||
3532 g_str_has_suffix (filename_lc, "jpeg") ||
3533 g_str_has_suffix (filename_lc, "gif") ||
3534 g_str_has_suffix (filename_lc, "bmp")) {
3535 image_type = GST_TAG_IMAGE_TYPE_UNDEFINED;
3537 g_free (filename_lc);
3539 /* First try to create an image tag buffer from this */
3540 if (image_type != GST_TAG_IMAGE_TYPE_NONE) {
3542 gst_tag_image_data_to_image_buffer (data, datalen, image_type);
3545 image_type = GST_TAG_IMAGE_TYPE_NONE;
3548 /* if this failed create an attachment buffer */
3550 tagbuffer = gst_buffer_new_and_alloc (datalen);
3552 memcpy (GST_BUFFER_DATA (tagbuffer), data, datalen);
3553 GST_BUFFER_SIZE (tagbuffer) = datalen;
3555 caps = gst_type_find_helper_for_buffer (NULL, tagbuffer, NULL);
3557 caps = gst_caps_new_simple (mimetype, NULL);
3558 gst_buffer_set_caps (tagbuffer, caps);
3559 gst_caps_unref (caps);
3562 /* Set filename and description on the caps */
3563 caps = GST_BUFFER_CAPS (tagbuffer);
3564 gst_caps_set_simple (caps, "filename", G_TYPE_STRING, filename, NULL);
3566 gst_caps_set_simple (caps, "description", G_TYPE_STRING, description,
3569 GST_DEBUG_OBJECT (demux,
3570 "Created attachment buffer with caps: %" GST_PTR_FORMAT, caps);
3572 /* and append to the tag list */
3573 if (image_type != GST_TAG_IMAGE_TYPE_NONE)
3574 gst_tag_list_add (taglist, GST_TAG_MERGE_APPEND, GST_TAG_IMAGE, tagbuffer,
3577 gst_tag_list_add (taglist, GST_TAG_MERGE_APPEND, GST_TAG_ATTACHMENT,
3584 g_free (description);
3589 static GstFlowReturn
3590 gst_matroska_demux_parse_attachments (GstMatroskaDemux * demux)
3592 GstEbmlRead *ebml = GST_EBML_READ (demux);
3594 GstFlowReturn ret = GST_FLOW_OK;
3595 GstTagList *taglist;
3597 DEBUG_ELEMENT_START (demux, ebml, "Attachments");
3599 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3600 DEBUG_ELEMENT_STOP (demux, ebml, "Attachments", ret);
3604 taglist = gst_tag_list_new ();
3606 while (ret == GST_FLOW_OK) {
3607 if ((ret = gst_ebml_peek_id (ebml, &demux->level_up, &id)) != GST_FLOW_OK)
3610 if (demux->level_up) {
3616 case GST_MATROSKA_ID_ATTACHEDFILE:
3617 ret = gst_matroska_demux_parse_attached_file (demux, taglist);
3621 GST_WARNING ("Unknown Attachments subelement 0x%x - ignoring", id);
3622 ret = gst_ebml_read_skip (ebml);
3626 if (demux->level_up) {
3631 DEBUG_ELEMENT_STOP (demux, ebml, "Attachments", ret);
3633 if (gst_structure_n_fields (GST_STRUCTURE (taglist)) > 0) {
3634 GST_DEBUG_OBJECT (demux, "Storing attachment tags");
3635 gst_matroska_demux_found_global_tag (demux, taglist);
3637 GST_DEBUG_OBJECT (demux, "No valid attachments found");
3638 gst_tag_list_free (taglist);
3641 demux->attachments_parsed = TRUE;
3646 static GstFlowReturn
3647 gst_matroska_demux_parse_chapters (GstMatroskaDemux * demux)
3649 GstEbmlRead *ebml = GST_EBML_READ (demux);
3651 GstFlowReturn ret = GST_FLOW_OK;
3653 GST_WARNING_OBJECT (demux, "Parsing of chapters not implemented yet");
3655 /* TODO: implement parsing of chapters */
3657 DEBUG_ELEMENT_START (demux, ebml, "Chapters");
3659 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3660 DEBUG_ELEMENT_STOP (demux, ebml, "Chapters", ret);
3664 while (ret == GST_FLOW_OK) {
3665 if ((ret = gst_ebml_peek_id (ebml, &demux->level_up, &id)) != GST_FLOW_OK)
3668 if (demux->level_up) {
3675 ret = gst_ebml_read_skip (ebml);
3679 if (demux->level_up) {
3685 DEBUG_ELEMENT_STOP (demux, ebml, "Chapters", ret);
3690 * Read signed/unsigned "EBML" numbers.
3691 * Return: number of bytes processed.
3695 gst_matroska_ebmlnum_uint (guint8 * data, guint size, guint64 * num)
3697 gint len_mask = 0x80, read = 1, n = 1, num_ffs = 0;
3705 while (read <= 8 && !(total & len_mask)) {
3712 if ((total &= (len_mask - 1)) == len_mask - 1)
3717 if (data[n] == 0xff)
3719 total = (total << 8) | data[n];
3723 if (read == num_ffs && total != 0)
3732 gst_matroska_ebmlnum_sint (guint8 * data, guint size, gint64 * num)
3737 /* read as unsigned number first */
3738 if ((res = gst_matroska_ebmlnum_uint (data, size, &unum)) < 0)
3742 if (unum == G_MAXUINT64)
3745 *num = unum - ((1 << ((7 * res) - 1)) - 1);
3751 * Mostly used for subtitles. We add void filler data for each
3752 * lagging stream to make sure we don't deadlock.
3756 gst_matroska_demux_sync_streams (GstMatroskaDemux * demux)
3760 GST_LOG_OBJECT (demux, "Sync to %" GST_TIME_FORMAT,
3761 GST_TIME_ARGS (demux->segment.last_stop));
3763 g_assert (demux->num_streams == demux->src->len);
3764 for (stream_nr = 0; stream_nr < demux->src->len; stream_nr++) {
3765 GstMatroskaTrackContext *context;
3767 context = g_ptr_array_index (demux->src, stream_nr);
3769 GST_LOG_OBJECT (demux,
3770 "Checking for resync on stream %d (%" GST_TIME_FORMAT ")", stream_nr,
3771 GST_TIME_ARGS (context->pos));
3773 if (G_LIKELY (context->type != GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
3774 GST_LOG_OBJECT (demux, "Skipping sync on non-subtitle stream");
3778 /* does it lag? 0.5 seconds is a random threshold...
3779 * lag need only be considered if we have advanced into requested segment */
3780 if (GST_CLOCK_TIME_IS_VALID (context->pos) &&
3781 GST_CLOCK_TIME_IS_VALID (demux->segment.last_stop) &&
3782 demux->segment.last_stop > demux->segment.start &&
3783 context->pos + (GST_SECOND / 2) < demux->segment.last_stop) {
3786 new_start = demux->segment.last_stop - (GST_SECOND / 2);
3787 if (GST_CLOCK_TIME_IS_VALID (demux->segment.stop))
3788 new_start = MIN (new_start, demux->segment.stop);
3789 GST_DEBUG_OBJECT (demux,
3790 "Synchronizing stream %d with others by advancing time " "from %"
3791 GST_TIME_FORMAT " to %" GST_TIME_FORMAT, stream_nr,
3792 GST_TIME_ARGS (context->pos), GST_TIME_ARGS (new_start));
3794 context->pos = new_start;
3796 /* advance stream time */
3797 gst_pad_push_event (context->pad,
3798 gst_event_new_new_segment (TRUE, demux->segment.rate,
3799 demux->segment.format, new_start,
3800 demux->segment.stop, new_start));
3805 static GstFlowReturn
3806 gst_matroska_demux_push_hdr_buf (GstMatroskaDemux * demux,
3807 GstMatroskaTrackContext * stream, guint8 * data, guint len)
3809 GstFlowReturn ret, cret;
3810 GstBuffer *header_buf = NULL;
3812 ret = gst_pad_alloc_buffer_and_set_caps (stream->pad,
3813 GST_BUFFER_OFFSET_NONE, len, stream->caps, &header_buf);
3815 /* we combine but don't use the combined value to check if we have a buffer
3816 * or not. The combined value is what we return. */
3817 cret = gst_matroska_demux_combine_flows (demux, stream, ret);
3818 if (ret != GST_FLOW_OK)
3821 memcpy (GST_BUFFER_DATA (header_buf), data, len);
3823 if (stream->set_discont) {
3824 GST_BUFFER_FLAG_SET (header_buf, GST_BUFFER_FLAG_DISCONT);
3825 stream->set_discont = FALSE;
3828 ret = gst_pad_push (stream->pad, header_buf);
3831 cret = gst_matroska_demux_combine_flows (demux, stream, ret);
3838 GST_DEBUG_OBJECT (demux, "could not alloc buffer: %s, combined %s",
3839 gst_flow_get_name (ret), gst_flow_get_name (cret));
3844 static GstFlowReturn
3845 gst_matroska_demux_push_flac_codec_priv_data (GstMatroskaDemux * demux,
3846 GstMatroskaTrackContext * stream)
3852 GST_LOG_OBJECT (demux, "priv data size = %u", stream->codec_priv_size);
3854 pdata = (guint8 *) stream->codec_priv;
3856 /* need at least 'fLaC' marker + STREAMINFO metadata block */
3857 if (stream->codec_priv_size < ((4) + (4 + 34))) {
3858 GST_WARNING_OBJECT (demux, "not enough codec priv data for flac headers");
3859 return GST_FLOW_ERROR;
3862 if (memcmp (pdata, "fLaC", 4) != 0) {
3863 GST_WARNING_OBJECT (demux, "no flac marker at start of stream headers");
3864 return GST_FLOW_ERROR;
3867 ret = gst_matroska_demux_push_hdr_buf (demux, stream, pdata, 4);
3868 if (ret != GST_FLOW_OK)
3871 off = 4; /* skip fLaC marker */
3872 while (off < stream->codec_priv_size) {
3873 len = GST_READ_UINT8 (pdata + off + 1) << 16;
3874 len |= GST_READ_UINT8 (pdata + off + 2) << 8;
3875 len |= GST_READ_UINT8 (pdata + off + 3);
3877 GST_DEBUG_OBJECT (demux, "header packet: len=%u bytes, flags=0x%02x",
3878 len, (guint) pdata[off]);
3880 ret = gst_matroska_demux_push_hdr_buf (demux, stream, pdata + off, len + 4);
3881 if (ret != GST_FLOW_OK)
3889 static GstFlowReturn
3890 gst_matroska_demux_push_speex_codec_priv_data (GstMatroskaDemux * demux,
3891 GstMatroskaTrackContext * stream)
3896 GST_LOG_OBJECT (demux, "priv data size = %u", stream->codec_priv_size);
3898 pdata = (guint8 *) stream->codec_priv;
3900 /* need at least 'fLaC' marker + STREAMINFO metadata block */
3901 if (stream->codec_priv_size < 80) {
3902 GST_WARNING_OBJECT (demux, "not enough codec priv data for speex headers");
3903 return GST_FLOW_ERROR;
3906 if (memcmp (pdata, "Speex ", 8) != 0) {
3907 GST_WARNING_OBJECT (demux, "no Speex marker at start of stream headers");
3908 return GST_FLOW_ERROR;
3911 ret = gst_matroska_demux_push_hdr_buf (demux, stream, pdata, 80);
3912 if (ret != GST_FLOW_OK)
3915 if (stream->codec_priv_size == 80)
3918 return gst_matroska_demux_push_hdr_buf (demux, stream, pdata + 80,
3919 stream->codec_priv_size - 80);
3922 static GstFlowReturn
3923 gst_matroska_demux_push_xiph_codec_priv_data (GstMatroskaDemux * demux,
3924 GstMatroskaTrackContext * stream)
3927 guint8 *p = (guint8 *) stream->codec_priv;
3928 gint i, offset, num_packets;
3929 guint *length, last;
3931 /* start of the stream and vorbis audio or theora video, need to
3932 * send the codec_priv data as first three packets */
3933 num_packets = p[0] + 1;
3934 GST_DEBUG_OBJECT (demux, "%u stream headers, total length=%u bytes",
3935 (guint) num_packets, stream->codec_priv_size);
3937 length = g_alloca (num_packets * sizeof (guint));
3941 /* first packets, read length values */
3942 for (i = 0; i < num_packets - 1; i++) {
3944 while (offset < stream->codec_priv_size) {
3945 length[i] += p[offset];
3946 if (p[offset++] != 0xff)
3951 if (offset + last > stream->codec_priv_size)
3952 return GST_FLOW_ERROR;
3954 /* last packet is the remaining size */
3955 length[i] = stream->codec_priv_size - offset - last;
3957 for (i = 0; i < num_packets; i++) {
3958 GST_DEBUG_OBJECT (demux, "buffer %d: length=%u bytes", i,
3960 if (offset + length[i] > stream->codec_priv_size)
3961 return GST_FLOW_ERROR;
3964 gst_matroska_demux_push_hdr_buf (demux, stream, p + offset, length[i]);
3965 if (ret != GST_FLOW_OK)
3968 offset += length[i];
3974 gst_matroska_demux_push_dvd_clut_change_event (GstMatroskaDemux * demux,
3975 GstMatroskaTrackContext * stream)
3979 g_assert (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB));
3981 if (!stream->codec_priv)
3984 /* ideally, VobSub private data should be parsed and stored more convenient
3985 * elsewhere, but for now, only interested in a small part */
3987 /* make sure we have terminating 0 */
3988 buf = g_strndup ((gchar *) stream->codec_priv, stream->codec_priv_size);
3990 /* just locate and parse palette part */
3991 start = strstr (buf, "palette:");
3996 guint8 r, g, b, y, u, v;
3999 while (g_ascii_isspace (*start))
4001 for (i = 0; i < 16; i++) {
4002 if (sscanf (start, "%06x", &col) != 1)
4005 while ((*start == ',') || g_ascii_isspace (*start))
4007 /* sigh, need to convert this from vobsub pseudo-RGB to YUV */
4008 r = (col >> 16) & 0xff;
4009 g = (col >> 8) & 0xff;
4011 y = CLAMP ((0.1494 * r + 0.6061 * g + 0.2445 * b) * 219 / 255 + 16, 0,
4013 u = CLAMP (0.6066 * r - 0.4322 * g - 0.1744 * b + 128, 0, 255);
4014 v = CLAMP (-0.08435 * r - 0.3422 * g + 0.4266 * b + 128, 0, 255);
4015 clut[i] = (y << 16) | (u << 8) | v;
4018 /* got them all without problems; build and send event */
4022 s = gst_structure_new ("application/x-gst-dvd", "event", G_TYPE_STRING,
4023 "dvd-spu-clut-change", "clut00", G_TYPE_INT, clut[0], "clut01",
4024 G_TYPE_INT, clut[1], "clut02", G_TYPE_INT, clut[2], "clut03",
4025 G_TYPE_INT, clut[3], "clut04", G_TYPE_INT, clut[4], "clut05",
4026 G_TYPE_INT, clut[5], "clut06", G_TYPE_INT, clut[6], "clut07",
4027 G_TYPE_INT, clut[7], "clut08", G_TYPE_INT, clut[8], "clut09",
4028 G_TYPE_INT, clut[9], "clut10", G_TYPE_INT, clut[10], "clut11",
4029 G_TYPE_INT, clut[11], "clut12", G_TYPE_INT, clut[12], "clut13",
4030 G_TYPE_INT, clut[13], "clut14", G_TYPE_INT, clut[14], "clut15",
4031 G_TYPE_INT, clut[15], NULL);
4033 gst_pad_push_event (stream->pad,
4034 gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM, s));
4040 static GstFlowReturn
4041 gst_matroska_demux_add_mpeg_seq_header (GstElement * element,
4042 GstMatroskaTrackContext * stream, GstBuffer ** buf)
4044 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
4046 guint seq_header_len;
4049 if (stream->codec_state) {
4050 seq_header = stream->codec_state;
4051 seq_header_len = stream->codec_state_size;
4052 } else if (stream->codec_priv) {
4053 seq_header = stream->codec_priv;
4054 seq_header_len = stream->codec_priv_size;
4059 /* Sequence header only needed for keyframes */
4060 if (GST_BUFFER_FLAG_IS_SET (*buf, GST_BUFFER_FLAG_DELTA_UNIT))
4063 if (GST_BUFFER_SIZE (*buf) < 4)
4066 header = GST_READ_UINT32_BE (GST_BUFFER_DATA (*buf));
4067 /* Sequence start code, if not found prepend */
4068 if (header != 0x000001b3) {
4070 GstFlowReturn ret, cret;
4072 ret = gst_pad_alloc_buffer_and_set_caps (stream->pad,
4073 GST_BUFFER_OFFSET_NONE, GST_BUFFER_SIZE (*buf) + seq_header_len,
4074 stream->caps, &newbuf);
4075 cret = gst_matroska_demux_combine_flows (demux, stream, ret);
4076 if (ret != GST_FLOW_OK) {
4077 GST_WARNING_OBJECT (demux, "Reallocating buffer for sequence header "
4078 "failed: %s, combined flow return: %s", gst_flow_get_name (ret),
4079 gst_flow_get_name (cret));
4083 GST_DEBUG_OBJECT (demux, "Prepending MPEG sequence header");
4084 gst_buffer_copy_metadata (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
4085 GST_BUFFER_COPY_FLAGS);
4086 g_memmove (GST_BUFFER_DATA (newbuf), seq_header, seq_header_len);
4087 g_memmove (GST_BUFFER_DATA (newbuf) + seq_header_len,
4088 GST_BUFFER_DATA (*buf), GST_BUFFER_SIZE (*buf));
4089 gst_buffer_unref (*buf);
4096 static GstFlowReturn
4097 gst_matroska_demux_add_wvpk_header (GstElement * element,
4098 GstMatroskaTrackContext * stream, GstBuffer ** buf)
4100 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
4101 GstMatroskaTrackAudioContext *audiocontext =
4102 (GstMatroskaTrackAudioContext *) stream;
4103 GstBuffer *newbuf = NULL;
4106 GstFlowReturn ret, cret = GST_FLOW_OK;
4114 wvh.version = GST_READ_UINT16_LE (stream->codec_priv);
4117 wvh.total_samples = -1;
4118 wvh.block_index = audiocontext->wvpk_block_index;
4120 if (audiocontext->channels <= 2) {
4121 guint32 block_samples;
4123 block_samples = GST_READ_UINT32_LE (GST_BUFFER_DATA (*buf));
4124 /* we need to reconstruct the header of the wavpack block */
4126 /* -20 because ck_size is the size of the wavpack block -8
4127 * and lace_size is the size of the wavpack block + 12
4128 * (the three guint32 of the header that already are in the buffer) */
4129 wvh.ck_size = GST_BUFFER_SIZE (*buf) + sizeof (Wavpack4Header) - 20;
4131 /* block_samples, flags and crc are already in the buffer */
4132 newlen = GST_BUFFER_SIZE (*buf) + sizeof (Wavpack4Header) - 12;
4134 gst_pad_alloc_buffer_and_set_caps (stream->pad, GST_BUFFER_OFFSET_NONE,
4135 newlen, stream->caps, &newbuf);
4136 cret = gst_matroska_demux_combine_flows (demux, stream, ret);
4137 if (ret != GST_FLOW_OK) {
4138 GST_DEBUG_OBJECT (demux, "pad_alloc failed %s, combined %s",
4139 gst_flow_get_name (ret), gst_flow_get_name (cret));
4143 data = GST_BUFFER_DATA (newbuf);
4148 GST_WRITE_UINT32_LE (data + 4, wvh.ck_size);
4149 GST_WRITE_UINT16_LE (data + 8, wvh.version);
4150 GST_WRITE_UINT8 (data + 10, wvh.track_no);
4151 GST_WRITE_UINT8 (data + 11, wvh.index_no);
4152 GST_WRITE_UINT32_LE (data + 12, wvh.total_samples);
4153 GST_WRITE_UINT32_LE (data + 16, wvh.block_index);
4154 g_memmove (data + 20, GST_BUFFER_DATA (*buf), GST_BUFFER_SIZE (*buf));
4155 gst_buffer_copy_metadata (newbuf, *buf,
4156 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS);
4157 gst_buffer_unref (*buf);
4159 audiocontext->wvpk_block_index += block_samples;
4164 guint32 block_samples, flags, crc, blocksize;
4166 data = GST_BUFFER_DATA (*buf);
4167 size = GST_BUFFER_SIZE (*buf);
4170 GST_ERROR_OBJECT (demux, "Too small wavpack buffer");
4171 return GST_FLOW_ERROR;
4174 block_samples = GST_READ_UINT32_LE (data);
4179 flags = GST_READ_UINT32_LE (data);
4182 crc = GST_READ_UINT32_LE (data);
4185 blocksize = GST_READ_UINT32_LE (data);
4189 if (blocksize == 0 || size < blocksize)
4192 if (newbuf == NULL) {
4193 newbuf = gst_buffer_new_and_alloc (sizeof (Wavpack4Header) + blocksize);
4194 gst_buffer_set_caps (newbuf, stream->caps);
4196 gst_buffer_copy_metadata (newbuf, *buf,
4197 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS);
4200 outdata = GST_BUFFER_DATA (newbuf);
4202 GST_BUFFER_SIZE (newbuf) += sizeof (Wavpack4Header) + blocksize;
4203 GST_BUFFER_DATA (newbuf) =
4204 g_realloc (GST_BUFFER_DATA (newbuf), GST_BUFFER_SIZE (newbuf));
4205 GST_BUFFER_MALLOCDATA (newbuf) = GST_BUFFER_DATA (newbuf);
4206 outdata = GST_BUFFER_DATA (newbuf);
4209 outdata[outpos] = 'w';
4210 outdata[outpos + 1] = 'v';
4211 outdata[outpos + 2] = 'p';
4212 outdata[outpos + 3] = 'k';
4215 GST_WRITE_UINT32_LE (outdata + outpos,
4216 blocksize + sizeof (Wavpack4Header) - 8);
4217 GST_WRITE_UINT16_LE (outdata + outpos + 4, wvh.version);
4218 GST_WRITE_UINT8 (outdata + outpos + 6, wvh.track_no);
4219 GST_WRITE_UINT8 (outdata + outpos + 7, wvh.index_no);
4220 GST_WRITE_UINT32_LE (outdata + outpos + 8, wvh.total_samples);
4221 GST_WRITE_UINT32_LE (outdata + outpos + 12, wvh.block_index);
4222 GST_WRITE_UINT32_LE (outdata + outpos + 16, block_samples);
4223 GST_WRITE_UINT32_LE (outdata + outpos + 20, flags);
4224 GST_WRITE_UINT32_LE (outdata + outpos + 24, crc);
4227 g_memmove (outdata + outpos, data, blocksize);
4228 outpos += blocksize;
4232 gst_buffer_unref (*buf);
4234 audiocontext->wvpk_block_index += block_samples;
4240 static GstFlowReturn
4241 gst_matroska_demux_check_subtitle_buffer (GstElement * element,
4242 GstMatroskaTrackContext * stream, GstBuffer ** buf)
4244 GstMatroskaTrackSubtitleContext *sub_stream;
4245 const gchar *encoding, *data;
4251 sub_stream = (GstMatroskaTrackSubtitleContext *) stream;
4253 data = (const gchar *) GST_BUFFER_DATA (*buf);
4254 size = GST_BUFFER_SIZE (*buf);
4256 if (!sub_stream->invalid_utf8) {
4257 if (g_utf8_validate (data, size, NULL)) {
4260 GST_WARNING_OBJECT (element, "subtitle stream %d is not valid UTF-8, this "
4261 "is broken according to the matroska specification", stream->num);
4262 sub_stream->invalid_utf8 = TRUE;
4265 /* file with broken non-UTF8 subtitle, do the best we can do to fix it */
4266 encoding = g_getenv ("GST_SUBTITLE_ENCODING");
4267 if (encoding == NULL || *encoding == '\0') {
4268 /* if local encoding is UTF-8 and no encoding specified
4269 * via the environment variable, assume ISO-8859-15 */
4270 if (g_get_charset (&encoding)) {
4271 encoding = "ISO-8859-15";
4275 utf8 = g_convert_with_fallback (data, size, "UTF-8", encoding, (char *) "*",
4279 GST_LOG_OBJECT (element, "could not convert string from '%s' to UTF-8: %s",
4280 encoding, err->message);
4284 /* invalid input encoding, fall back to ISO-8859-15 (always succeeds) */
4285 encoding = "ISO-8859-15";
4286 utf8 = g_convert_with_fallback (data, size, "UTF-8", encoding, (char *) "*",
4290 GST_LOG_OBJECT (element, "converted subtitle text from %s to UTF-8 %s",
4291 encoding, (err) ? "(using ISO-8859-15 as fallback)" : "");
4294 utf8 = g_strdup ("invalid subtitle");
4296 newbuf = gst_buffer_new ();
4297 GST_BUFFER_MALLOCDATA (newbuf) = (guint8 *) utf8;
4298 GST_BUFFER_DATA (newbuf) = (guint8 *) utf8;
4299 GST_BUFFER_SIZE (newbuf) = strlen (utf8);
4300 gst_buffer_copy_metadata (newbuf, *buf,
4301 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS);
4302 gst_buffer_unref (*buf);
4308 static GstFlowReturn
4309 gst_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux,
4310 guint64 cluster_time, guint64 cluster_offset, gboolean is_simpleblock)
4312 GstMatroskaTrackContext *stream = NULL;
4313 GstEbmlRead *ebml = GST_EBML_READ (demux);
4314 GstFlowReturn ret = GST_FLOW_OK;
4315 gboolean readblock = FALSE;
4317 guint64 block_duration = 0;
4318 GstBuffer *buf = NULL;
4319 gint stream_num = -1, n, laces = 0;
4321 gint *lace_size = NULL;
4324 gint64 referenceblock = 0;
4327 offset = demux->parent.offset;
4329 while (ret == GST_FLOW_OK) {
4330 if (!is_simpleblock) {
4331 if ((ret = gst_ebml_peek_id (ebml, &demux->level_up, &id)) != GST_FLOW_OK)
4334 if (demux->level_up) {
4339 id = GST_MATROSKA_ID_SIMPLEBLOCK;
4343 /* one block inside the group. Note, block parsing is one
4344 * of the harder things, so this code is a bit complicated.
4345 * See http://www.matroska.org/ for documentation. */
4346 case GST_MATROSKA_ID_SIMPLEBLOCK:
4347 case GST_MATROSKA_ID_BLOCK:
4353 gst_buffer_unref (buf);
4356 if ((ret = gst_ebml_read_buffer (ebml, &id, &buf)) != GST_FLOW_OK)
4359 data = GST_BUFFER_DATA (buf);
4360 size = GST_BUFFER_SIZE (buf);
4362 /* first byte(s): blocknum */
4363 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0) {
4364 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Data error"));
4365 gst_buffer_unref (buf);
4367 ret = GST_FLOW_ERROR;
4373 /* fetch stream from num */
4374 stream_num = gst_matroska_demux_stream_from_num (demux, num);
4375 if (size < 3 || stream_num < 0 || stream_num >= demux->num_streams) {
4376 gst_buffer_unref (buf);
4378 GST_WARNING_OBJECT (demux, "Invalid stream %d or size %u", stream_num,
4380 ret = GST_FLOW_ERROR;
4384 stream = g_ptr_array_index (demux->src, stream_num);
4386 /* time (relative to cluster time) */
4387 time = ((gint16) GST_READ_UINT16_BE (data));
4390 flags = GST_READ_UINT8 (data);
4394 GST_LOG_OBJECT (demux, "time %" G_GUINT64_FORMAT ", flags %d", time,
4397 switch ((flags & 0x06) >> 1) {
4398 case 0x0: /* no lacing */
4400 lace_size = g_new (gint, 1);
4401 lace_size[0] = size;
4404 case 0x1: /* xiph lacing */
4405 case 0x2: /* fixed-size lacing */
4406 case 0x3: /* EBML lacing */
4408 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4409 ("Invalid lacing size"));
4410 ret = GST_FLOW_ERROR;
4413 laces = GST_READ_UINT8 (data) + 1;
4416 lace_size = g_new0 (gint, laces);
4418 switch ((flags & 0x06) >> 1) {
4419 case 0x1: /* xiph lacing */ {
4420 guint temp, total = 0;
4422 for (n = 0; ret == GST_FLOW_OK && n < laces - 1; n++) {
4425 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4426 ("Invalid lacing size"));
4427 ret = GST_FLOW_ERROR;
4430 temp = GST_READ_UINT8 (data);
4431 lace_size[n] += temp;
4437 total += lace_size[n];
4439 lace_size[n] = size - total;
4443 case 0x2: /* fixed-size lacing */
4444 for (n = 0; n < laces; n++)
4445 lace_size[n] = size / laces;
4448 case 0x3: /* EBML lacing */ {
4451 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0) {
4452 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4454 ret = GST_FLOW_ERROR;
4459 total = lace_size[0] = num;
4460 for (n = 1; ret == GST_FLOW_OK && n < laces - 1; n++) {
4464 if ((r = gst_matroska_ebmlnum_sint (data, size, &snum)) < 0) {
4465 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4467 ret = GST_FLOW_ERROR;
4472 lace_size[n] = lace_size[n - 1] + snum;
4473 total += lace_size[n];
4476 lace_size[n] = size - total;
4483 if (stream->send_xiph_headers) {
4484 ret = gst_matroska_demux_push_xiph_codec_priv_data (demux, stream);
4485 stream->send_xiph_headers = FALSE;
4488 if (stream->send_flac_headers) {
4489 ret = gst_matroska_demux_push_flac_codec_priv_data (demux, stream);
4490 stream->send_flac_headers = FALSE;
4493 if (stream->send_speex_headers) {
4494 ret = gst_matroska_demux_push_speex_codec_priv_data (demux, stream);
4495 stream->send_speex_headers = FALSE;
4498 if (stream->send_dvd_event) {
4499 gst_matroska_demux_push_dvd_clut_change_event (demux, stream);
4500 /* FIXME: should we send this event again after (flushing) seek ? */
4501 stream->send_dvd_event = FALSE;
4504 if (ret != GST_FLOW_OK)
4511 case GST_MATROSKA_ID_BLOCKDURATION:{
4512 ret = gst_ebml_read_uint (ebml, &id, &block_duration);
4513 GST_DEBUG_OBJECT (demux, "BlockDuration: %" G_GUINT64_FORMAT,
4518 case GST_MATROSKA_ID_REFERENCEBLOCK:{
4519 ret = gst_ebml_read_sint (ebml, &id, &referenceblock);
4520 GST_DEBUG_OBJECT (demux, "ReferenceBlock: %" G_GINT64_FORMAT,
4525 case GST_MATROSKA_ID_CODECSTATE:{
4527 guint64 data_len = 0;
4530 gst_ebml_read_binary (ebml, &id, &data,
4531 &data_len)) != GST_FLOW_OK)
4534 if (G_UNLIKELY (stream == NULL)) {
4535 GST_WARNING_OBJECT (demux,
4536 "Unexpected CodecState subelement - ignoring");
4540 g_free (stream->codec_state);
4541 stream->codec_state = data;
4542 stream->codec_state_size = data_len;
4544 /* Decode if necessary */
4545 if (stream->encodings && stream->encodings->len > 0
4546 && stream->codec_state && stream->codec_state_size > 0) {
4547 if (!gst_matroska_decode_data (stream->encodings,
4548 &stream->codec_state, &stream->codec_state_size,
4549 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
4550 GST_WARNING_OBJECT (demux, "Decoding codec state failed");
4554 GST_DEBUG_OBJECT (demux, "CodecState of %u bytes",
4555 stream->codec_state_size);
4560 GST_WARNING_OBJECT (demux,
4561 "Unknown BlockGroup subelement 0x%x - ignoring", id);
4564 case GST_MATROSKA_ID_BLOCKVIRTUAL:
4565 case GST_MATROSKA_ID_BLOCKADDITIONS:
4566 case GST_MATROSKA_ID_REFERENCEPRIORITY:
4567 case GST_MATROSKA_ID_REFERENCEVIRTUAL:
4568 case GST_MATROSKA_ID_SLICES:
4569 GST_DEBUG_OBJECT (demux,
4570 "Skipping BlockGroup subelement 0x%x - ignoring", id);
4571 ret = gst_ebml_read_skip (ebml);
4578 if (demux->level_up) {
4584 if (ret == GST_FLOW_OK && readblock) {
4585 guint64 duration = 0;
4586 gint64 lace_time = 0;
4588 stream = g_ptr_array_index (demux->src, stream_num);
4590 if (cluster_time != GST_CLOCK_TIME_NONE) {
4591 /* FIXME: What to do with negative timestamps? Give timestamp 0 or -1?
4592 * Drop unless the lace contains timestamp 0? */
4593 if (time < 0 && (-time) > cluster_time) {
4596 if (stream->timecodescale == 1.0)
4597 lace_time = (cluster_time + time) * demux->time_scale;
4600 gst_util_guint64_to_gdouble ((cluster_time + time) *
4601 demux->time_scale) * stream->timecodescale;
4604 lace_time = GST_CLOCK_TIME_NONE;
4607 /* need to refresh segment info ASAP */
4608 if (GST_CLOCK_TIME_IS_VALID (lace_time) && demux->need_newsegment) {
4609 GST_DEBUG_OBJECT (demux,
4610 "generating segment starting at %" GST_TIME_FORMAT,
4611 GST_TIME_ARGS (lace_time));
4612 /* pretend we seeked here */
4613 gst_segment_set_seek (&demux->segment, demux->segment.rate,
4614 GST_FORMAT_TIME, 0, GST_SEEK_TYPE_SET, lace_time,
4615 GST_SEEK_TYPE_SET, GST_CLOCK_TIME_NONE, NULL);
4616 /* now convey our segment notion downstream */
4617 gst_matroska_demux_send_event (demux, gst_event_new_new_segment (FALSE,
4618 demux->segment.rate, demux->segment.format, demux->segment.start,
4619 demux->segment.stop, demux->segment.start));
4620 demux->need_newsegment = FALSE;
4623 if (block_duration) {
4624 if (stream->timecodescale == 1.0)
4625 duration = block_duration * demux->time_scale;
4628 gst_util_gdouble_to_guint64 (gst_util_guint64_to_gdouble
4629 (block_duration * demux->time_scale) * stream->timecodescale);
4630 } else if (stream->default_duration) {
4631 duration = stream->default_duration * laces;
4633 /* else duration is diff between timecode of this and next block */
4634 for (n = 0; n < laces; n++) {
4637 if (G_UNLIKELY (lace_size[n] > size)) {
4638 GST_WARNING_OBJECT (demux, "Invalid lace size");
4642 sub = gst_buffer_create_sub (buf,
4643 GST_BUFFER_SIZE (buf) - size, lace_size[n]);
4644 GST_DEBUG_OBJECT (demux, "created subbuffer %p", sub);
4646 if (stream->encodings != NULL && stream->encodings->len > 0)
4647 sub = gst_matroska_decode_buffer (stream, sub);
4650 GST_WARNING_OBJECT (demux, "Decoding buffer failed");
4654 GST_BUFFER_TIMESTAMP (sub) = lace_time;
4656 if (GST_CLOCK_TIME_IS_VALID (lace_time)) {
4657 GstClockTime last_stop_end;
4659 /* Check if this stream is after segment stop */
4660 if (GST_CLOCK_TIME_IS_VALID (demux->segment.stop) &&
4661 lace_time >= demux->segment.stop) {
4662 GST_DEBUG_OBJECT (demux,
4663 "Stream %d after segment stop %" GST_TIME_FORMAT, stream->index,
4664 GST_TIME_ARGS (demux->segment.stop));
4665 gst_buffer_unref (sub);
4668 if (offset >= demux->to_offset) {
4669 GST_DEBUG_OBJECT (demux, "Stream %d after playback section",
4671 gst_buffer_unref (sub);
4675 /* handle gaps, e.g. non-zero start-time, or an cue index entry
4676 * that landed us with timestamps not quite intended */
4677 if (GST_CLOCK_TIME_IS_VALID (demux->segment.last_stop) &&
4678 demux->segment.rate > 0.0) {
4679 GstClockTimeDiff diff;
4681 /* only send newsegments with increasing start times,
4682 * otherwise if these go back and forth downstream (sinks) increase
4683 * accumulated time and running_time */
4684 diff = GST_CLOCK_DIFF (demux->segment.last_stop, lace_time);
4685 if (diff > 2 * GST_SECOND && lace_time > demux->segment.start &&
4686 (!GST_CLOCK_TIME_IS_VALID (demux->segment.stop) ||
4687 lace_time < demux->segment.stop)) {
4688 GST_DEBUG_OBJECT (demux,
4689 "Gap of %" G_GINT64_FORMAT " ns detected in"
4690 "stream %d (%" GST_TIME_FORMAT " -> %" GST_TIME_FORMAT "). "
4691 "Sending updated NEWSEGMENT events", diff,
4692 stream->index, GST_TIME_ARGS (stream->pos),
4693 GST_TIME_ARGS (lace_time));
4694 /* send newsegment events such that the gap is not accounted in
4695 * accum time, hence running_time */
4696 /* close ahead of gap */
4697 gst_matroska_demux_send_event (demux,
4698 gst_event_new_new_segment (TRUE, demux->segment.rate,
4699 demux->segment.format, demux->segment.last_stop,
4700 demux->segment.last_stop, demux->segment.last_stop));
4702 gst_matroska_demux_send_event (demux,
4703 gst_event_new_new_segment (FALSE, demux->segment.rate,
4704 demux->segment.format, lace_time, demux->segment.stop,
4706 /* align segment view with downstream,
4707 * prevents double-counting accum when closing segment */
4708 gst_segment_set_newsegment (&demux->segment, FALSE,
4709 demux->segment.rate, demux->segment.format, lace_time,
4710 demux->segment.stop, lace_time);
4711 demux->segment.last_stop = lace_time;
4715 if (!GST_CLOCK_TIME_IS_VALID (demux->segment.last_stop)
4716 || demux->segment.last_stop < lace_time) {
4717 demux->segment.last_stop = lace_time;
4720 last_stop_end = lace_time;
4722 GST_BUFFER_DURATION (sub) = duration / laces;
4723 last_stop_end += GST_BUFFER_DURATION (sub);
4726 if (!GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) ||
4727 demux->last_stop_end < last_stop_end)
4728 demux->last_stop_end = last_stop_end;
4730 if (demux->segment.duration == -1 ||
4731 demux->segment.duration < lace_time) {
4732 gst_segment_set_duration (&demux->segment, GST_FORMAT_TIME,
4734 gst_element_post_message (GST_ELEMENT_CAST (demux),
4735 gst_message_new_duration (GST_OBJECT_CAST (demux),
4736 GST_FORMAT_TIME, GST_CLOCK_TIME_NONE));
4740 stream->pos = lace_time;
4742 gst_matroska_demux_sync_streams (demux);
4744 if (is_simpleblock) {
4746 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
4748 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
4750 if (referenceblock) {
4751 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
4753 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
4757 if (GST_BUFFER_FLAG_IS_SET (sub, GST_BUFFER_FLAG_DELTA_UNIT)
4758 && stream->set_discont) {
4759 /* When doing seeks or such, we need to restart on key frames or
4760 * decoders might choke. */
4761 GST_DEBUG_OBJECT (demux, "skipping delta unit");
4762 gst_buffer_unref (sub);
4766 if (stream->set_discont) {
4767 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DISCONT);
4768 stream->set_discont = FALSE;
4771 /* reverse playback book-keeping */
4772 if (!GST_CLOCK_TIME_IS_VALID (stream->from_time))
4773 stream->from_time = lace_time;
4774 if (demux->from_offset == -1)
4775 demux->from_offset = offset;
4777 GST_DEBUG_OBJECT (demux,
4778 "Pushing lace %d, data of size %d for stream %d, time=%"
4779 GST_TIME_FORMAT " and duration=%" GST_TIME_FORMAT, n,
4780 GST_BUFFER_SIZE (sub), stream_num,
4781 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (sub)),
4782 GST_TIME_ARGS (GST_BUFFER_DURATION (sub)));
4784 if (demux->element_index) {
4785 if (stream->index_writer_id == -1)
4786 gst_index_get_writer_id (demux->element_index,
4787 GST_OBJECT (stream->pad), &stream->index_writer_id);
4789 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
4790 G_GUINT64_FORMAT " for writer id %d",
4791 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (sub)), cluster_offset,
4792 stream->index_writer_id);
4793 gst_index_add_association (demux->element_index,
4794 stream->index_writer_id, GST_BUFFER_FLAG_IS_SET (sub,
4795 GST_BUFFER_FLAG_DELTA_UNIT) ? 0 : GST_ASSOCIATION_FLAG_KEY_UNIT,
4796 GST_FORMAT_TIME, GST_BUFFER_TIMESTAMP (sub), GST_FORMAT_BYTES,
4797 cluster_offset, NULL);
4800 gst_buffer_set_caps (sub, GST_PAD_CAPS (stream->pad));
4802 /* Postprocess the buffers depending on the codec used */
4803 if (stream->postprocess_frame) {
4804 GST_LOG_OBJECT (demux, "running post process");
4805 ret = stream->postprocess_frame (GST_ELEMENT (demux), stream, &sub);
4808 ret = gst_pad_push (stream->pad, sub);
4810 ret = gst_matroska_demux_combine_flows (demux, stream, ret);
4813 size -= lace_size[n];
4814 if (lace_time != GST_CLOCK_TIME_NONE && duration)
4815 lace_time += duration / laces;
4817 lace_time = GST_CLOCK_TIME_NONE;
4823 gst_buffer_unref (buf);
4834 ret = gst_matroska_demux_combine_flows (demux, stream, ret);
4839 /* return FALSE if block(group) should be skipped (due to a seek) */
4840 static inline gboolean
4841 gst_matroska_demux_seek_block (GstMatroskaDemux * demux)
4843 if (G_UNLIKELY (demux->seek_block)) {
4844 if (!(--demux->seek_block)) {
4847 GST_LOG_OBJECT (demux, "should skip block due to seek");
4855 static GstFlowReturn
4856 gst_matroska_demux_parse_cluster (GstMatroskaDemux * demux)
4858 GstEbmlRead *ebml = GST_EBML_READ (demux);
4859 GstFlowReturn ret = GST_FLOW_OK;
4860 guint64 cluster_time = GST_CLOCK_TIME_NONE;
4862 guint64 cluster_offset = demux->parent.offset;
4864 DEBUG_ELEMENT_START (demux, ebml, "Cluster");
4866 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
4867 DEBUG_ELEMENT_STOP (demux, ebml, "Cluster", ret);
4871 while (ret == GST_FLOW_OK) {
4872 if ((ret = gst_ebml_peek_id (ebml, &demux->level_up, &id)) != GST_FLOW_OK)
4875 if (demux->level_up) {
4881 /* cluster timecode */
4882 case GST_MATROSKA_ID_CLUSTERTIMECODE:
4886 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
4889 GST_DEBUG_OBJECT (demux, "ClusterTimeCode: %" G_GUINT64_FORMAT, num);
4894 /* a group of blocks inside a cluster */
4895 case GST_MATROSKA_ID_BLOCKGROUP:
4896 if (!gst_matroska_demux_seek_block (demux))
4898 DEBUG_ELEMENT_START (demux, ebml, "BlockGroup");
4899 if ((ret = gst_ebml_read_master (ebml, &id)) == GST_FLOW_OK) {
4900 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4901 cluster_time, cluster_offset, FALSE);
4903 DEBUG_ELEMENT_STOP (demux, ebml, "BlockGroup", ret);
4906 case GST_MATROSKA_ID_SIMPLEBLOCK:
4908 if (!gst_matroska_demux_seek_block (demux))
4910 DEBUG_ELEMENT_START (demux, ebml, "SimpleBlock");
4911 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4912 cluster_time, cluster_offset, TRUE);
4913 DEBUG_ELEMENT_STOP (demux, ebml, "SimpleBlock", ret);
4918 GST_WARNING ("Unknown Cluster subelement 0x%x - ignoring", id);
4920 case GST_MATROSKA_ID_POSITION:
4921 case GST_MATROSKA_ID_PREVSIZE:
4922 case GST_MATROSKA_ID_ENCRYPTEDBLOCK:
4923 case GST_MATROSKA_ID_SILENTTRACKS:
4925 GST_DEBUG ("Skipping Cluster subelement 0x%x - ignoring", id);
4926 ret = gst_ebml_read_skip (ebml);
4930 if (demux->level_up) {
4936 if (demux->element_index) {
4937 if (demux->element_index_writer_id == -1)
4938 gst_index_get_writer_id (demux->element_index,
4939 GST_OBJECT (demux), &demux->element_index_writer_id);
4941 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
4942 G_GUINT64_FORMAT " for writer id %d",
4943 GST_TIME_ARGS (cluster_time), cluster_offset,
4944 demux->element_index_writer_id);
4945 gst_index_add_association (demux->element_index,
4946 demux->element_index_writer_id, GST_ASSOCIATION_FLAG_KEY_UNIT,
4947 GST_FORMAT_TIME, cluster_time, GST_FORMAT_BYTES, cluster_offset, NULL);
4950 DEBUG_ELEMENT_STOP (demux, ebml, "Cluster", ret);
4952 if (G_UNLIKELY (demux->seek_block)) {
4953 GST_DEBUG_OBJECT (demux, "seek target block %" G_GUINT64_FORMAT
4954 " not found in Cluster, trying next Cluster's first block instead",
4956 demux->seek_block = 0;
4962 static GstFlowReturn
4963 gst_matroska_demux_parse_contents_seekentry (GstMatroskaDemux * demux)
4965 GstEbmlRead *ebml = GST_EBML_READ (demux);
4967 guint64 seek_pos = (guint64) - 1;
4968 guint32 seek_id = 0;
4971 DEBUG_ELEMENT_START (demux, ebml, "Seek");
4973 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
4974 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
4978 while (ret == GST_FLOW_OK) {
4979 if ((ret = gst_ebml_peek_id (ebml, &demux->level_up, &id)) != GST_FLOW_OK)
4982 if (demux->level_up) {
4988 case GST_MATROSKA_ID_SEEKID:
4992 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
4995 GST_DEBUG_OBJECT (demux, "SeekID: %" G_GUINT64_FORMAT, t);
5000 case GST_MATROSKA_ID_SEEKPOSITION:
5004 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
5007 if (t > G_MAXINT64) {
5008 GST_WARNING_OBJECT (demux,
5009 "Too large SeekPosition %" G_GUINT64_FORMAT, t);
5013 GST_DEBUG_OBJECT (demux, "SeekPosition: %" G_GUINT64_FORMAT, t);
5019 GST_WARNING_OBJECT (demux,
5020 "Unknown SeekHead subelement 0x%x - ignoring", id);
5021 ret = gst_ebml_read_skip (ebml);
5025 if (demux->level_up) {
5031 if (ret != GST_FLOW_OK && ret != GST_FLOW_UNEXPECTED)
5034 if (!seek_id || seek_pos == (guint64) - 1) {
5035 GST_WARNING_OBJECT (demux, "Incomplete seekhead entry (0x%x/%"
5036 G_GUINT64_FORMAT ")", seek_id, seek_pos);
5041 case GST_MATROSKA_ID_CUES:
5042 case GST_MATROSKA_ID_TAGS:
5043 case GST_MATROSKA_ID_TRACKS:
5044 case GST_MATROSKA_ID_SEEKHEAD:
5045 case GST_MATROSKA_ID_SEGMENTINFO:
5046 case GST_MATROSKA_ID_ATTACHMENTS:
5047 case GST_MATROSKA_ID_CHAPTERS:
5049 guint level_up = demux->level_up;
5050 guint64 before_pos, length;
5051 GstEbmlLevel *level;
5054 length = gst_ebml_read_get_length (ebml);
5055 before_pos = ebml->offset;
5057 /* check for validity */
5058 if (seek_pos + demux->ebml_segment_start + 12 >= length) {
5059 GST_WARNING_OBJECT (demux,
5060 "SeekHead reference lies outside file!" " (%"
5061 G_GUINT64_FORMAT "+%" G_GUINT64_FORMAT "+12 >= %"
5062 G_GUINT64_FORMAT ")", seek_pos, demux->ebml_segment_start, length);
5066 /* only pick up index location when streaming */
5067 if (demux->streaming) {
5068 if (seek_id == GST_MATROSKA_ID_CUES) {
5069 demux->index_offset = seek_pos + demux->ebml_segment_start;
5070 GST_DEBUG_OBJECT (demux, "Cues located at offset %" G_GUINT64_FORMAT,
5071 demux->index_offset);
5077 if (gst_ebml_read_seek (ebml, seek_pos + demux->ebml_segment_start) !=
5081 /* we don't want to lose our seekhead level, so we add
5082 * a dummy. This is a crude hack. */
5083 level = g_slice_new (GstEbmlLevel);
5085 level->length = G_MAXUINT64;
5086 ebml->level = g_list_prepend (ebml->level, level);
5089 if ((ret = gst_ebml_peek_id (ebml, &demux->level_up, &id)) != GST_FLOW_OK)
5092 if (id != seek_id) {
5093 GST_WARNING_OBJECT (demux,
5094 "We looked for ID=0x%x but got ID=0x%x (pos=%" G_GUINT64_FORMAT ")",
5095 seek_id, id, seek_pos + demux->ebml_segment_start);
5099 /* read master + parse */
5101 case GST_MATROSKA_ID_CUES:
5102 if (!demux->index_parsed) {
5103 ret = gst_matroska_demux_parse_index (demux);
5106 case GST_MATROSKA_ID_TAGS:
5107 ret = gst_matroska_demux_parse_metadata (demux);
5109 case GST_MATROSKA_ID_TRACKS:
5110 if (!demux->tracks_parsed) {
5111 ret = gst_matroska_demux_parse_tracks (demux);
5115 case GST_MATROSKA_ID_SEGMENTINFO:
5116 if (!demux->segmentinfo_parsed) {
5117 ret = gst_matroska_demux_parse_info (demux);
5120 case GST_MATROSKA_ID_SEEKHEAD:
5124 DEBUG_ELEMENT_START (demux, ebml, "SeekHead");
5125 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
5128 /* Prevent infinite recursion if there's a cycle from
5129 * one seekhead to the same again. Simply break if
5130 * we already had this seekhead, finish will clean up
5132 for (l = ebml->level; l; l = l->next) {
5133 GstEbmlLevel *level = (GstEbmlLevel *) l->data;
5135 if (level->start == ebml->offset && l->prev)
5139 ret = gst_matroska_demux_parse_contents (demux);
5142 case GST_MATROSKA_ID_ATTACHMENTS:
5143 if (!demux->attachments_parsed) {
5144 ret = gst_matroska_demux_parse_attachments (demux);
5147 case GST_MATROSKA_ID_CHAPTERS:
5148 ret = gst_matroska_demux_parse_chapters (demux);
5153 /* remove dummy level */
5154 while (ebml->level) {
5157 level = ebml->level->data;
5158 ebml->level = g_list_delete_link (ebml->level, ebml->level);
5159 length = level->length;
5160 g_slice_free (GstEbmlLevel, level);
5161 if (length == G_MAXUINT64)
5166 (void) gst_ebml_read_seek (ebml, before_pos);
5167 demux->level_up = level_up;
5172 GST_DEBUG_OBJECT (demux, "Ignoring Seek entry for ID=0x%x", seek_id);
5175 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
5180 static GstFlowReturn
5181 gst_matroska_demux_parse_contents (GstMatroskaDemux * demux)
5183 GstEbmlRead *ebml = GST_EBML_READ (demux);
5184 GstFlowReturn ret = GST_FLOW_OK;
5187 while (ret == GST_FLOW_OK) {
5188 if ((ret = gst_ebml_peek_id (ebml, &demux->level_up, &id)) != GST_FLOW_OK)
5191 if (demux->level_up) {
5197 case GST_MATROSKA_ID_SEEKENTRY:
5199 ret = gst_matroska_demux_parse_contents_seekentry (demux);
5200 /* Ignore EOS and errors here */
5201 if (ret != GST_FLOW_OK) {
5202 GST_DEBUG_OBJECT (demux, "Ignoring %s", gst_flow_get_name (ret));
5209 GST_WARNING ("Unknown SeekHead subelement 0x%x - ignoring", id);
5210 ret = gst_ebml_read_skip (ebml);
5214 if (demux->level_up) {
5220 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
5225 /* returns FALSE on error, otherwise TRUE */
5226 static GstFlowReturn
5227 gst_matroska_demux_loop_stream_parse_id (GstMatroskaDemux * demux,
5228 guint32 id, gboolean * p_run_loop)
5230 GstEbmlRead *ebml = GST_EBML_READ (demux);
5231 GstFlowReturn ret = GST_FLOW_OK;
5235 * Can exist more than once but following occurences
5236 * must have the same content so ignore them */
5237 case GST_MATROSKA_ID_SEGMENTINFO:
5238 if (!demux->segmentinfo_parsed) {
5239 if ((ret = gst_matroska_demux_parse_info (demux)) != GST_FLOW_OK)
5242 if ((ret = gst_ebml_read_skip (ebml)) != GST_FLOW_OK)
5247 /* track info headers
5248 * Can exist more than once but following occurences
5249 * must have the same content so ignore them */
5250 case GST_MATROSKA_ID_TRACKS:
5252 if (!demux->tracks_parsed) {
5253 if ((ret = gst_matroska_demux_parse_tracks (demux)) != GST_FLOW_OK)
5256 if ((ret = gst_ebml_read_skip (ebml)) != GST_FLOW_OK)
5262 /* cues - seek table
5263 * Either exists exactly one time or never but ignore
5264 * following occurences for the sake of sanity */
5265 case GST_MATROSKA_ID_CUES:
5267 if (!demux->index_parsed) {
5268 if ((ret = gst_matroska_demux_parse_index (demux)) != GST_FLOW_OK)
5271 if ((ret = gst_ebml_read_skip (ebml)) != GST_FLOW_OK)
5278 * can exist more than one time with different content */
5279 case GST_MATROSKA_ID_TAGS:
5281 if ((ret = gst_matroska_demux_parse_metadata (demux)) != GST_FLOW_OK)
5286 /* file index (if seekable, seek to Cues/Tags/etc to parse it) */
5287 case GST_MATROSKA_ID_SEEKHEAD:
5289 DEBUG_ELEMENT_START (demux, ebml, "SeekHead");
5290 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
5292 if ((ret = gst_matroska_demux_parse_contents (demux)) != GST_FLOW_OK)
5297 /* cluster - contains the payload */
5298 case GST_MATROSKA_ID_CLUSTER:
5300 if (demux->state != GST_MATROSKA_DEMUX_STATE_DATA) {
5301 /* We need a Tracks element first before we can output anything.
5304 if (!demux->tracks_parsed) {
5305 GstEbmlLevel *level;
5310 GST_WARNING_OBJECT (demux,
5311 "Found Cluster element before Tracks, searching Tracks");
5314 level_up = demux->level_up;
5315 before_pos = ebml->offset;
5317 /* we don't want to lose our seekhead level, so we add
5318 * a dummy. This is a crude hack. */
5320 level = g_slice_new (GstEbmlLevel);
5322 level->length = G_MAXUINT64;
5323 ebml->level = g_list_prepend (ebml->level, level);
5325 /* Search Tracks element */
5327 if (gst_ebml_read_skip (ebml) != GST_FLOW_OK)
5330 if (gst_ebml_peek_id (ebml, &demux->level_up, &iid) != GST_FLOW_OK)
5333 if (iid != GST_MATROSKA_ID_TRACKS)
5336 gst_matroska_demux_parse_tracks (demux);
5340 if (!demux->tracks_parsed) {
5341 GST_ERROR_OBJECT (demux, "No Tracks element found");
5342 ret = GST_FLOW_ERROR;
5345 /* remove dummy level */
5346 while (ebml->level) {
5349 level = ebml->level->data;
5350 ebml->level = g_list_delete_link (ebml->level, ebml->level);
5351 length = level->length;
5352 g_slice_free (GstEbmlLevel, level);
5353 if (length == G_MAXUINT64)
5358 gst_ebml_read_seek (ebml, before_pos);
5359 demux->level_up = level_up;
5362 if (ret != GST_FLOW_OK)
5365 demux->state = GST_MATROSKA_DEMUX_STATE_DATA;
5366 GST_DEBUG_OBJECT (demux, "signaling no more pads");
5367 gst_element_no_more_pads (GST_ELEMENT (demux));
5368 /* send initial discont */
5369 gst_matroska_demux_send_event (demux,
5370 gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_TIME, 0, -1, 0));
5372 /* The idea is that we parse one cluster per loop and
5373 * then break out of the loop here. In the next call
5374 * of the loopfunc, we will get back here with the
5375 * next cluster. If an error occurs, we didn't
5376 * actually push a buffer, but we still want to break
5377 * out of the loop to handle a possible error. We'll
5378 * get back here if it's recoverable. */
5379 if ((ret = gst_matroska_demux_parse_cluster (demux)) != GST_FLOW_OK)
5381 *p_run_loop = FALSE;
5386 /* attachments - contains files attached to the mkv container
5387 * like album art, etc */
5388 case GST_MATROSKA_ID_ATTACHMENTS:{
5389 if (!demux->attachments_parsed) {
5390 if ((ret = gst_matroska_demux_parse_attachments (demux)) != GST_FLOW_OK)
5393 if ((ret = gst_ebml_read_skip (ebml)) != GST_FLOW_OK)
5399 /* chapters - contains meta information about how to group
5400 * the file into chapters, similar to DVD */
5401 case GST_MATROSKA_ID_CHAPTERS:{
5402 if ((ret = gst_matroska_demux_parse_chapters (demux)) != GST_FLOW_OK)
5408 GST_WARNING_OBJECT (demux, "Unknown Segment subelement 0x%x at %"
5409 G_GUINT64_FORMAT " - ignoring", id, GST_EBML_READ (demux)->offset);
5410 if ((ret = gst_ebml_read_skip (ebml)) != GST_FLOW_OK)
5417 static GstFlowReturn
5418 gst_matroska_demux_loop_stream (GstMatroskaDemux * demux)
5420 GstEbmlRead *ebml = GST_EBML_READ (demux);
5421 GstFlowReturn ret = GST_FLOW_OK;
5422 gboolean run_loop = TRUE;
5425 /* we've found our segment, start reading the different contents in here */
5426 while (run_loop && ret == GST_FLOW_OK) {
5427 if ((ret = gst_ebml_peek_id (ebml, &demux->level_up, &id)) != GST_FLOW_OK)
5430 if (demux->level_up) {
5435 ret = gst_matroska_demux_loop_stream_parse_id (demux, id, &run_loop);
5437 if (demux->level_up) {
5446 gst_matroska_demux_loop (GstPad * pad)
5448 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (pad));
5449 GstEbmlRead *ebml = GST_EBML_READ (demux);
5452 /* first, if we're to start, let's actually get starting */
5453 if (G_UNLIKELY (demux->state == GST_MATROSKA_DEMUX_STATE_START)) {
5454 ret = gst_matroska_demux_init_stream (demux);
5455 if (ret != GST_FLOW_OK) {
5456 GST_WARNING_OBJECT (demux, "init stream failed!");
5459 demux->state = GST_MATROSKA_DEMUX_STATE_HEADER;
5462 /* If we have to close a segment, send a new segment to do this now */
5464 if (G_LIKELY (demux->state == GST_MATROSKA_DEMUX_STATE_DATA)) {
5465 if (G_UNLIKELY (demux->close_segment)) {
5466 gst_matroska_demux_send_event (demux, demux->close_segment);
5467 demux->close_segment = NULL;
5469 if (G_UNLIKELY (demux->new_segment)) {
5470 gst_matroska_demux_send_event (demux, demux->new_segment);
5471 demux->new_segment = NULL;
5475 ret = gst_matroska_demux_loop_stream (demux);
5476 if (ret == GST_FLOW_UNEXPECTED)
5478 if (ret != GST_FLOW_OK)
5481 /* check if we're at the end of a configured segment */
5482 if (G_LIKELY (demux->src->len)) {
5485 g_assert (demux->num_streams == demux->src->len);
5486 for (i = 0; i < demux->src->len; i++) {
5487 GstMatroskaTrackContext *context = g_ptr_array_index (demux->src, i);
5488 GST_DEBUG_OBJECT (context->pad, "pos %" GST_TIME_FORMAT,
5489 GST_TIME_ARGS (context->pos));
5490 if (context->eos == FALSE)
5494 GST_INFO_OBJECT (demux, "All streams are EOS");
5495 ret = GST_FLOW_UNEXPECTED;
5500 if (G_UNLIKELY (ebml->offset == gst_ebml_read_get_length (ebml))) {
5501 GST_LOG_OBJECT (demux, "Reached end of stream, sending EOS");
5502 ret = GST_FLOW_UNEXPECTED;
5511 if (demux->segment.rate < 0.0) {
5512 ret = gst_matroska_demux_seek_to_previous_keyframe (demux);
5513 if (ret == GST_FLOW_OK)
5520 const gchar *reason = gst_flow_get_name (ret);
5522 GST_LOG_OBJECT (demux, "pausing task, reason %s", reason);
5523 demux->segment_running = FALSE;
5524 gst_pad_pause_task (demux->sinkpad);
5526 if (GST_FLOW_IS_FATAL (ret) || ret == GST_FLOW_NOT_LINKED) {
5527 gboolean push_eos = TRUE;
5529 if (ret == GST_FLOW_UNEXPECTED) {
5530 /* perform EOS logic */
5532 /* Close the segment, i.e. update segment stop with the duration
5533 * if no stop was set */
5534 if (GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) &&
5535 !GST_CLOCK_TIME_IS_VALID (demux->segment.stop)) {
5537 gst_event_new_new_segment_full (TRUE, demux->segment.rate,
5538 demux->segment.applied_rate, demux->segment.format,
5539 demux->segment.start,
5540 MAX (demux->last_stop_end, demux->segment.start),
5541 demux->segment.time);
5542 gst_matroska_demux_send_event (demux, event);
5545 if (demux->segment.flags & GST_SEEK_FLAG_SEGMENT) {
5548 /* for segment playback we need to post when (in stream time)
5549 * we stopped, this is either stop (when set) or the duration. */
5550 if ((stop = demux->segment.stop) == -1)
5551 stop = demux->last_stop_end;
5553 GST_LOG_OBJECT (demux, "Sending segment done, at end of segment");
5554 gst_element_post_message (GST_ELEMENT (demux),
5555 gst_message_new_segment_done (GST_OBJECT (demux), GST_FORMAT_TIME,
5560 /* for fatal errors we post an error message */
5561 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
5562 ("stream stopped, reason %s", reason));
5565 /* send EOS, and prevent hanging if no streams yet */
5566 GST_LOG_OBJECT (demux, "Sending EOS, at end of stream");
5567 if (!gst_matroska_demux_send_event (demux, gst_event_new_eos ()) &&
5568 (ret == GST_FLOW_UNEXPECTED)) {
5569 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
5570 (NULL), ("got eos but no streams (yet)"));
5579 * Create and push a flushing seek event upstream
5582 perform_seek_to_offset (GstMatroskaDemux * demux, guint64 offset)
5587 GST_DEBUG_OBJECT (demux, "Seeking to %" G_GUINT64_FORMAT, offset);
5590 gst_event_new_seek (1.0, GST_FORMAT_BYTES,
5591 GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, GST_SEEK_TYPE_SET, offset,
5592 GST_SEEK_TYPE_NONE, -1);
5594 res = gst_pad_push_event (demux->sinkpad, event);
5596 /* newsegment event will update offset */
5601 gst_matroska_demux_check_seekability (GstMatroskaDemux * demux)
5604 gboolean seekable = FALSE;
5605 gint64 start = -1, stop = -1;
5607 query = gst_query_new_seeking (GST_FORMAT_BYTES);
5608 if (!gst_pad_peer_query (demux->sinkpad, query)) {
5609 GST_DEBUG_OBJECT (demux, "seeking query failed");
5613 gst_query_parse_seeking (query, NULL, &seekable, &start, &stop);
5615 /* try harder to query upstream size if we didn't get it the first time */
5616 if (seekable && stop == -1) {
5617 GstFormat fmt = GST_FORMAT_BYTES;
5619 GST_DEBUG_OBJECT (demux, "doing duration query to fix up unset stop");
5620 gst_pad_query_peer_duration (demux->sinkpad, &fmt, &stop);
5623 /* if upstream doesn't know the size, it's likely that it's not seekable in
5624 * practice even if it technically may be seekable */
5625 if (seekable && (start != 0 || stop <= start)) {
5626 GST_DEBUG_OBJECT (demux, "seekable but unknown start/stop -> disable");
5631 GST_INFO_OBJECT (demux, "seekable: %d (%" G_GUINT64_FORMAT " - %"
5632 G_GUINT64_FORMAT ")", seekable, start, stop);
5633 demux->seekable = seekable;
5635 gst_query_unref (query);
5639 gst_matroska_demux_take (GstMatroskaDemux * demux, guint bytes)
5643 GST_LOG_OBJECT (demux, "caching %d bytes for parsing", bytes);
5644 buffer = gst_adapter_take_buffer (demux->adapter, bytes);
5645 gst_ebml_read_reset_cache (GST_EBML_READ (demux), buffer, demux->offset);
5646 demux->offset += bytes;
5650 gst_matroska_demux_flush (GstMatroskaDemux * demux, guint flush)
5652 GST_LOG_OBJECT (demux, "skipping %d bytes", flush);
5653 gst_adapter_flush (demux->adapter, flush);
5654 demux->offset += flush;
5657 static GstFlowReturn
5658 gst_matroska_demux_peek_id_length (GstMatroskaDemux * demux, guint32 * _id,
5659 guint64 * _length, guint * _needed)
5661 guint avail, needed;
5663 gint len_mask = 0x80, read = 1, n = 1, num_ffs = 0;
5667 g_return_val_if_fail (_id != NULL, GST_FLOW_ERROR);
5668 g_return_val_if_fail (_length != NULL, GST_FLOW_ERROR);
5669 g_return_val_if_fail (_needed != NULL, GST_FLOW_ERROR);
5672 *_id = (guint32) GST_EBML_SIZE_UNKNOWN;
5673 *_length = GST_EBML_SIZE_UNKNOWN;
5675 /* read element id */
5677 avail = gst_adapter_available (demux->adapter);
5681 buf = gst_adapter_peek (demux->adapter, 1);
5682 b = GST_READ_UINT8 (buf);
5684 total = (guint64) b;
5685 while (read <= 4 && !(total & len_mask)) {
5689 if (G_UNLIKELY (read > 4))
5691 /* need id and at least something for subsequent length */
5692 if ((needed = read + 1) > avail)
5695 buf = gst_adapter_peek (demux->adapter, needed);
5697 b = GST_READ_UINT8 (buf + n);
5698 total = (total << 8) | b;
5701 *_id = (guint32) total;
5703 /* read element length */
5704 b = GST_READ_UINT8 (buf + n);
5705 total = (guint64) b;
5708 while (read <= 8 && !(total & len_mask)) {
5712 if (G_UNLIKELY (read > 8))
5713 goto invalid_length;
5714 if ((needed += read - 1) > avail)
5716 if ((total &= (len_mask - 1)) == len_mask - 1)
5719 buf = gst_adapter_peek (demux->adapter, needed);
5720 buf += (needed - read);
5723 guint8 b = GST_READ_UINT8 (buf + n);
5725 if (G_UNLIKELY (b == 0xff))
5727 total = (total << 8) | b;
5731 if (G_UNLIKELY (read == num_ffs))
5732 *_length = G_MAXUINT64;
5745 GST_ERROR_OBJECT (demux,
5746 "Invalid EBML ID size tag (0x%x) at position %" G_GUINT64_FORMAT " (0x%"
5747 G_GINT64_MODIFIER "x)", (guint) b, demux->offset, demux->offset);
5748 return GST_FLOW_ERROR;
5752 GST_ERROR_OBJECT (demux,
5753 "Invalid EBML length size tag (0x%x) at position %" G_GUINT64_FORMAT
5754 " (0x%" G_GINT64_MODIFIER "x)", (guint) b, demux->offset,
5756 return GST_FLOW_ERROR;
5760 static GstFlowReturn
5761 gst_matroska_demux_chain (GstPad * pad, GstBuffer * buffer)
5763 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (pad));
5764 GstEbmlRead *ebml = GST_EBML_READ (demux);
5766 GstFlowReturn ret = GST_FLOW_OK;
5772 if (G_UNLIKELY (GST_BUFFER_IS_DISCONT (buffer))) {
5773 GST_DEBUG_OBJECT (demux, "got DISCONT");
5774 gst_adapter_clear (demux->adapter);
5775 gst_matroska_demux_reset_streams (demux, GST_CLOCK_TIME_NONE, FALSE);
5778 gst_adapter_push (demux->adapter, buffer);
5782 available = gst_adapter_available (demux->adapter);
5784 ret = gst_matroska_demux_peek_id_length (demux, &id, &length, &needed);
5785 if (G_UNLIKELY (ret != GST_FLOW_OK))
5788 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
5789 "size %" G_GUINT64_FORMAT ", needed %d, available %d", demux->offset, id,
5790 length, needed, available);
5792 if (needed > available)
5795 /* only a few blocks are expected/allowed to be large,
5796 * and will be recursed into, whereas others must fit */
5797 if (G_LIKELY (id != GST_MATROSKA_ID_SEGMENT && id != GST_MATROSKA_ID_CLUSTER)) {
5798 if (needed + length > available)
5800 /* probably happens with 'large pieces' at the end, so consider it EOS */
5801 if (G_UNLIKELY (length > 10 * 1024 * 1024)) {
5802 GST_WARNING_OBJECT (demux, "forcing EOS due to size %" G_GUINT64_FORMAT,
5804 return GST_FLOW_UNEXPECTED;
5808 switch (demux->state) {
5809 case GST_MATROSKA_DEMUX_STATE_START:
5811 case GST_EBML_ID_HEADER:
5812 gst_matroska_demux_take (demux, length + needed);
5813 ret = gst_matroska_demux_parse_header (demux);
5814 if (ret != GST_FLOW_OK)
5816 demux->state = GST_MATROSKA_DEMUX_STATE_HEADER;
5817 gst_matroska_demux_check_seekability (demux);
5820 goto invalid_header;
5824 case GST_MATROSKA_DEMUX_STATE_HEADER:
5825 case GST_MATROSKA_DEMUX_STATE_DATA:
5826 case GST_MATROSKA_DEMUX_STATE_SEEK:
5828 case GST_MATROSKA_ID_SEGMENT:
5829 /* eat segment prefix */
5830 gst_matroska_demux_flush (demux, needed);
5831 GST_DEBUG_OBJECT (demux,
5832 "Found Segment start at offset %" G_GUINT64_FORMAT, ebml->offset);
5833 /* seeks are from the beginning of the segment,
5834 * after the segment ID/length */
5835 demux->ebml_segment_start = demux->offset;
5837 case GST_MATROSKA_ID_SEGMENTINFO:
5838 if (!demux->segmentinfo_parsed) {
5839 gst_matroska_demux_take (demux, length + needed);
5840 ret = gst_matroska_demux_parse_info (demux);
5842 gst_matroska_demux_flush (demux, needed + length);
5845 case GST_MATROSKA_ID_TRACKS:
5846 if (!demux->tracks_parsed) {
5847 gst_matroska_demux_take (demux, length + needed);
5848 ret = gst_matroska_demux_parse_tracks (demux);
5850 gst_matroska_demux_flush (demux, needed + length);
5853 case GST_MATROSKA_ID_CLUSTER:
5854 if (G_UNLIKELY (!demux->tracks_parsed)) {
5855 GST_DEBUG_OBJECT (demux, "Cluster before Track");
5856 goto not_streamable;
5857 } else if (demux->state == GST_MATROSKA_DEMUX_STATE_HEADER) {
5858 demux->state = GST_MATROSKA_DEMUX_STATE_DATA;
5859 GST_DEBUG_OBJECT (demux, "signaling no more pads");
5860 gst_element_no_more_pads (GST_ELEMENT (demux));
5861 /* send initial newsegment */
5862 gst_matroska_demux_send_event (demux,
5863 gst_event_new_new_segment (FALSE, 1.0,
5865 (demux->segment.duration >
5866 0) ? demux->segment.duration : -1, 0));
5868 demux->cluster_time = GST_CLOCK_TIME_NONE;
5869 demux->cluster_offset = demux->parent.offset;
5870 /* eat cluster prefix */
5871 gst_matroska_demux_flush (demux, needed);
5873 case GST_MATROSKA_ID_CLUSTERTIMECODE:
5877 gst_matroska_demux_take (demux, length + needed);
5878 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
5880 GST_DEBUG_OBJECT (demux, "ClusterTimeCode: %" G_GUINT64_FORMAT, num);
5881 demux->cluster_time = num;
5884 case GST_MATROSKA_ID_BLOCKGROUP:
5885 gst_matroska_demux_take (demux, length + needed);
5886 DEBUG_ELEMENT_START (demux, ebml, "BlockGroup");
5887 if ((ret = gst_ebml_read_master (ebml, &id)) == GST_FLOW_OK) {
5888 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
5889 demux->cluster_time, demux->cluster_offset, FALSE);
5891 DEBUG_ELEMENT_STOP (demux, ebml, "BlockGroup", ret);
5892 if (ret != GST_FLOW_OK)
5895 case GST_MATROSKA_ID_SIMPLEBLOCK:
5896 gst_matroska_demux_take (demux, length + needed);
5897 DEBUG_ELEMENT_START (demux, ebml, "SimpleBlock");
5898 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
5899 demux->cluster_time, demux->cluster_offset, TRUE);
5900 DEBUG_ELEMENT_STOP (demux, ebml, "SimpleBlock", ret);
5901 if (ret != GST_FLOW_OK)
5904 case GST_MATROSKA_ID_ATTACHMENTS:
5905 if (!demux->attachments_parsed) {
5906 gst_matroska_demux_take (demux, length + needed);
5907 ret = gst_matroska_demux_parse_attachments (demux);
5909 gst_matroska_demux_flush (demux, needed + length);
5912 case GST_MATROSKA_ID_TAGS:
5913 gst_matroska_demux_take (demux, length + needed);
5914 ret = gst_matroska_demux_parse_metadata (demux);
5916 case GST_MATROSKA_ID_CHAPTERS:
5919 case GST_MATROSKA_ID_SEEKHEAD:
5920 gst_matroska_demux_take (demux, length + needed);
5921 DEBUG_ELEMENT_START (demux, ebml, "SeekHead");
5922 if ((ret = gst_ebml_read_master (ebml, &id)) == GST_FLOW_OK)
5923 ret = gst_matroska_demux_parse_contents (demux);
5924 if (ret != GST_FLOW_OK)
5927 case GST_MATROSKA_ID_CUES:
5928 if (demux->index_parsed) {
5929 gst_matroska_demux_flush (demux, needed + length);
5932 gst_matroska_demux_take (demux, length + needed);
5933 ret = gst_matroska_demux_parse_index (demux);
5934 if (demux->state == GST_MATROSKA_DEMUX_STATE_SEEK) {
5937 GST_OBJECT_LOCK (demux);
5938 event = demux->seek_event;
5939 demux->seek_event = NULL;
5940 GST_OBJECT_UNLOCK (demux);
5943 /* unlikely to fail, since we managed to seek to this point */
5944 if (!gst_matroska_demux_handle_seek_event (demux, NULL, event))
5946 /* resume data handling, main thread clear to seek again */
5947 GST_OBJECT_LOCK (demux);
5948 demux->state = GST_MATROSKA_DEMUX_STATE_DATA;
5949 GST_OBJECT_UNLOCK (demux);
5955 GST_DEBUG_OBJECT (demux, "skipping Element 0x%x (%s)", id, name);
5956 gst_matroska_demux_flush (demux, needed + length);
5962 if (ret != GST_FLOW_OK)
5973 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
5974 ("Failed to parse Element 0x%x", id));
5975 return GST_FLOW_ERROR;
5979 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
5980 ("File layout does not permit streaming"));
5981 return GST_FLOW_ERROR;
5985 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Invalid header"));
5986 return GST_FLOW_ERROR;
5990 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Failed to seek"));
5991 return GST_FLOW_ERROR;
5996 gst_matroska_demux_handle_sink_event (GstPad * pad, GstEvent * event)
5998 gboolean res = TRUE;
5999 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (pad));
6001 GST_DEBUG_OBJECT (demux,
6002 "have event type %s: %p on sink pad", GST_EVENT_TYPE_NAME (event), event);
6004 switch (GST_EVENT_TYPE (event)) {
6005 case GST_EVENT_NEWSEGMENT:
6008 gdouble rate, arate;
6009 gint64 start, stop, time = 0;
6013 /* some debug output */
6014 gst_segment_init (&segment, GST_FORMAT_UNDEFINED);
6015 gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format,
6016 &start, &stop, &time);
6017 gst_segment_set_newsegment_full (&segment, update, rate, arate, format,
6019 GST_DEBUG_OBJECT (demux,
6020 "received format %d newsegment %" GST_SEGMENT_FORMAT, format,
6023 if (demux->state < GST_MATROSKA_DEMUX_STATE_DATA) {
6024 GST_DEBUG_OBJECT (demux, "still starting");
6028 /* we only expect a BYTE segment, e.g. following a seek */
6029 if (format != GST_FORMAT_BYTES) {
6030 GST_DEBUG_OBJECT (demux, "unsupported segment format, ignoring");
6034 GST_DEBUG_OBJECT (demux, "clearing segment state");
6035 /* clear current segment leftover */
6036 gst_adapter_clear (demux->adapter);
6037 /* and some streaming setup */
6038 demux->offset = start;
6039 /* do not know where we are;
6040 * need to come across a cluster and generate newsegment */
6041 demux->segment.last_stop = GST_CLOCK_TIME_NONE;
6042 demux->cluster_time = GST_CLOCK_TIME_NONE;
6043 demux->cluster_offset = 0;
6044 demux->need_newsegment = TRUE;
6045 /* but keep some of the upstream segment */
6046 demux->segment.rate = rate;
6048 /* chain will send initial newsegment after pads have been added,
6049 * or otherwise come up with one */
6050 GST_DEBUG_OBJECT (demux, "eating event");
6051 gst_event_unref (event);
6057 if (demux->state != GST_MATROSKA_DEMUX_STATE_DATA) {
6058 gst_event_unref (event);
6059 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
6060 (NULL), ("got eos and didn't receive a complete header object"));
6061 } else if (demux->num_streams == 0) {
6062 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
6063 (NULL), ("got eos but no streams (yet)"));
6065 gst_matroska_demux_send_event (demux, event);
6069 case GST_EVENT_FLUSH_STOP:
6071 gst_adapter_clear (demux->adapter);
6072 gst_matroska_demux_reset_streams (demux, GST_CLOCK_TIME_NONE, TRUE);
6073 demux->segment.last_stop = GST_CLOCK_TIME_NONE;
6074 demux->cluster_time = GST_CLOCK_TIME_NONE;
6075 demux->cluster_offset = 0;
6079 res = gst_pad_event_default (pad, event);
6087 gst_matroska_demux_sink_activate (GstPad * sinkpad)
6089 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (sinkpad));
6091 if (gst_pad_check_pull_range (sinkpad)) {
6092 GST_DEBUG ("going to pull mode");
6093 demux->streaming = FALSE;
6094 return gst_pad_activate_pull (sinkpad, TRUE);
6096 GST_DEBUG ("going to push (streaming) mode");
6097 demux->streaming = TRUE;
6098 return gst_pad_activate_push (sinkpad, TRUE);
6105 gst_matroska_demux_sink_activate_pull (GstPad * sinkpad, gboolean active)
6107 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (sinkpad));
6110 /* if we have a scheduler we can start the task */
6111 demux->segment_running = TRUE;
6112 gst_pad_start_task (sinkpad, (GstTaskFunction) gst_matroska_demux_loop,
6115 demux->segment_running = FALSE;
6116 gst_pad_stop_task (sinkpad);
6123 * XXX: This code is duplicated in gst/qtdemux/qtdemux.c. Please replicate any
6124 * changes you make over there as well.
6127 avc_profile_idc_to_string (guint profile_idc, guint constraint_set_flags)
6129 const gchar *profile = NULL;
6132 csf1 = (constraint_set_flags & 0x40) >> 6;
6133 csf3 = (constraint_set_flags & 0x10) >> 4;
6135 switch (profile_idc) {
6138 profile = "constrained-baseline";
6140 profile = "baseline";
6146 profile = "extended";
6153 profile = "high-10-intra";
6155 profile = "high-10";
6159 profile = "high-4:2:2-intra";
6161 profile = "high-4:2:2";
6165 profile = "high-4:4:4-intra";
6167 profile = "high-4:4:4";
6170 profile = "cavlc-4:4:4-intra";
6176 return g_strdup (profile);
6180 avc_level_idc_to_string (guint level_idc, guint constraint_set_flags)
6184 csf3 = (constraint_set_flags & 0x10) >> 4;
6186 if (level_idc == 11 && csf3)
6187 return g_strdup ("1b");
6188 else if (level_idc % 10 == 0)
6189 return g_strdup_printf ("%u", level_idc / 10);
6191 return g_strdup_printf ("%u.%u", level_idc / 10, level_idc % 10);
6195 avc_get_profile_and_level_string (const guint8 * avc_data, gint size,
6196 gchar ** profile, gchar ** level)
6199 /* First byte is the version, second is the profile indication,
6200 * and third is the 5 contraint_set_flags and 3 reserved bits */
6201 *profile = avc_profile_idc_to_string (GST_READ_UINT8 (avc_data + 1),
6202 GST_READ_UINT8 (avc_data + 2));
6205 /* Fourth byte is the level indication */
6206 *level = avc_level_idc_to_string (GST_READ_UINT8 (avc_data + 3),
6207 GST_READ_UINT8 (avc_data + 2));
6211 gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext *
6212 videocontext, const gchar * codec_id, guint8 * data, guint size,
6213 gchar ** codec_name)
6215 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) videocontext;
6216 GstCaps *caps = NULL;
6218 g_assert (videocontext != NULL);
6219 g_assert (codec_name != NULL);
6221 context->send_xiph_headers = FALSE;
6222 context->send_flac_headers = FALSE;
6223 context->send_speex_headers = FALSE;
6225 /* TODO: check if we have all codec types from matroska-ids.h
6226 * check if we have to do more special things with codec_private
6229 * GST_MATROSKA_CODEC_ID_VIDEO_QUICKTIME
6230 * GST_MATROSKA_CODEC_ID_VIDEO_SNOW
6233 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VFW_FOURCC)) {
6234 gst_riff_strf_vids *vids = NULL;
6237 GstBuffer *buf = NULL;
6239 vids = (gst_riff_strf_vids *) data;
6241 /* assure size is big enough */
6243 GST_WARNING ("Too small BITMAPINFOHEADER (%d bytes)", size);
6246 if (size < sizeof (gst_riff_strf_vids)) {
6247 vids = g_new (gst_riff_strf_vids, 1);
6248 memcpy (vids, data, size);
6251 /* little-endian -> byte-order */
6252 vids->size = GUINT32_FROM_LE (vids->size);
6253 vids->width = GUINT32_FROM_LE (vids->width);
6254 vids->height = GUINT32_FROM_LE (vids->height);
6255 vids->planes = GUINT16_FROM_LE (vids->planes);
6256 vids->bit_cnt = GUINT16_FROM_LE (vids->bit_cnt);
6257 vids->compression = GUINT32_FROM_LE (vids->compression);
6258 vids->image_size = GUINT32_FROM_LE (vids->image_size);
6259 vids->xpels_meter = GUINT32_FROM_LE (vids->xpels_meter);
6260 vids->ypels_meter = GUINT32_FROM_LE (vids->ypels_meter);
6261 vids->num_colors = GUINT32_FROM_LE (vids->num_colors);
6262 vids->imp_colors = GUINT32_FROM_LE (vids->imp_colors);
6264 if (size > sizeof (gst_riff_strf_vids)) { /* some extra_data */
6265 buf = gst_buffer_new_and_alloc (size - sizeof (gst_riff_strf_vids));
6266 memcpy (GST_BUFFER_DATA (buf),
6267 (guint8 *) vids + sizeof (gst_riff_strf_vids),
6268 GST_BUFFER_SIZE (buf));
6271 caps = gst_riff_create_video_caps (vids->compression, NULL, vids,
6272 buf, NULL, codec_name);
6275 gst_buffer_unref (buf);
6277 if (vids != (gst_riff_strf_vids *) data)
6280 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_UNCOMPRESSED)) {
6283 switch (videocontext->fourcc) {
6284 case GST_MAKE_FOURCC ('I', '4', '2', '0'):
6285 *codec_name = g_strdup ("Raw planar YUV 4:2:0");
6286 fourcc = videocontext->fourcc;
6288 case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
6289 *codec_name = g_strdup ("Raw packed YUV 4:2:2");
6290 fourcc = videocontext->fourcc;
6292 case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
6293 *codec_name = g_strdup ("Raw packed YUV 4:2:0");
6294 fourcc = videocontext->fourcc;
6296 case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
6297 *codec_name = g_strdup ("Raw packed YUV 4:2:2");
6298 fourcc = videocontext->fourcc;
6300 case GST_MAKE_FOURCC ('A', 'Y', 'U', 'V'):
6301 *codec_name = g_strdup ("Raw packed YUV 4:4:4 with alpha channel");
6302 fourcc = videocontext->fourcc;
6306 GST_DEBUG ("Unknown fourcc %" GST_FOURCC_FORMAT,
6307 GST_FOURCC_ARGS (videocontext->fourcc));
6311 caps = gst_caps_new_simple ("video/x-raw-yuv",
6312 "format", GST_TYPE_FOURCC, fourcc, NULL);
6313 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_SP)) {
6314 caps = gst_caps_new_simple ("video/x-divx",
6315 "divxversion", G_TYPE_INT, 4, NULL);
6316 *codec_name = g_strdup ("MPEG-4 simple profile");
6317 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP) ||
6318 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AP)) {
6320 caps = gst_caps_new_full (gst_structure_new ("video/x-divx",
6321 "divxversion", G_TYPE_INT, 5, NULL),
6322 gst_structure_new ("video/x-xvid", NULL),
6323 gst_structure_new ("video/mpeg",
6324 "mpegversion", G_TYPE_INT, 4,
6325 "systemstream", G_TYPE_BOOLEAN, FALSE, NULL), NULL);
6327 caps = gst_caps_new_simple ("video/mpeg",
6328 "mpegversion", G_TYPE_INT, 4,
6329 "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
6331 GstBuffer *priv = gst_buffer_new_and_alloc (size);
6333 memcpy (GST_BUFFER_DATA (priv), data, size);
6334 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
6335 gst_buffer_unref (priv);
6337 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP))
6338 *codec_name = g_strdup ("MPEG-4 advanced simple profile");
6340 *codec_name = g_strdup ("MPEG-4 advanced profile");
6341 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MSMPEG4V3)) {
6343 caps = gst_caps_new_full (gst_structure_new ("video/x-divx",
6344 "divxversion", G_TYPE_INT, 3, NULL),
6345 gst_structure_new ("video/x-msmpeg",
6346 "msmpegversion", G_TYPE_INT, 43, NULL), NULL);
6348 caps = gst_caps_new_simple ("video/x-msmpeg",
6349 "msmpegversion", G_TYPE_INT, 43, NULL);
6350 *codec_name = g_strdup ("Microsoft MPEG-4 v.3");
6351 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1) ||
6352 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG2)) {
6353 gint mpegversion = -1;
6355 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1))
6357 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG2))
6360 g_assert_not_reached ();
6362 caps = gst_caps_new_simple ("video/mpeg",
6363 "systemstream", G_TYPE_BOOLEAN, FALSE,
6364 "mpegversion", G_TYPE_INT, mpegversion, NULL);
6365 *codec_name = g_strdup_printf ("MPEG-%d video", mpegversion);
6366 context->postprocess_frame = gst_matroska_demux_add_mpeg_seq_header;
6367 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MJPEG)) {
6368 caps = gst_caps_new_simple ("image/jpeg", NULL);
6369 *codec_name = g_strdup ("Motion-JPEG");
6370 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AVC)) {
6371 caps = gst_caps_new_simple ("video/x-h264", NULL);
6373 GstBuffer *priv = gst_buffer_new_and_alloc (size);
6374 gchar *profile = NULL, *level = NULL;
6376 avc_get_profile_and_level_string (data, size, &profile, &level);
6378 gst_caps_set_simple (caps, "profile", G_TYPE_STRING, profile, NULL);
6382 gst_caps_set_simple (caps, "level", G_TYPE_STRING, level, NULL);
6386 memcpy (GST_BUFFER_DATA (priv), data, size);
6387 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
6388 gst_buffer_unref (priv);
6391 *codec_name = g_strdup ("H264");
6392 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1)) ||
6393 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2)) ||
6394 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3)) ||
6395 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))) {
6396 gint rmversion = -1;
6398 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1))
6400 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2))
6402 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3))
6404 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))
6407 caps = gst_caps_new_simple ("video/x-pn-realvideo",
6408 "rmversion", G_TYPE_INT, rmversion, NULL);
6409 GST_DEBUG ("data:%p, size:0x%x", data, size);
6410 /* We need to extract the extradata ! */
6411 if (data && (size >= 0x22)) {
6416 subformat = GST_READ_UINT32_BE (data + 0x1a);
6417 rformat = GST_READ_UINT32_BE (data + 0x1e);
6419 priv = gst_buffer_new_and_alloc (size - 0x1a);
6421 memcpy (GST_BUFFER_DATA (priv), data + 0x1a, size - 0x1a);
6422 gst_caps_set_simple (caps,
6423 "codec_data", GST_TYPE_BUFFER, priv,
6424 "format", G_TYPE_INT, rformat,
6425 "subformat", G_TYPE_INT, subformat, NULL);
6426 gst_buffer_unref (priv);
6429 *codec_name = g_strdup_printf ("RealVideo %d.0", rmversion);
6430 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_THEORA)) {
6431 caps = gst_caps_new_simple ("video/x-theora", NULL);
6432 context->send_xiph_headers = TRUE;
6433 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_DIRAC)) {
6434 caps = gst_caps_new_simple ("video/x-dirac", NULL);
6435 context->send_xiph_headers = FALSE;
6436 *codec_name = g_strdup_printf ("Dirac");
6437 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8)) {
6438 caps = gst_caps_new_simple ("video/x-vp8", NULL);
6439 *codec_name = g_strdup_printf ("On2 VP8");
6441 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
6447 GstStructure *structure;
6449 for (i = 0; i < gst_caps_get_size (caps); i++) {
6450 structure = gst_caps_get_structure (caps, i);
6452 /* FIXME: use the real unit here! */
6453 GST_DEBUG ("video size %dx%d, target display size %dx%d (any unit)",
6454 videocontext->pixel_width,
6455 videocontext->pixel_height,
6456 videocontext->display_width, videocontext->display_height);
6458 /* pixel width and height are the w and h of the video in pixels */
6459 if (videocontext->pixel_width > 0 && videocontext->pixel_height > 0) {
6460 gint w = videocontext->pixel_width;
6462 gint h = videocontext->pixel_height;
6464 gst_structure_set (structure,
6465 "width", G_TYPE_INT, w, "height", G_TYPE_INT, h, NULL);
6468 if (videocontext->display_width > 0 && videocontext->display_height > 0) {
6471 /* calculate the pixel aspect ratio using the display and pixel w/h */
6472 n = videocontext->display_width * videocontext->pixel_height;
6473 d = videocontext->display_height * videocontext->pixel_width;
6474 GST_DEBUG ("setting PAR to %d/%d", n, d);
6475 gst_structure_set (structure, "pixel-aspect-ratio",
6477 videocontext->display_width * videocontext->pixel_height,
6478 videocontext->display_height * videocontext->pixel_width, NULL);
6481 if (videocontext->default_fps > 0.0) {
6482 GValue fps_double = { 0, };
6483 GValue fps_fraction = { 0, };
6485 g_value_init (&fps_double, G_TYPE_DOUBLE);
6486 g_value_init (&fps_fraction, GST_TYPE_FRACTION);
6487 g_value_set_double (&fps_double, videocontext->default_fps);
6488 g_value_transform (&fps_double, &fps_fraction);
6490 GST_DEBUG ("using default fps %f", videocontext->default_fps);
6492 gst_structure_set_value (structure, "framerate", &fps_fraction);
6493 g_value_unset (&fps_double);
6494 g_value_unset (&fps_fraction);
6495 } else if (context->default_duration > 0) {
6496 GValue fps_double = { 0, };
6497 GValue fps_fraction = { 0, };
6499 g_value_init (&fps_double, G_TYPE_DOUBLE);
6500 g_value_init (&fps_fraction, GST_TYPE_FRACTION);
6501 g_value_set_double (&fps_double, (gdouble) GST_SECOND /
6502 gst_guint64_to_gdouble (context->default_duration));
6503 g_value_transform (&fps_double, &fps_fraction);
6505 GST_DEBUG ("using default duration %" G_GUINT64_FORMAT,
6506 context->default_duration);
6508 gst_structure_set_value (structure, "framerate", &fps_fraction);
6509 g_value_unset (&fps_double);
6510 g_value_unset (&fps_fraction);
6512 /* sort of a hack to get most codecs to support,
6513 * even if the default_duration is missing */
6514 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
6518 if (videocontext->parent.flags & GST_MATROSKA_VIDEOTRACK_INTERLACED)
6519 gst_structure_set (structure, "interlaced", G_TYPE_BOOLEAN, TRUE, NULL);
6522 gst_caps_do_simplify (caps);
6529 * Some AAC specific code... *sigh*
6530 * FIXME: maybe we should use '15' and code the sample rate explicitly
6531 * if the sample rate doesn't match the predefined rates exactly? (tpm)
6535 aac_rate_idx (gint rate)
6539 else if (75132 <= rate)
6541 else if (55426 <= rate)
6543 else if (46009 <= rate)
6545 else if (37566 <= rate)
6547 else if (27713 <= rate)
6549 else if (23004 <= rate)
6551 else if (18783 <= rate)
6553 else if (13856 <= rate)
6555 else if (11502 <= rate)
6557 else if (9391 <= rate)
6564 aac_profile_idx (const gchar * codec_id)
6568 if (strlen (codec_id) <= 12)
6570 else if (!strncmp (&codec_id[12], "MAIN", 4))
6572 else if (!strncmp (&codec_id[12], "LC", 2))
6574 else if (!strncmp (&codec_id[12], "SSR", 3))
6582 #define AAC_SYNC_EXTENSION_TYPE 0x02b7
6585 gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext *
6586 audiocontext, const gchar * codec_id, guint8 * data, guint size,
6587 gchar ** codec_name)
6589 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) audiocontext;
6590 GstCaps *caps = NULL;
6592 g_assert (audiocontext != NULL);
6593 g_assert (codec_name != NULL);
6595 context->send_xiph_headers = FALSE;
6596 context->send_flac_headers = FALSE;
6597 context->send_speex_headers = FALSE;
6599 /* TODO: check if we have all codec types from matroska-ids.h
6600 * check if we have to do more special things with codec_private
6601 * check if we need bitdepth in different places too
6602 * implement channel position magic
6604 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID9
6605 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID10
6606 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDMC
6607 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDM2
6610 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1) ||
6611 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2) ||
6612 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L3)) {
6615 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1))
6617 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2))
6619 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L3))
6622 g_assert_not_reached ();
6624 caps = gst_caps_new_simple ("audio/mpeg",
6625 "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, layer, NULL);
6626 *codec_name = g_strdup_printf ("MPEG-1 layer %d", layer);
6627 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE) ||
6628 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_LE)) {
6629 gint endianness = -1;
6631 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE))
6632 endianness = G_BIG_ENDIAN;
6633 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_LE))
6634 endianness = G_LITTLE_ENDIAN;
6636 g_assert_not_reached ();
6638 caps = gst_caps_new_simple ("audio/x-raw-int",
6639 "width", G_TYPE_INT, audiocontext->bitdepth,
6640 "depth", G_TYPE_INT, audiocontext->bitdepth,
6641 "signed", G_TYPE_BOOLEAN, audiocontext->bitdepth != 8,
6642 "endianness", G_TYPE_INT, endianness, NULL);
6644 *codec_name = g_strdup_printf ("Raw %d-bit PCM audio",
6645 audiocontext->bitdepth);
6646 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_FLOAT)) {
6647 caps = gst_caps_new_simple ("audio/x-raw-float",
6648 "endianness", G_TYPE_INT, G_LITTLE_ENDIAN,
6649 "width", G_TYPE_INT, audiocontext->bitdepth, NULL);
6650 *codec_name = g_strdup_printf ("Raw %d-bit floating-point audio",
6651 audiocontext->bitdepth);
6652 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AC3,
6653 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AC3))) {
6654 caps = gst_caps_new_simple ("audio/x-ac3", NULL);
6655 *codec_name = g_strdup ("AC-3 audio");
6656 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_EAC3,
6657 strlen (GST_MATROSKA_CODEC_ID_AUDIO_EAC3))) {
6658 caps = gst_caps_new_simple ("audio/x-eac3", NULL);
6659 *codec_name = g_strdup ("E-AC-3 audio");
6660 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_DTS)) {
6661 caps = gst_caps_new_simple ("audio/x-dts", NULL);
6662 *codec_name = g_strdup ("DTS audio");
6663 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_VORBIS)) {
6664 caps = gst_caps_new_simple ("audio/x-vorbis", NULL);
6665 context->send_xiph_headers = TRUE;
6666 /* vorbis decoder does tags */
6667 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_FLAC)) {
6668 caps = gst_caps_new_simple ("audio/x-flac", NULL);
6669 context->send_flac_headers = TRUE;
6670 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_SPEEX)) {
6671 caps = gst_caps_new_simple ("audio/x-speex", NULL);
6672 context->send_speex_headers = TRUE;
6673 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_ACM)) {
6674 gst_riff_strf_auds auds;
6677 GstBuffer *codec_data = gst_buffer_new ();
6679 /* little-endian -> byte-order */
6680 auds.format = GST_READ_UINT16_LE (data);
6681 auds.channels = GST_READ_UINT16_LE (data + 2);
6682 auds.rate = GST_READ_UINT32_LE (data + 4);
6683 auds.av_bps = GST_READ_UINT32_LE (data + 8);
6684 auds.blockalign = GST_READ_UINT16_LE (data + 12);
6685 auds.size = GST_READ_UINT16_LE (data + 16);
6687 /* 18 is the waveformatex size */
6688 gst_buffer_set_data (codec_data, data + 18, auds.size);
6690 caps = gst_riff_create_audio_caps (auds.format, NULL, &auds, NULL,
6691 codec_data, codec_name);
6692 gst_buffer_unref (codec_data);
6694 } else if (g_str_has_prefix (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC)) {
6695 GstBuffer *priv = NULL;
6696 gint mpegversion = -1;
6697 gint rate_idx, profile;
6698 guint8 *data = NULL;
6700 /* unspecified AAC profile with opaque private codec data */
6701 if (strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC) == 0) {
6702 if (context->codec_priv_size >= 2) {
6703 guint obj_type, freq_index, explicit_freq_bytes = 0;
6705 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
6706 freq_index = (GST_READ_UINT16_BE (context->codec_priv) & 0x780) >> 7;
6707 obj_type = (GST_READ_UINT16_BE (context->codec_priv) & 0xF800) >> 11;
6708 if (freq_index == 15)
6709 explicit_freq_bytes = 3;
6710 GST_DEBUG ("obj_type = %u, freq_index = %u", obj_type, freq_index);
6711 priv = gst_buffer_new_and_alloc (context->codec_priv_size);
6712 memcpy (GST_BUFFER_DATA (priv), context->codec_priv,
6713 context->codec_priv_size);
6714 /* assume SBR if samplerate <= 24kHz */
6715 if (obj_type == 5 || (freq_index >= 6 && freq_index != 15) ||
6716 (context->codec_priv_size == (5 + explicit_freq_bytes))) {
6717 audiocontext->samplerate *= 2;
6720 GST_WARNING ("Opaque A_AAC codec ID, but no codec private data");
6721 /* just try this and see what happens ... */
6722 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
6726 /* make up decoder-specific data if it is not supplied */
6728 priv = gst_buffer_new_and_alloc (5);
6729 data = GST_BUFFER_DATA (priv);
6730 rate_idx = aac_rate_idx (audiocontext->samplerate);
6731 profile = aac_profile_idx (codec_id);
6733 data[0] = ((profile + 1) << 3) | ((rate_idx & 0xE) >> 1);
6734 data[1] = ((rate_idx & 0x1) << 7) | (audiocontext->channels << 3);
6735 GST_BUFFER_SIZE (priv) = 2;
6738 if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2,
6739 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2))) {
6741 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4,
6742 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4))) {
6745 if (g_strrstr (codec_id, "SBR")) {
6746 /* HE-AAC (aka SBR AAC) */
6747 audiocontext->samplerate *= 2;
6748 rate_idx = aac_rate_idx (audiocontext->samplerate);
6749 data[2] = AAC_SYNC_EXTENSION_TYPE >> 3;
6750 data[3] = ((AAC_SYNC_EXTENSION_TYPE & 0x07) << 5) | 5;
6751 data[4] = (1 << 7) | (rate_idx << 3);
6752 GST_BUFFER_SIZE (priv) = 5;
6755 g_assert_not_reached ();
6758 caps = gst_caps_new_simple ("audio/mpeg",
6759 "mpegversion", G_TYPE_INT, mpegversion,
6760 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
6762 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
6764 *codec_name = g_strdup_printf ("MPEG-%d AAC audio", mpegversion);
6765 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TTA)) {
6766 caps = gst_caps_new_simple ("audio/x-tta",
6767 "width", G_TYPE_INT, audiocontext->bitdepth, NULL);
6768 *codec_name = g_strdup ("TTA audio");
6769 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_WAVPACK4)) {
6770 caps = gst_caps_new_simple ("audio/x-wavpack",
6771 "width", G_TYPE_INT, audiocontext->bitdepth,
6772 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
6773 *codec_name = g_strdup ("Wavpack audio");
6774 context->postprocess_frame = gst_matroska_demux_add_wvpk_header;
6775 audiocontext->wvpk_block_index = 0;
6776 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4)) ||
6777 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4)) ||
6778 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))) {
6779 gint raversion = -1;
6781 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4))
6783 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))
6788 caps = gst_caps_new_simple ("audio/x-pn-realaudio",
6789 "raversion", G_TYPE_INT, raversion, NULL);
6790 /* Extract extra information from caps, mapping varies based on codec */
6791 if (data && (size >= 0x50)) {
6798 guint extra_data_size;
6800 GST_ERROR ("real audio raversion:%d", raversion);
6801 if (raversion == 8) {
6803 flavor = GST_READ_UINT16_BE (data + 22);
6804 packet_size = GST_READ_UINT32_BE (data + 24);
6805 height = GST_READ_UINT16_BE (data + 40);
6806 leaf_size = GST_READ_UINT16_BE (data + 44);
6807 sample_width = GST_READ_UINT16_BE (data + 58);
6808 extra_data_size = GST_READ_UINT32_BE (data + 74);
6811 ("flavor:%d, packet_size:%d, height:%d, leaf_size:%d, sample_width:%d, extra_data_size:%d",
6812 flavor, packet_size, height, leaf_size, sample_width,
6814 gst_caps_set_simple (caps, "flavor", G_TYPE_INT, flavor, "packet_size",
6815 G_TYPE_INT, packet_size, "height", G_TYPE_INT, height, "leaf_size",
6816 G_TYPE_INT, leaf_size, "width", G_TYPE_INT, sample_width, NULL);
6818 if ((size - 78) >= extra_data_size) {
6819 priv = gst_buffer_new_and_alloc (extra_data_size);
6820 memcpy (GST_BUFFER_DATA (priv), data + 78, extra_data_size);
6821 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
6822 gst_buffer_unref (priv);
6827 *codec_name = g_strdup_printf ("RealAudio %d.0", raversion);
6828 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_SIPR)) {
6829 caps = gst_caps_new_simple ("audio/x-sipro", NULL);
6830 *codec_name = g_strdup ("Sipro/ACELP.NET Voice Codec");
6831 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_RALF)) {
6832 caps = gst_caps_new_simple ("audio/x-ralf-mpeg4-generic", NULL);
6833 *codec_name = g_strdup ("Real Audio Lossless");
6834 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_ATRC)) {
6835 caps = gst_caps_new_simple ("audio/x-vnd.sony.atrac3", NULL);
6836 *codec_name = g_strdup ("Sony ATRAC3");
6838 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
6843 if (audiocontext->samplerate > 0 && audiocontext->channels > 0) {
6846 for (i = 0; i < gst_caps_get_size (caps); i++) {
6847 gst_structure_set (gst_caps_get_structure (caps, i),
6848 "channels", G_TYPE_INT, audiocontext->channels,
6849 "rate", G_TYPE_INT, audiocontext->samplerate, NULL);
6853 gst_caps_do_simplify (caps);
6860 gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
6861 subtitlecontext, const gchar * codec_id, gpointer data, guint size)
6863 GstCaps *caps = NULL;
6864 GstMatroskaTrackContext *context =
6865 (GstMatroskaTrackContext *) subtitlecontext;
6867 /* for backwards compatibility */
6868 if (!g_ascii_strcasecmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASCII))
6869 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8;
6870 else if (!g_ascii_strcasecmp (codec_id, "S_SSA"))
6871 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_SSA;
6872 else if (!g_ascii_strcasecmp (codec_id, "S_ASS"))
6873 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_ASS;
6874 else if (!g_ascii_strcasecmp (codec_id, "S_USF"))
6875 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_USF;
6877 /* TODO: Add GST_MATROSKA_CODEC_ID_SUBTITLE_BMP support
6878 * Check if we have to do something with codec_private */
6879 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8)) {
6880 caps = gst_caps_new_simple ("text/plain", NULL);
6881 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
6882 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_SSA)) {
6883 caps = gst_caps_new_simple ("application/x-ssa", NULL);
6884 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
6885 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASS)) {
6886 caps = gst_caps_new_simple ("application/x-ass", NULL);
6887 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
6888 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_USF)) {
6889 caps = gst_caps_new_simple ("application/x-usf", NULL);
6890 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
6891 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB)) {
6892 caps = gst_caps_new_simple ("video/x-dvd-subpicture", NULL);
6893 ((GstMatroskaTrackContext *) subtitlecontext)->send_dvd_event = TRUE;
6894 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_HDMVPGS)) {
6895 caps = gst_caps_new_simple ("subpicture/x-pgs", NULL);
6896 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_KATE)) {
6897 caps = gst_caps_new_simple ("subtitle/x-kate", NULL);
6898 context->send_xiph_headers = TRUE;
6900 GST_DEBUG ("Unknown subtitle stream: codec_id='%s'", codec_id);
6901 caps = gst_caps_new_simple ("application/x-subtitle-unknown", NULL);
6904 if (data != NULL && size > 0) {
6907 buf = gst_buffer_new_and_alloc (size);
6908 memcpy (GST_BUFFER_DATA (buf), data, size);
6909 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, buf, NULL);
6910 gst_buffer_unref (buf);
6917 gst_matroska_demux_set_index (GstElement * element, GstIndex * index)
6919 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
6921 GST_OBJECT_LOCK (demux);
6922 if (demux->element_index)
6923 gst_object_unref (demux->element_index);
6924 demux->element_index = index ? gst_object_ref (index) : NULL;
6925 GST_OBJECT_UNLOCK (demux);
6926 GST_DEBUG_OBJECT (demux, "Set index %" GST_PTR_FORMAT, demux->element_index);
6930 gst_matroska_demux_get_index (GstElement * element)
6932 GstIndex *result = NULL;
6933 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
6935 GST_OBJECT_LOCK (demux);
6936 if (demux->element_index)
6937 result = gst_object_ref (demux->element_index);
6938 GST_OBJECT_UNLOCK (demux);
6940 GST_DEBUG_OBJECT (demux, "Returning index %" GST_PTR_FORMAT, result);
6945 static GstStateChangeReturn
6946 gst_matroska_demux_change_state (GstElement * element,
6947 GstStateChange transition)
6949 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
6950 GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
6952 /* handle upwards state changes here */
6953 switch (transition) {
6958 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
6960 /* handle downwards state changes */
6961 switch (transition) {
6962 case GST_STATE_CHANGE_PAUSED_TO_READY:
6963 gst_matroska_demux_reset (GST_ELEMENT (demux));
6973 gst_matroska_demux_plugin_init (GstPlugin * plugin)
6977 /* create an elementfactory for the matroska_demux element */
6978 if (!gst_element_register (plugin, "matroskademux",
6979 GST_RANK_PRIMARY, GST_TYPE_MATROSKA_DEMUX))