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, gst_ebml_read_get_pos (ebml))
85 #define DEBUG_ELEMENT_STOP(demux, ebml, element, ret) \
86 GST_DEBUG_OBJECT (demux, "Parsing " element " element " \
87 " finished with '%s'", gst_flow_get_name (ret))
96 static GstStaticPadTemplate sink_templ = GST_STATIC_PAD_TEMPLATE ("sink",
99 GST_STATIC_CAPS ("video/x-matroska; video/webm")
102 /* TODO: fill in caps! */
104 static GstStaticPadTemplate audio_src_templ =
105 GST_STATIC_PAD_TEMPLATE ("audio_%02d",
108 GST_STATIC_CAPS ("ANY")
111 static GstStaticPadTemplate video_src_templ =
112 GST_STATIC_PAD_TEMPLATE ("video_%02d",
115 GST_STATIC_CAPS ("ANY")
118 static GstStaticPadTemplate subtitle_src_templ =
119 GST_STATIC_PAD_TEMPLATE ("subtitle_%02d",
122 GST_STATIC_CAPS ("text/plain; application/x-ssa; application/x-ass; "
123 "application/x-usf; video/x-dvd-subpicture; "
124 "subpicture/x-pgs; subtitle/x-kate; " "application/x-subtitle-unknown")
127 static GstFlowReturn gst_matroska_demux_parse_id (GstMatroskaDemux * demux,
128 guint32 id, guint64 length, guint needed);
130 /* element functions */
131 static void gst_matroska_demux_loop (GstPad * pad);
133 static gboolean gst_matroska_demux_element_send_event (GstElement * element,
135 static gboolean gst_matroska_demux_element_query (GstElement * element,
139 static gboolean gst_matroska_demux_sink_activate_pull (GstPad * sinkpad,
141 static gboolean gst_matroska_demux_sink_activate (GstPad * sinkpad);
143 static gboolean gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
144 GstPad * pad, GstEvent * event);
145 static gboolean gst_matroska_demux_handle_src_event (GstPad * pad,
147 static const GstQueryType *gst_matroska_demux_get_src_query_types (GstPad *
149 static gboolean gst_matroska_demux_handle_src_query (GstPad * pad,
152 static gboolean gst_matroska_demux_handle_sink_event (GstPad * pad,
154 static GstFlowReturn gst_matroska_demux_chain (GstPad * pad,
157 static GstStateChangeReturn
158 gst_matroska_demux_change_state (GstElement * element,
159 GstStateChange transition);
161 gst_matroska_demux_set_index (GstElement * element, GstIndex * index);
162 static GstIndex *gst_matroska_demux_get_index (GstElement * element);
165 static GstCaps *gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext
167 const gchar * codec_id, guint8 * data, guint size, gchar ** codec_name);
168 static GstCaps *gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext
170 const gchar * codec_id, guint8 * data, guint size, gchar ** codec_name);
172 * gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
173 subtitlecontext, const gchar * codec_id, gpointer data, guint size);
176 static void gst_matroska_demux_reset (GstElement * element);
177 static gboolean perform_seek_to_offset (GstMatroskaDemux * demux,
180 GType gst_matroska_demux_get_type (void);
181 GST_BOILERPLATE (GstMatroskaDemux, gst_matroska_demux, GstElement,
185 gst_matroska_demux_base_init (gpointer klass)
187 GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
189 gst_element_class_add_pad_template (element_class,
190 gst_static_pad_template_get (&video_src_templ));
191 gst_element_class_add_pad_template (element_class,
192 gst_static_pad_template_get (&audio_src_templ));
193 gst_element_class_add_pad_template (element_class,
194 gst_static_pad_template_get (&subtitle_src_templ));
195 gst_element_class_add_pad_template (element_class,
196 gst_static_pad_template_get (&sink_templ));
198 gst_element_class_set_details_simple (element_class, "Matroska demuxer",
200 "Demuxes Matroska/WebM streams into video/audio/subtitles",
201 "GStreamer maintainers <gstreamer-devel@lists.sourceforge.net>");
205 gst_matroska_demux_finalize (GObject * object)
207 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (object);
210 g_ptr_array_free (demux->src, TRUE);
214 if (demux->global_tags) {
215 gst_tag_list_free (demux->global_tags);
216 demux->global_tags = NULL;
219 g_object_unref (demux->adapter);
221 G_OBJECT_CLASS (parent_class)->finalize (object);
225 gst_matroska_demux_class_init (GstMatroskaDemuxClass * klass)
227 GObjectClass *gobject_class = (GObjectClass *) klass;
228 GstElementClass *gstelement_class = (GstElementClass *) klass;
230 /* parser helper separate debug */
231 GST_DEBUG_CATEGORY_INIT (ebmlread_debug, "ebmlread",
232 0, "EBML stream helper class");
234 GST_DEBUG_CATEGORY_INIT (matroskademux_debug, "matroskademux", 0,
237 gobject_class->finalize = gst_matroska_demux_finalize;
239 gstelement_class->change_state =
240 GST_DEBUG_FUNCPTR (gst_matroska_demux_change_state);
241 gstelement_class->send_event =
242 GST_DEBUG_FUNCPTR (gst_matroska_demux_element_send_event);
243 gstelement_class->query =
244 GST_DEBUG_FUNCPTR (gst_matroska_demux_element_query);
246 gstelement_class->set_index =
247 GST_DEBUG_FUNCPTR (gst_matroska_demux_set_index);
248 gstelement_class->get_index =
249 GST_DEBUG_FUNCPTR (gst_matroska_demux_get_index);
253 gst_matroska_demux_init (GstMatroskaDemux * demux,
254 GstMatroskaDemuxClass * klass)
256 demux->sinkpad = gst_pad_new_from_static_template (&sink_templ, "sink");
257 gst_pad_set_activate_function (demux->sinkpad,
258 GST_DEBUG_FUNCPTR (gst_matroska_demux_sink_activate));
259 gst_pad_set_activatepull_function (demux->sinkpad,
260 GST_DEBUG_FUNCPTR (gst_matroska_demux_sink_activate_pull));
261 gst_pad_set_chain_function (demux->sinkpad,
262 GST_DEBUG_FUNCPTR (gst_matroska_demux_chain));
263 gst_pad_set_event_function (demux->sinkpad,
264 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_sink_event));
265 gst_element_add_pad (GST_ELEMENT (demux), demux->sinkpad);
267 /* initial stream no. */
270 demux->writing_app = NULL;
271 demux->muxing_app = NULL;
273 demux->global_tags = NULL;
275 demux->adapter = gst_adapter_new ();
278 gst_matroska_demux_reset (GST_ELEMENT (demux));
282 gst_matroska_track_free (GstMatroskaTrackContext * track)
284 g_free (track->codec_id);
285 g_free (track->codec_name);
286 g_free (track->name);
287 g_free (track->language);
288 g_free (track->codec_priv);
289 g_free (track->codec_state);
291 if (track->encodings != NULL) {
294 for (i = 0; i < track->encodings->len; ++i) {
295 GstMatroskaTrackEncoding *enc = &g_array_index (track->encodings,
296 GstMatroskaTrackEncoding,
299 g_free (enc->comp_settings);
301 g_array_free (track->encodings, TRUE);
304 if (track->pending_tags)
305 gst_tag_list_free (track->pending_tags);
307 if (track->index_table)
308 g_array_free (track->index_table, TRUE);
314 * Returns the aggregated GstFlowReturn.
317 gst_matroska_demux_combine_flows (GstMatroskaDemux * demux,
318 GstMatroskaTrackContext * track, GstFlowReturn ret)
322 /* store the value */
323 track->last_flow = ret;
325 /* any other error that is not-linked can be returned right away */
326 if (ret != GST_FLOW_NOT_LINKED)
329 /* only return NOT_LINKED if all other pads returned NOT_LINKED */
330 g_assert (demux->src->len == demux->num_streams);
331 for (i = 0; i < demux->src->len; i++) {
332 GstMatroskaTrackContext *ostream = g_ptr_array_index (demux->src, i);
337 ret = ostream->last_flow;
338 /* some other return value (must be SUCCESS but we can return
339 * other values as well) */
340 if (ret != GST_FLOW_NOT_LINKED)
343 /* if we get here, all other pads were unlinked and we return
346 GST_LOG_OBJECT (demux, "combined return %s", gst_flow_get_name (ret));
351 gst_matroska_demux_free_parsed_el (gpointer mem, gpointer user_data)
353 g_slice_free (guint64, mem);
357 gst_matroska_demux_reset (GstElement * element)
359 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
362 GST_DEBUG_OBJECT (demux, "Resetting state");
365 demux->state = GST_MATROSKA_DEMUX_STATE_START;
367 /* clean up existing streams */
369 g_assert (demux->src->len == demux->num_streams);
370 for (i = 0; i < demux->src->len; i++) {
371 GstMatroskaTrackContext *context = g_ptr_array_index (demux->src, i);
373 if (context->pad != NULL)
374 gst_element_remove_pad (GST_ELEMENT (demux), context->pad);
376 gst_caps_replace (&context->caps, NULL);
377 gst_matroska_track_free (context);
379 g_ptr_array_free (demux->src, TRUE);
381 demux->src = g_ptr_array_new ();
383 demux->num_streams = 0;
384 demux->num_a_streams = 0;
385 demux->num_t_streams = 0;
386 demux->num_v_streams = 0;
388 /* reset media info */
389 g_free (demux->writing_app);
390 demux->writing_app = NULL;
391 g_free (demux->muxing_app);
392 demux->muxing_app = NULL;
396 g_array_free (demux->index, TRUE);
402 demux->time_scale = 1000000;
403 demux->created = G_MININT64;
405 demux->index_parsed = FALSE;
406 demux->tracks_parsed = FALSE;
407 demux->segmentinfo_parsed = FALSE;
408 demux->attachments_parsed = FALSE;
410 g_list_foreach (demux->tags_parsed,
411 (GFunc) gst_matroska_demux_free_parsed_el, NULL);
412 g_list_free (demux->tags_parsed);
413 demux->tags_parsed = NULL;
415 g_list_foreach (demux->seek_parsed,
416 (GFunc) gst_matroska_demux_free_parsed_el, NULL);
417 g_list_free (demux->seek_parsed);
418 demux->seek_parsed = NULL;
420 gst_segment_init (&demux->segment, GST_FORMAT_TIME);
421 demux->last_stop_end = GST_CLOCK_TIME_NONE;
422 demux->seek_block = 0;
425 demux->cluster_time = GST_CLOCK_TIME_NONE;
426 demux->cluster_offset = 0;
427 demux->index_offset = 0;
428 demux->seekable = FALSE;
429 demux->need_newsegment = FALSE;
430 demux->building_index = FALSE;
431 if (demux->seek_event) {
432 gst_event_unref (demux->seek_event);
433 demux->seek_event = NULL;
436 demux->seek_index = NULL;
437 demux->seek_entry = 0;
439 if (demux->close_segment) {
440 gst_event_unref (demux->close_segment);
441 demux->close_segment = NULL;
444 if (demux->new_segment) {
445 gst_event_unref (demux->new_segment);
446 demux->new_segment = NULL;
449 if (demux->element_index) {
450 gst_object_unref (demux->element_index);
451 demux->element_index = NULL;
453 demux->element_index_writer_id = -1;
455 if (demux->global_tags) {
456 gst_tag_list_free (demux->global_tags);
458 demux->global_tags = gst_tag_list_new ();
460 if (demux->cached_buffer) {
461 gst_buffer_unref (demux->cached_buffer);
462 demux->cached_buffer = NULL;
467 * Calls pull_range for (offset,size) without advancing our offset
470 gst_matroska_demux_peek_bytes (GstMatroskaDemux * demux, guint64 offset,
471 guint size, GstBuffer ** p_buf, guint8 ** bytes)
475 /* Caching here actually makes much less difference than one would expect.
476 * We do it mainly to avoid pulling buffers of 1 byte all the time */
477 if (demux->cached_buffer) {
478 guint64 cache_offset = GST_BUFFER_OFFSET (demux->cached_buffer);
479 guint cache_size = GST_BUFFER_SIZE (demux->cached_buffer);
481 if (cache_offset <= demux->offset &&
482 (demux->offset + size) <= (cache_offset + cache_size)) {
484 *p_buf = gst_buffer_create_sub (demux->cached_buffer,
485 demux->offset - cache_offset, size);
487 *bytes = GST_BUFFER_DATA (demux->cached_buffer) + demux->offset -
491 /* not enough data in the cache, free cache and get a new one */
492 gst_buffer_unref (demux->cached_buffer);
493 demux->cached_buffer = NULL;
496 /* refill the cache */
497 ret = gst_pad_pull_range (demux->sinkpad, demux->offset,
498 MAX (size, 64 * 1024), &demux->cached_buffer);
499 if (ret != GST_FLOW_OK) {
500 demux->cached_buffer = NULL;
504 if (GST_BUFFER_SIZE (demux->cached_buffer) >= size) {
506 *p_buf = gst_buffer_create_sub (demux->cached_buffer, 0, size);
508 *bytes = GST_BUFFER_DATA (demux->cached_buffer);
512 /* Not possible to get enough data, try a last time with
513 * requesting exactly the size we need */
514 gst_buffer_unref (demux->cached_buffer);
515 demux->cached_buffer = NULL;
518 gst_pad_pull_range (demux->sinkpad, demux->offset, size,
519 &demux->cached_buffer);
520 if (ret != GST_FLOW_OK) {
521 GST_DEBUG_OBJECT (demux, "pull_range returned %d", ret);
529 if (GST_BUFFER_SIZE (demux->cached_buffer) < size) {
530 GST_WARNING_OBJECT (demux, "Dropping short buffer at offset %"
531 G_GUINT64_FORMAT ": wanted %u bytes, got %u bytes", demux->offset,
532 size, GST_BUFFER_SIZE (demux->cached_buffer));
534 gst_buffer_unref (demux->cached_buffer);
535 demux->cached_buffer = NULL;
540 return GST_FLOW_UNEXPECTED;
544 *p_buf = gst_buffer_create_sub (demux->cached_buffer, 0, size);
546 *bytes = GST_BUFFER_DATA (demux->cached_buffer);
551 static const guint8 *
552 gst_matroska_demux_peek_pull (GstMatroskaDemux * demux, guint peek)
556 gst_matroska_demux_peek_bytes (demux, demux->offset, peek, NULL, &data);
561 gst_matroska_demux_peek_id_length_pull (GstMatroskaDemux * demux, guint32 * _id,
562 guint64 * _length, guint * _needed)
564 return gst_ebml_peek_id_length (_id, _length, _needed,
565 (GstPeekData) gst_matroska_demux_peek_pull, (gpointer) demux,
566 GST_ELEMENT_CAST (demux), demux->offset);
570 gst_matroska_demux_get_length (GstMatroskaDemux * demux)
572 GstFormat fmt = GST_FORMAT_BYTES;
575 /* FIXME: what to do if we don't get the upstream length */
576 if (!gst_pad_query_peer_duration (demux->sinkpad, &fmt, &end) ||
577 fmt != GST_FORMAT_BYTES || end < 0)
578 g_return_val_if_reached (0);
584 gst_matroska_demux_stream_from_num (GstMatroskaDemux * demux, guint track_num)
588 g_assert (demux->src->len == demux->num_streams);
589 for (n = 0; n < demux->src->len; n++) {
590 GstMatroskaTrackContext *context = g_ptr_array_index (demux->src, n);
592 if (context->num == track_num) {
597 if (n == demux->num_streams)
598 GST_WARNING_OBJECT (demux,
599 "Failed to find corresponding pad for tracknum %d", track_num);
605 gst_matroska_demux_encoding_cmp (GstMatroskaTrackEncoding * a,
606 GstMatroskaTrackEncoding * b)
608 if (b->order > a->order)
610 else if (b->order < a->order)
617 gst_matroska_demux_encoding_order_unique (GArray * encodings, guint64 order)
621 if (encodings == NULL || encodings->len == 0)
624 for (i = 0; i < encodings->len; i++)
625 if (g_array_index (encodings, GstMatroskaTrackEncoding, i).order == order)
632 gst_matroska_demux_read_track_encoding (GstMatroskaDemux * demux,
633 GstEbmlRead * ebml, GstMatroskaTrackContext * context)
635 GstMatroskaTrackEncoding enc = { 0, };
639 DEBUG_ELEMENT_START (demux, ebml, "ContentEncoding");
640 /* Set default values */
642 /* All other default values are 0 */
644 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
645 DEBUG_ELEMENT_STOP (demux, ebml, "ContentEncoding", ret);
649 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
650 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
654 case GST_MATROSKA_ID_CONTENTENCODINGORDER:{
657 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
660 if (!gst_matroska_demux_encoding_order_unique (context->encodings, num)) {
661 GST_ERROR_OBJECT (demux, "ContentEncodingOrder %" G_GUINT64_FORMAT
662 "is not unique for track %d", num, context->num);
663 ret = GST_FLOW_ERROR;
667 GST_DEBUG_OBJECT (demux, "ContentEncodingOrder: %" G_GUINT64_FORMAT,
672 case GST_MATROSKA_ID_CONTENTENCODINGSCOPE:{
675 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
678 if (num > 7 && num == 0) {
679 GST_ERROR_OBJECT (demux, "Invalid ContentEncodingScope %"
680 G_GUINT64_FORMAT, num);
681 ret = GST_FLOW_ERROR;
685 GST_DEBUG_OBJECT (demux, "ContentEncodingScope: %" G_GUINT64_FORMAT,
691 case GST_MATROSKA_ID_CONTENTENCODINGTYPE:{
694 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
698 GST_ERROR_OBJECT (demux, "Invalid ContentEncodingType %"
699 G_GUINT64_FORMAT, num);
700 ret = GST_FLOW_ERROR;
702 } else if (num != 0) {
703 GST_ERROR_OBJECT (demux, "Encrypted tracks are not supported yet");
704 ret = GST_FLOW_ERROR;
707 GST_DEBUG_OBJECT (demux, "ContentEncodingType: %" G_GUINT64_FORMAT,
712 case GST_MATROSKA_ID_CONTENTCOMPRESSION:{
714 DEBUG_ELEMENT_START (demux, ebml, "ContentCompression");
716 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
719 while (ret == GST_FLOW_OK &&
720 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
721 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
725 case GST_MATROSKA_ID_CONTENTCOMPALGO:{
728 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK) {
732 GST_ERROR_OBJECT (demux, "Invalid ContentCompAlgo %"
733 G_GUINT64_FORMAT, num);
734 ret = GST_FLOW_ERROR;
737 GST_DEBUG_OBJECT (demux, "ContentCompAlgo: %" G_GUINT64_FORMAT,
743 case GST_MATROSKA_ID_CONTENTCOMPSETTINGS:{
748 gst_ebml_read_binary (ebml, &id, &data,
749 &size)) != GST_FLOW_OK) {
752 enc.comp_settings = data;
753 enc.comp_settings_length = size;
754 GST_DEBUG_OBJECT (demux,
755 "ContentCompSettings of size %" G_GUINT64_FORMAT, size);
759 GST_WARNING_OBJECT (demux,
760 "Unknown ContentCompression subelement 0x%x - ignoring", id);
761 ret = gst_ebml_read_skip (ebml);
765 DEBUG_ELEMENT_STOP (demux, ebml, "ContentCompression", ret);
769 case GST_MATROSKA_ID_CONTENTENCRYPTION:
770 GST_ERROR_OBJECT (demux, "Encrypted tracks not yet supported");
771 gst_ebml_read_skip (ebml);
772 ret = GST_FLOW_ERROR;
775 GST_WARNING_OBJECT (demux,
776 "Unknown ContentEncoding subelement 0x%x - ignoring", id);
777 ret = gst_ebml_read_skip (ebml);
782 DEBUG_ELEMENT_STOP (demux, ebml, "ContentEncoding", ret);
783 if (ret != GST_FLOW_OK && ret != GST_FLOW_UNEXPECTED)
786 /* TODO: Check if the combination of values is valid */
788 g_array_append_val (context->encodings, enc);
794 gst_matroska_decompress_data (GstMatroskaTrackEncoding * enc,
795 guint8 ** data_out, guint * size_out,
796 GstMatroskaTrackCompressionAlgorithm algo)
798 guint8 *new_data = NULL;
801 guint8 *data = *data_out;
802 guint size = *size_out;
806 if (algo == GST_MATROSKA_TRACK_COMPRESSION_ALGORITHM_ZLIB) {
808 /* zlib encoded data */
814 zstream.zalloc = (alloc_func) 0;
815 zstream.zfree = (free_func) 0;
816 zstream.opaque = (voidpf) 0;
817 if (inflateInit (&zstream) != Z_OK) {
818 GST_WARNING ("zlib initialization failed.");
822 zstream.next_in = (Bytef *) data;
823 zstream.avail_in = orig_size;
824 new_size = orig_size;
825 new_data = g_malloc (new_size);
826 zstream.avail_out = new_size;
827 zstream.next_out = (Bytef *) new_data;
830 result = inflate (&zstream, Z_NO_FLUSH);
831 if (result != Z_OK && result != Z_STREAM_END) {
832 GST_WARNING ("zlib decompression failed.");
834 inflateEnd (&zstream);
838 new_data = g_realloc (new_data, new_size);
839 zstream.next_out = (Bytef *) (new_data + zstream.total_out);
840 zstream.avail_out += 4000;
841 } while (zstream.avail_in != 0 && result != Z_STREAM_END);
843 if (result != Z_STREAM_END) {
847 new_size = zstream.total_out;
848 inflateEnd (&zstream);
851 GST_WARNING ("zlib encoded tracks not supported.");
855 } else if (algo == GST_MATROSKA_TRACK_COMPRESSION_ALGORITHM_BZLIB) {
857 /* bzip2 encoded data */
862 bzstream.bzalloc = NULL;
863 bzstream.bzfree = NULL;
864 bzstream.opaque = NULL;
867 if (BZ2_bzDecompressInit (&bzstream, 0, 0) != BZ_OK) {
868 GST_WARNING ("bzip2 initialization failed.");
873 bzstream.next_in = (char *) data;
874 bzstream.avail_in = orig_size;
875 new_size = orig_size;
876 new_data = g_malloc (new_size);
877 bzstream.avail_out = new_size;
878 bzstream.next_out = (char *) new_data;
881 result = BZ2_bzDecompress (&bzstream);
882 if (result != BZ_OK && result != BZ_STREAM_END) {
883 GST_WARNING ("bzip2 decompression failed.");
885 BZ2_bzDecompressEnd (&bzstream);
889 new_data = g_realloc (new_data, new_size);
890 bzstream.next_out = (char *) (new_data + bzstream.total_out_lo32);
891 bzstream.avail_out += 4000;
892 } while (bzstream.avail_in != 0 && result != BZ_STREAM_END);
894 if (result != BZ_STREAM_END) {
898 new_size = bzstream.total_out_lo32;
899 BZ2_bzDecompressEnd (&bzstream);
902 GST_WARNING ("bzip2 encoded tracks not supported.");
906 } else if (algo == GST_MATROSKA_TRACK_COMPRESSION_ALGORITHM_LZO1X) {
907 /* lzo encoded data */
909 int orig_size, out_size;
914 new_data = g_malloc (new_size);
920 result = lzo1x_decode (new_data, &out_size, data, &orig_size);
924 new_data = g_realloc (new_data, new_size);
926 } while (orig_size > 0 && result == LZO_OUTPUT_FULL);
928 new_size -= out_size;
930 if (result != LZO_OUTPUT_FULL) {
931 GST_WARNING ("lzo decompression failed");
938 } else if (algo == GST_MATROSKA_TRACK_COMPRESSION_ALGORITHM_HEADERSTRIP) {
939 /* header stripped encoded data */
940 if (enc->comp_settings_length > 0) {
941 new_data = g_malloc (size + enc->comp_settings_length);
942 new_size = size + enc->comp_settings_length;
944 memcpy (new_data, enc->comp_settings, enc->comp_settings_length);
945 memcpy (new_data + enc->comp_settings_length, data, size);
948 g_assert_not_reached ();
957 *data_out = new_data;
958 *size_out = new_size;
965 gst_matroska_decode_data (GArray * encodings, guint8 ** data_out,
966 guint * size_out, GstMatroskaTrackEncodingScope scope, gboolean free)
973 g_return_val_if_fail (encodings != NULL, FALSE);
974 g_return_val_if_fail (data_out != NULL && *data_out != NULL, FALSE);
975 g_return_val_if_fail (size_out != NULL, FALSE);
980 for (i = 0; i < encodings->len; i++) {
981 GstMatroskaTrackEncoding *enc =
982 &g_array_index (encodings, GstMatroskaTrackEncoding, i);
983 guint8 *new_data = NULL;
986 if ((enc->scope & scope) == 0)
989 /* Encryption not supported yet */
990 if (enc->type != 0) {
999 gst_matroska_decompress_data (enc, &new_data, &new_size,
1005 if ((data == *data_out && free) || (data != *data_out))
1013 if ((data == *data_out && free) || (data != *data_out))
1027 gst_matroska_decode_buffer (GstMatroskaTrackContext * context, GstBuffer * buf)
1033 g_return_val_if_fail (GST_IS_BUFFER (buf), NULL);
1035 GST_DEBUG ("decoding buffer %p", buf);
1037 data = GST_BUFFER_DATA (buf);
1038 size = GST_BUFFER_SIZE (buf);
1040 g_return_val_if_fail (data != NULL && size > 0, buf);
1042 if (gst_matroska_decode_data (context->encodings, &data, &size,
1043 GST_MATROSKA_TRACK_ENCODING_SCOPE_FRAME, FALSE)) {
1044 new_buf = gst_buffer_new ();
1045 GST_BUFFER_MALLOCDATA (new_buf) = (guint8 *) data;
1046 GST_BUFFER_DATA (new_buf) = (guint8 *) data;
1047 GST_BUFFER_SIZE (new_buf) = size;
1049 gst_buffer_unref (buf);
1054 GST_DEBUG ("decode data failed");
1055 gst_buffer_unref (buf);
1060 static GstFlowReturn
1061 gst_matroska_decode_content_encodings (GArray * encodings)
1065 if (encodings == NULL)
1068 for (i = 0; i < encodings->len; i++) {
1069 GstMatroskaTrackEncoding *enc =
1070 &g_array_index (encodings, GstMatroskaTrackEncoding, i);
1071 GstMatroskaTrackEncoding *enc2;
1072 guint8 *data = NULL;
1075 if ((enc->scope & GST_MATROSKA_TRACK_ENCODING_SCOPE_NEXT_CONTENT_ENCODING)
1079 /* Encryption not supported yet */
1081 return GST_FLOW_ERROR;
1083 if (i + 1 >= encodings->len)
1084 return GST_FLOW_ERROR;
1086 enc2 = &g_array_index (encodings, GstMatroskaTrackEncoding, i + 1);
1088 if (enc->comp_settings_length == 0)
1091 data = enc->comp_settings;
1092 size = enc->comp_settings_length;
1094 if (!gst_matroska_decompress_data (enc, &data, &size, enc->comp_algo))
1095 return GST_FLOW_ERROR;
1097 g_free (enc->comp_settings);
1099 enc->comp_settings = data;
1100 enc->comp_settings_length = size;
1106 static GstFlowReturn
1107 gst_matroska_demux_read_track_encodings (GstMatroskaDemux * demux,
1108 GstEbmlRead * ebml, GstMatroskaTrackContext * context)
1113 DEBUG_ELEMENT_START (demux, ebml, "ContentEncodings");
1115 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
1116 DEBUG_ELEMENT_STOP (demux, ebml, "ContentEncodings", ret);
1120 context->encodings =
1121 g_array_sized_new (FALSE, FALSE, sizeof (GstMatroskaTrackEncoding), 1);
1123 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1124 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1128 case GST_MATROSKA_ID_CONTENTENCODING:
1129 ret = gst_matroska_demux_read_track_encoding (demux, ebml, context);
1132 GST_WARNING_OBJECT (demux,
1133 "Unknown ContentEncodings subelement 0x%x - ignoring", id);
1134 ret = gst_ebml_read_skip (ebml);
1139 DEBUG_ELEMENT_STOP (demux, ebml, "ContentEncodings", ret);
1140 if (ret != GST_FLOW_OK && ret != GST_FLOW_UNEXPECTED)
1143 /* Sort encodings according to their order */
1144 g_array_sort (context->encodings,
1145 (GCompareFunc) gst_matroska_demux_encoding_cmp);
1147 return gst_matroska_decode_content_encodings (context->encodings);
1151 gst_matroska_demux_tracknumber_unique (GstMatroskaDemux * demux, guint64 num)
1155 g_assert (demux->src->len == demux->num_streams);
1156 for (i = 0; i < demux->src->len; i++) {
1157 GstMatroskaTrackContext *context = g_ptr_array_index (demux->src, i);
1159 if (context->num == num)
1166 static GstFlowReturn
1167 gst_matroska_demux_add_stream (GstMatroskaDemux * demux, GstEbmlRead * ebml)
1169 GstElementClass *klass = GST_ELEMENT_GET_CLASS (demux);
1170 GstMatroskaTrackContext *context;
1171 GstPadTemplate *templ = NULL;
1172 GstCaps *caps = NULL;
1173 gchar *padname = NULL;
1176 GstTagList *list = NULL;
1177 gchar *codec = NULL;
1179 DEBUG_ELEMENT_START (demux, ebml, "TrackEntry");
1181 /* start with the master */
1182 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
1183 DEBUG_ELEMENT_STOP (demux, ebml, "TrackEntry", ret);
1187 /* allocate generic... if we know the type, we'll g_renew()
1188 * with the precise type */
1189 context = g_new0 (GstMatroskaTrackContext, 1);
1190 g_ptr_array_add (demux->src, context);
1191 context->index = demux->num_streams;
1192 context->index_writer_id = -1;
1193 context->type = 0; /* no type yet */
1194 context->default_duration = 0;
1196 context->set_discont = TRUE;
1197 context->timecodescale = 1.0;
1199 GST_MATROSKA_TRACK_ENABLED | GST_MATROSKA_TRACK_DEFAULT |
1200 GST_MATROSKA_TRACK_LACING;
1201 context->last_flow = GST_FLOW_OK;
1202 context->to_offset = G_MAXINT64;
1203 demux->num_streams++;
1204 g_assert (demux->src->len == demux->num_streams);
1206 GST_DEBUG_OBJECT (demux, "Stream number %d", context->index);
1208 /* try reading the trackentry headers */
1209 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1210 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1214 /* track number (unique stream ID) */
1215 case GST_MATROSKA_ID_TRACKNUMBER:{
1218 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1222 GST_ERROR_OBJECT (demux, "Invalid TrackNumber 0");
1223 ret = GST_FLOW_ERROR;
1225 } else if (!gst_matroska_demux_tracknumber_unique (demux, num)) {
1226 GST_ERROR_OBJECT (demux, "TrackNumber %" G_GUINT64_FORMAT
1227 " is not unique", num);
1228 ret = GST_FLOW_ERROR;
1232 GST_DEBUG_OBJECT (demux, "TrackNumber: %" G_GUINT64_FORMAT, num);
1236 /* track UID (unique identifier) */
1237 case GST_MATROSKA_ID_TRACKUID:{
1240 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1244 GST_ERROR_OBJECT (demux, "Invalid TrackUID 0");
1245 ret = GST_FLOW_ERROR;
1249 GST_DEBUG_OBJECT (demux, "TrackUID: %" G_GUINT64_FORMAT, num);
1254 /* track type (video, audio, combined, subtitle, etc.) */
1255 case GST_MATROSKA_ID_TRACKTYPE:{
1258 if ((ret = gst_ebml_read_uint (ebml, &id, &track_type)) != GST_FLOW_OK) {
1262 if (context->type != 0 && context->type != track_type) {
1263 GST_WARNING_OBJECT (demux,
1264 "More than one tracktype defined in a TrackEntry - skipping");
1266 } else if (track_type < 1 || track_type > 254) {
1267 GST_WARNING_OBJECT (demux, "Invalid TrackType %" G_GUINT64_FORMAT,
1272 GST_DEBUG_OBJECT (demux, "TrackType: %" G_GUINT64_FORMAT, track_type);
1274 /* ok, so we're actually going to reallocate this thing */
1275 switch (track_type) {
1276 case GST_MATROSKA_TRACK_TYPE_VIDEO:
1277 gst_matroska_track_init_video_context (&context);
1279 case GST_MATROSKA_TRACK_TYPE_AUDIO:
1280 gst_matroska_track_init_audio_context (&context);
1282 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
1283 gst_matroska_track_init_subtitle_context (&context);
1285 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1286 case GST_MATROSKA_TRACK_TYPE_LOGO:
1287 case GST_MATROSKA_TRACK_TYPE_BUTTONS:
1288 case GST_MATROSKA_TRACK_TYPE_CONTROL:
1290 GST_WARNING_OBJECT (demux,
1291 "Unknown or unsupported TrackType %" G_GUINT64_FORMAT,
1296 g_ptr_array_index (demux->src, demux->num_streams - 1) = context;
1300 /* tracktype specific stuff for video */
1301 case GST_MATROSKA_ID_TRACKVIDEO:{
1302 GstMatroskaTrackVideoContext *videocontext;
1304 DEBUG_ELEMENT_START (demux, ebml, "TrackVideo");
1306 if (!gst_matroska_track_init_video_context (&context)) {
1307 GST_WARNING_OBJECT (demux,
1308 "TrackVideo element in non-video track - ignoring track");
1309 ret = GST_FLOW_ERROR;
1311 } else if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
1314 videocontext = (GstMatroskaTrackVideoContext *) context;
1315 g_ptr_array_index (demux->src, demux->num_streams - 1) = context;
1317 while (ret == GST_FLOW_OK &&
1318 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1319 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1323 /* Should be one level up but some broken muxers write it here. */
1324 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
1327 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1331 GST_WARNING_OBJECT (demux, "Invalid TrackDefaultDuration 0");
1335 GST_DEBUG_OBJECT (demux,
1336 "TrackDefaultDuration: %" G_GUINT64_FORMAT, num);
1337 context->default_duration = num;
1341 /* video framerate */
1342 /* NOTE: This one is here only for backward compatibility.
1343 * Use _TRACKDEFAULDURATION one level up. */
1344 case GST_MATROSKA_ID_VIDEOFRAMERATE:{
1347 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
1351 GST_WARNING_OBJECT (demux, "Invalid TrackVideoFPS %lf", num);
1355 GST_DEBUG_OBJECT (demux, "TrackVideoFrameRate: %lf", num);
1356 if (context->default_duration == 0)
1357 context->default_duration =
1358 gst_gdouble_to_guint64 ((gdouble) GST_SECOND * (1.0 / num));
1359 videocontext->default_fps = num;
1363 /* width of the size to display the video at */
1364 case GST_MATROSKA_ID_VIDEODISPLAYWIDTH:{
1367 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1371 GST_WARNING_OBJECT (demux, "Invalid TrackVideoDisplayWidth 0");
1375 GST_DEBUG_OBJECT (demux,
1376 "TrackVideoDisplayWidth: %" G_GUINT64_FORMAT, num);
1377 videocontext->display_width = num;
1381 /* height of the size to display the video at */
1382 case GST_MATROSKA_ID_VIDEODISPLAYHEIGHT:{
1385 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1389 GST_WARNING_OBJECT (demux, "Invalid TrackVideoDisplayHeight 0");
1393 GST_DEBUG_OBJECT (demux,
1394 "TrackVideoDisplayHeight: %" G_GUINT64_FORMAT, num);
1395 videocontext->display_height = num;
1399 /* width of the video in the file */
1400 case GST_MATROSKA_ID_VIDEOPIXELWIDTH:{
1403 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1407 GST_WARNING_OBJECT (demux, "Invalid TrackVideoPixelWidth 0");
1411 GST_DEBUG_OBJECT (demux,
1412 "TrackVideoPixelWidth: %" G_GUINT64_FORMAT, num);
1413 videocontext->pixel_width = num;
1417 /* height of the video in the file */
1418 case GST_MATROSKA_ID_VIDEOPIXELHEIGHT:{
1421 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1425 GST_WARNING_OBJECT (demux, "Invalid TrackVideoPixelHeight 0");
1429 GST_DEBUG_OBJECT (demux,
1430 "TrackVideoPixelHeight: %" G_GUINT64_FORMAT, num);
1431 videocontext->pixel_height = num;
1435 /* whether the video is interlaced */
1436 case GST_MATROSKA_ID_VIDEOFLAGINTERLACED:{
1439 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1443 context->flags |= GST_MATROSKA_VIDEOTRACK_INTERLACED;
1445 context->flags &= ~GST_MATROSKA_VIDEOTRACK_INTERLACED;
1446 GST_DEBUG_OBJECT (demux, "TrackVideoInterlaced: %d",
1447 (context->flags & GST_MATROSKA_VIDEOTRACK_INTERLACED) ? 1 :
1452 /* aspect ratio behaviour */
1453 case GST_MATROSKA_ID_VIDEOASPECTRATIOTYPE:{
1456 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1459 if (num != GST_MATROSKA_ASPECT_RATIO_MODE_FREE &&
1460 num != GST_MATROSKA_ASPECT_RATIO_MODE_KEEP &&
1461 num != GST_MATROSKA_ASPECT_RATIO_MODE_FIXED) {
1462 GST_WARNING_OBJECT (demux,
1463 "Unknown TrackVideoAspectRatioType 0x%x", (guint) num);
1466 GST_DEBUG_OBJECT (demux,
1467 "TrackVideoAspectRatioType: %" G_GUINT64_FORMAT, num);
1468 videocontext->asr_mode = num;
1472 /* colourspace (only matters for raw video) fourcc */
1473 case GST_MATROSKA_ID_VIDEOCOLOURSPACE:{
1478 gst_ebml_read_binary (ebml, &id, &data,
1479 &datalen)) != GST_FLOW_OK)
1484 GST_WARNING_OBJECT (demux,
1485 "Invalid TrackVideoColourSpace length %" G_GUINT64_FORMAT,
1490 memcpy (&videocontext->fourcc, data, 4);
1491 GST_DEBUG_OBJECT (demux,
1492 "TrackVideoColourSpace: %" GST_FOURCC_FORMAT,
1493 GST_FOURCC_ARGS (videocontext->fourcc));
1499 GST_WARNING_OBJECT (demux,
1500 "Unknown TrackVideo subelement 0x%x - ignoring", id);
1502 case GST_MATROSKA_ID_VIDEOSTEREOMODE:
1503 case GST_MATROSKA_ID_VIDEODISPLAYUNIT:
1504 case GST_MATROSKA_ID_VIDEOPIXELCROPBOTTOM:
1505 case GST_MATROSKA_ID_VIDEOPIXELCROPTOP:
1506 case GST_MATROSKA_ID_VIDEOPIXELCROPLEFT:
1507 case GST_MATROSKA_ID_VIDEOPIXELCROPRIGHT:
1508 case GST_MATROSKA_ID_VIDEOGAMMAVALUE:
1509 ret = gst_ebml_read_skip (ebml);
1514 DEBUG_ELEMENT_STOP (demux, ebml, "TrackVideo", ret);
1518 /* tracktype specific stuff for audio */
1519 case GST_MATROSKA_ID_TRACKAUDIO:{
1520 GstMatroskaTrackAudioContext *audiocontext;
1522 DEBUG_ELEMENT_START (demux, ebml, "TrackAudio");
1524 if (!gst_matroska_track_init_audio_context (&context)) {
1525 GST_WARNING_OBJECT (demux,
1526 "TrackAudio element in non-audio track - ignoring track");
1527 ret = GST_FLOW_ERROR;
1531 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
1534 audiocontext = (GstMatroskaTrackAudioContext *) context;
1535 g_ptr_array_index (demux->src, demux->num_streams - 1) = context;
1537 while (ret == GST_FLOW_OK &&
1538 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1539 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1544 case GST_MATROSKA_ID_AUDIOSAMPLINGFREQ:{
1547 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
1552 GST_WARNING_OBJECT (demux,
1553 "Invalid TrackAudioSamplingFrequency %lf", num);
1557 GST_DEBUG_OBJECT (demux, "TrackAudioSamplingFrequency: %lf", num);
1558 audiocontext->samplerate = num;
1563 case GST_MATROSKA_ID_AUDIOBITDEPTH:{
1566 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1570 GST_WARNING_OBJECT (demux, "Invalid TrackAudioBitDepth 0");
1574 GST_DEBUG_OBJECT (demux, "TrackAudioBitDepth: %" G_GUINT64_FORMAT,
1576 audiocontext->bitdepth = num;
1581 case GST_MATROSKA_ID_AUDIOCHANNELS:{
1584 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1588 GST_WARNING_OBJECT (demux, "Invalid TrackAudioChannels 0");
1592 GST_DEBUG_OBJECT (demux, "TrackAudioChannels: %" G_GUINT64_FORMAT,
1594 audiocontext->channels = num;
1599 GST_WARNING_OBJECT (demux,
1600 "Unknown TrackAudio subelement 0x%x - ignoring", id);
1602 case GST_MATROSKA_ID_AUDIOCHANNELPOSITIONS:
1603 case GST_MATROSKA_ID_AUDIOOUTPUTSAMPLINGFREQ:
1604 ret = gst_ebml_read_skip (ebml);
1609 DEBUG_ELEMENT_STOP (demux, ebml, "TrackAudio", ret);
1614 /* codec identifier */
1615 case GST_MATROSKA_ID_CODECID:{
1618 if ((ret = gst_ebml_read_ascii (ebml, &id, &text)) != GST_FLOW_OK)
1621 GST_DEBUG_OBJECT (demux, "CodecID: %s", GST_STR_NULL (text));
1622 context->codec_id = text;
1626 /* codec private data */
1627 case GST_MATROSKA_ID_CODECPRIVATE:{
1632 gst_ebml_read_binary (ebml, &id, &data, &size)) != GST_FLOW_OK)
1635 context->codec_priv = data;
1636 context->codec_priv_size = size;
1638 GST_DEBUG_OBJECT (demux, "CodecPrivate of size %" G_GUINT64_FORMAT,
1643 /* name of the codec */
1644 case GST_MATROSKA_ID_CODECNAME:{
1647 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1650 GST_DEBUG_OBJECT (demux, "CodecName: %s", GST_STR_NULL (text));
1651 context->codec_name = text;
1655 /* name of this track */
1656 case GST_MATROSKA_ID_TRACKNAME:{
1659 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1662 context->name = text;
1663 GST_DEBUG_OBJECT (demux, "TrackName: %s", GST_STR_NULL (text));
1667 /* language (matters for audio/subtitles, mostly) */
1668 case GST_MATROSKA_ID_TRACKLANGUAGE:{
1671 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1675 context->language = text;
1678 if (strlen (context->language) >= 4 && context->language[3] == '-')
1679 context->language[3] = '\0';
1681 GST_DEBUG_OBJECT (demux, "TrackLanguage: %s",
1682 GST_STR_NULL (context->language));
1686 /* whether this is actually used */
1687 case GST_MATROSKA_ID_TRACKFLAGENABLED:{
1690 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1694 context->flags |= GST_MATROSKA_TRACK_ENABLED;
1696 context->flags &= ~GST_MATROSKA_TRACK_ENABLED;
1698 GST_DEBUG_OBJECT (demux, "TrackEnabled: %d",
1699 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
1703 /* whether it's the default for this track type */
1704 case GST_MATROSKA_ID_TRACKFLAGDEFAULT:{
1707 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1711 context->flags |= GST_MATROSKA_TRACK_DEFAULT;
1713 context->flags &= ~GST_MATROSKA_TRACK_DEFAULT;
1715 GST_DEBUG_OBJECT (demux, "TrackDefault: %d",
1716 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
1720 /* whether the track must be used during playback */
1721 case GST_MATROSKA_ID_TRACKFLAGFORCED:{
1724 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1728 context->flags |= GST_MATROSKA_TRACK_FORCED;
1730 context->flags &= ~GST_MATROSKA_TRACK_FORCED;
1732 GST_DEBUG_OBJECT (demux, "TrackForced: %d",
1733 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
1737 /* lacing (like MPEG, where blocks don't end/start on frame
1739 case GST_MATROSKA_ID_TRACKFLAGLACING:{
1742 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1746 context->flags |= GST_MATROSKA_TRACK_LACING;
1748 context->flags &= ~GST_MATROSKA_TRACK_LACING;
1750 GST_DEBUG_OBJECT (demux, "TrackLacing: %d",
1751 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
1755 /* default length (in time) of one data block in this track */
1756 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
1759 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1764 GST_WARNING_OBJECT (demux, "Invalid TrackDefaultDuration 0");
1768 GST_DEBUG_OBJECT (demux, "TrackDefaultDuration: %" G_GUINT64_FORMAT,
1770 context->default_duration = num;
1774 case GST_MATROSKA_ID_CONTENTENCODINGS:{
1775 ret = gst_matroska_demux_read_track_encodings (demux, ebml, context);
1779 case GST_MATROSKA_ID_TRACKTIMECODESCALE:{
1782 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
1786 GST_WARNING_OBJECT (demux, "Invalid TrackTimeCodeScale %lf", num);
1790 GST_DEBUG_OBJECT (demux, "TrackTimeCodeScale: %lf", num);
1791 context->timecodescale = num;
1796 GST_WARNING ("Unknown TrackEntry subelement 0x%x - ignoring", id);
1799 /* we ignore these because they're nothing useful (i.e. crap)
1800 * or simply not implemented yet. */
1801 case GST_MATROSKA_ID_TRACKMINCACHE:
1802 case GST_MATROSKA_ID_TRACKMAXCACHE:
1803 case GST_MATROSKA_ID_MAXBLOCKADDITIONID:
1804 case GST_MATROSKA_ID_TRACKATTACHMENTLINK:
1805 case GST_MATROSKA_ID_TRACKOVERLAY:
1806 case GST_MATROSKA_ID_TRACKTRANSLATE:
1807 case GST_MATROSKA_ID_TRACKOFFSET:
1808 case GST_MATROSKA_ID_CODECSETTINGS:
1809 case GST_MATROSKA_ID_CODECINFOURL:
1810 case GST_MATROSKA_ID_CODECDOWNLOADURL:
1811 case GST_MATROSKA_ID_CODECDECODEALL:
1812 ret = gst_ebml_read_skip (ebml);
1817 DEBUG_ELEMENT_STOP (demux, ebml, "TrackEntry", ret);
1819 /* Decode codec private data if necessary */
1820 if (context->encodings && context->encodings->len > 0 && context->codec_priv
1821 && context->codec_priv_size > 0) {
1822 if (!gst_matroska_decode_data (context->encodings,
1823 &context->codec_priv, &context->codec_priv_size,
1824 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
1825 GST_WARNING_OBJECT (demux, "Decoding codec private data failed");
1826 ret = GST_FLOW_ERROR;
1830 if (context->type == 0 || context->codec_id == NULL || (ret != GST_FLOW_OK
1831 && ret != GST_FLOW_UNEXPECTED)) {
1832 if (ret == GST_FLOW_OK || ret == GST_FLOW_UNEXPECTED)
1833 GST_WARNING_OBJECT (ebml, "Unknown stream/codec in track entry header");
1835 demux->num_streams--;
1836 g_ptr_array_remove_index (demux->src, demux->num_streams);
1837 g_assert (demux->src->len == demux->num_streams);
1839 gst_matroska_track_free (context);
1845 /* now create the GStreamer connectivity */
1846 switch (context->type) {
1847 case GST_MATROSKA_TRACK_TYPE_VIDEO:{
1848 GstMatroskaTrackVideoContext *videocontext =
1849 (GstMatroskaTrackVideoContext *) context;
1851 padname = g_strdup_printf ("video_%02d", demux->num_v_streams++);
1852 templ = gst_element_class_get_pad_template (klass, "video_%02d");
1853 caps = gst_matroska_demux_video_caps (videocontext,
1855 (guint8 *) context->codec_priv, context->codec_priv_size, &codec);
1857 list = gst_tag_list_new ();
1858 gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
1859 GST_TAG_VIDEO_CODEC, codec, NULL);
1865 case GST_MATROSKA_TRACK_TYPE_AUDIO:{
1866 GstMatroskaTrackAudioContext *audiocontext =
1867 (GstMatroskaTrackAudioContext *) context;
1869 padname = g_strdup_printf ("audio_%02d", demux->num_a_streams++);
1870 templ = gst_element_class_get_pad_template (klass, "audio_%02d");
1871 caps = gst_matroska_demux_audio_caps (audiocontext,
1873 context->codec_priv, context->codec_priv_size, &codec);
1875 list = gst_tag_list_new ();
1876 gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
1877 GST_TAG_AUDIO_CODEC, codec, NULL);
1883 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:{
1884 GstMatroskaTrackSubtitleContext *subtitlecontext =
1885 (GstMatroskaTrackSubtitleContext *) context;
1887 padname = g_strdup_printf ("subtitle_%02d", demux->num_t_streams++);
1888 templ = gst_element_class_get_pad_template (klass, "subtitle_%02d");
1889 caps = gst_matroska_demux_subtitle_caps (subtitlecontext,
1890 context->codec_id, context->codec_priv, context->codec_priv_size);
1894 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1895 case GST_MATROSKA_TRACK_TYPE_LOGO:
1896 case GST_MATROSKA_TRACK_TYPE_BUTTONS:
1897 case GST_MATROSKA_TRACK_TYPE_CONTROL:
1899 /* we should already have quit by now */
1900 g_assert_not_reached ();
1903 if ((context->language == NULL || *context->language == '\0') &&
1904 (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO ||
1905 context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
1906 GST_LOG ("stream %d: language=eng (assuming default)", context->index);
1907 context->language = g_strdup ("eng");
1910 if (context->language) {
1914 list = gst_tag_list_new ();
1916 /* Matroska contains ISO 639-2B codes, we want ISO 639-1 */
1917 lang = gst_tag_get_language_code (context->language);
1918 gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
1919 GST_TAG_LANGUAGE_CODE, (lang) ? lang : context->language, NULL);
1923 GST_WARNING_OBJECT (demux, "could not determine caps for stream with "
1924 "codec_id='%s'", context->codec_id);
1925 switch (context->type) {
1926 case GST_MATROSKA_TRACK_TYPE_VIDEO:
1927 caps = gst_caps_new_simple ("video/x-unknown", NULL);
1929 case GST_MATROSKA_TRACK_TYPE_AUDIO:
1930 caps = gst_caps_new_simple ("audio/x-unknown", NULL);
1932 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
1933 caps = gst_caps_new_simple ("application/x-subtitle-unknown", NULL);
1935 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1937 caps = gst_caps_new_simple ("application/x-matroska-unknown", NULL);
1940 gst_caps_set_simple (caps, "codec-id", G_TYPE_STRING, context->codec_id,
1944 /* the pad in here */
1945 context->pad = gst_pad_new_from_template (templ, padname);
1946 context->caps = caps;
1948 gst_pad_set_event_function (context->pad,
1949 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_event));
1950 gst_pad_set_query_type_function (context->pad,
1951 GST_DEBUG_FUNCPTR (gst_matroska_demux_get_src_query_types));
1952 gst_pad_set_query_function (context->pad,
1953 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_query));
1955 GST_INFO_OBJECT (demux, "Adding pad '%s' with caps %" GST_PTR_FORMAT,
1958 context->pending_tags = list;
1960 gst_pad_set_element_private (context->pad, context);
1962 gst_pad_use_fixed_caps (context->pad);
1963 gst_pad_set_caps (context->pad, context->caps);
1964 gst_pad_set_active (context->pad, TRUE);
1965 gst_element_add_pad (GST_ELEMENT (demux), context->pad);
1973 static const GstQueryType *
1974 gst_matroska_demux_get_src_query_types (GstPad * pad)
1976 static const GstQueryType query_types[] = {
1987 gst_matroska_demux_query (GstMatroskaDemux * demux, GstPad * pad,
1990 gboolean res = FALSE;
1991 GstMatroskaTrackContext *context = NULL;
1994 context = gst_pad_get_element_private (pad);
1997 switch (GST_QUERY_TYPE (query)) {
1998 case GST_QUERY_POSITION:
2002 gst_query_parse_position (query, &format, NULL);
2004 if (format == GST_FORMAT_TIME) {
2005 GST_OBJECT_LOCK (demux);
2007 gst_query_set_position (query, GST_FORMAT_TIME, context->pos);
2009 gst_query_set_position (query, GST_FORMAT_TIME,
2010 demux->segment.last_stop);
2011 GST_OBJECT_UNLOCK (demux);
2012 } else if (format == GST_FORMAT_DEFAULT && context
2013 && context->default_duration) {
2014 GST_OBJECT_LOCK (demux);
2015 gst_query_set_position (query, GST_FORMAT_DEFAULT,
2016 context->pos / context->default_duration);
2017 GST_OBJECT_UNLOCK (demux);
2019 GST_DEBUG_OBJECT (demux,
2020 "only position query in TIME and DEFAULT format is supported");
2026 case GST_QUERY_DURATION:
2030 gst_query_parse_duration (query, &format, NULL);
2032 if (format == GST_FORMAT_TIME) {
2033 GST_OBJECT_LOCK (demux);
2034 gst_query_set_duration (query, GST_FORMAT_TIME,
2035 demux->segment.duration);
2036 GST_OBJECT_UNLOCK (demux);
2037 } else if (format == GST_FORMAT_DEFAULT && context
2038 && context->default_duration) {
2039 GST_OBJECT_LOCK (demux);
2040 gst_query_set_duration (query, GST_FORMAT_DEFAULT,
2041 demux->segment.duration / context->default_duration);
2042 GST_OBJECT_UNLOCK (demux);
2044 GST_DEBUG_OBJECT (demux,
2045 "only duration query in TIME and DEFAULT format is supported");
2052 case GST_QUERY_SEEKING:
2056 gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
2057 if (fmt == GST_FORMAT_TIME) {
2060 if (demux->streaming) {
2061 /* assuming we'll be able to get an index ... */
2062 seekable = demux->seekable;
2064 seekable = !!demux->index;
2067 gst_query_set_seeking (query, GST_FORMAT_TIME, seekable,
2068 0, demux->segment.duration);
2074 res = gst_pad_query_default (pad, query);
2082 gst_matroska_demux_element_query (GstElement * element, GstQuery * query)
2084 return gst_matroska_demux_query (GST_MATROSKA_DEMUX (element), NULL, query);
2088 gst_matroska_demux_handle_src_query (GstPad * pad, GstQuery * query)
2091 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (gst_pad_get_parent (pad));
2093 ret = gst_matroska_demux_query (demux, pad, query);
2095 gst_object_unref (demux);
2101 gst_matroska_index_seek_find (GstMatroskaIndex * i1, GstClockTime * time,
2104 if (i1->time < *time)
2106 else if (i1->time > *time)
2112 static GstMatroskaIndex *
2113 gst_matroskademux_do_index_seek (GstMatroskaDemux * demux,
2114 GstMatroskaTrackContext * track, gint64 seek_pos, GArray ** _index,
2115 gint * _entry_index)
2117 GstMatroskaIndex *entry = NULL;
2120 if (!demux->index || !demux->index->len)
2123 /* find entry just before or at the requested position */
2124 if (track && track->index_table)
2125 index = track->index_table;
2127 index = demux->index;
2130 gst_util_array_binary_search (index->data, index->len,
2131 sizeof (GstMatroskaIndex),
2132 (GCompareDataFunc) gst_matroska_index_seek_find, GST_SEARCH_MODE_BEFORE,
2136 entry = &g_array_index (index, GstMatroskaIndex, 0);
2141 *_entry_index = entry - (GstMatroskaIndex *) index->data;
2146 /* takes ownership of taglist */
2148 gst_matroska_demux_found_global_tag (GstMatroskaDemux * demux,
2149 GstTagList * taglist)
2151 if (demux->global_tags) {
2152 /* nothing sent yet, add to cache */
2153 gst_tag_list_insert (demux->global_tags, taglist, GST_TAG_MERGE_APPEND);
2154 gst_tag_list_free (taglist);
2156 /* hm, already sent, no need to cache and wait anymore */
2157 GST_DEBUG_OBJECT (demux, "Sending late global tags %" GST_PTR_FORMAT,
2159 gst_element_found_tags (GST_ELEMENT (demux), taglist);
2163 /* returns FALSE if there are no pads to deliver event to,
2164 * otherwise TRUE (whatever the outcome of event sending),
2165 * takes ownership of the passed event! */
2167 gst_matroska_demux_send_event (GstMatroskaDemux * demux, GstEvent * event)
2169 gboolean is_newsegment;
2170 gboolean ret = FALSE;
2173 g_return_val_if_fail (event != NULL, FALSE);
2175 GST_DEBUG_OBJECT (demux, "Sending event of type %s to all source pads",
2176 GST_EVENT_TYPE_NAME (event));
2178 is_newsegment = (GST_EVENT_TYPE (event) == GST_EVENT_NEWSEGMENT);
2180 g_assert (demux->src->len == demux->num_streams);
2181 for (i = 0; i < demux->src->len; i++) {
2182 GstMatroskaTrackContext *stream;
2184 stream = g_ptr_array_index (demux->src, i);
2185 gst_event_ref (event);
2186 gst_pad_push_event (stream->pad, event);
2189 /* FIXME: send global tags before stream tags */
2190 if (G_UNLIKELY (is_newsegment && stream->pending_tags != NULL)) {
2191 GST_DEBUG_OBJECT (demux, "Sending pending_tags %p for pad %s:%s : %"
2192 GST_PTR_FORMAT, stream->pending_tags,
2193 GST_DEBUG_PAD_NAME (stream->pad), stream->pending_tags);
2194 gst_element_found_tags_for_pad (GST_ELEMENT (demux), stream->pad,
2195 stream->pending_tags);
2196 stream->pending_tags = NULL;
2200 if (G_UNLIKELY (is_newsegment && demux->global_tags != NULL)) {
2201 gst_tag_list_add (demux->global_tags, GST_TAG_MERGE_REPLACE,
2202 GST_TAG_CONTAINER_FORMAT, "Matroska", NULL);
2203 GST_DEBUG_OBJECT (demux, "Sending global_tags %p : %" GST_PTR_FORMAT,
2204 demux->global_tags, demux->global_tags);
2205 gst_element_found_tags (GST_ELEMENT (demux), demux->global_tags);
2206 demux->global_tags = NULL;
2209 gst_event_unref (event);
2214 gst_matroska_demux_element_send_event (GstElement * element, GstEvent * event)
2216 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
2219 g_return_val_if_fail (event != NULL, FALSE);
2221 if (GST_EVENT_TYPE (event) == GST_EVENT_SEEK) {
2222 res = gst_matroska_demux_handle_seek_event (demux, NULL, event);
2224 GST_WARNING_OBJECT (demux, "Unhandled event of type %s",
2225 GST_EVENT_TYPE_NAME (event));
2228 gst_event_unref (event);
2232 /* determine track to seek in */
2233 static GstMatroskaTrackContext *
2234 gst_matroska_demux_get_seek_track (GstMatroskaDemux * demux,
2235 GstMatroskaTrackContext * track)
2239 if (track && track->type == GST_MATROSKA_TRACK_TYPE_VIDEO)
2242 for (i = 0; i < demux->src->len; i++) {
2243 GstMatroskaTrackContext *stream;
2245 stream = g_ptr_array_index (demux->src, i);
2246 if (stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO && stream->index_table)
2254 gst_matroska_demux_reset_streams (GstMatroskaDemux * demux, GstClockTime time,
2259 GST_DEBUG_OBJECT (demux, "resetting stream state");
2261 g_assert (demux->src->len == demux->num_streams);
2262 for (i = 0; i < demux->src->len; i++) {
2263 GstMatroskaTrackContext *context = g_ptr_array_index (demux->src, i);
2264 context->pos = time;
2265 context->set_discont = TRUE;
2266 context->eos = FALSE;
2267 context->from_time = GST_CLOCK_TIME_NONE;
2269 context->last_flow = GST_FLOW_OK;
2270 if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
2271 GstMatroskaTrackVideoContext *videocontext =
2272 (GstMatroskaTrackVideoContext *) context;
2273 /* demux object lock held by caller */
2274 videocontext->earliest_time = GST_CLOCK_TIME_NONE;
2280 gst_matroska_demux_move_to_entry (GstMatroskaDemux * demux,
2281 GstMatroskaIndex * entry, gboolean reset)
2285 GST_OBJECT_LOCK (demux);
2287 /* seek (relative to matroska segment) */
2288 /* position might be invalid; will error when streaming resumes ... */
2289 demux->offset = entry->pos + demux->ebml_segment_start;
2291 GST_DEBUG_OBJECT (demux, "Seeked to offset %" G_GUINT64_FORMAT ", block %d, "
2292 "time %" GST_TIME_FORMAT, entry->pos + demux->ebml_segment_start,
2293 entry->block, GST_TIME_ARGS (entry->time));
2295 /* update the time */
2296 gst_matroska_demux_reset_streams (demux, entry->time, TRUE);
2297 demux->segment.last_stop = entry->time;
2298 demux->seek_block = entry->block;
2299 demux->seek_first = TRUE;
2300 demux->last_stop_end = GST_CLOCK_TIME_NONE;
2302 for (i = 0; i < demux->src->len; i++) {
2303 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->src, i);
2306 stream->to_offset = G_MAXINT64;
2308 if (stream->from_offset != -1)
2309 stream->to_offset = stream->from_offset;
2311 stream->from_offset = -1;
2314 GST_OBJECT_UNLOCK (demux);
2320 gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
2321 GstPad * pad, GstEvent * event)
2323 GstMatroskaIndex *entry = NULL;
2325 GstSeekType cur_type, stop_type;
2327 gboolean flush, keyunit;
2330 GstMatroskaTrackContext *track = NULL;
2331 GstSegment seeksegment = { 0, };
2335 track = gst_pad_get_element_private (pad);
2337 track = gst_matroska_demux_get_seek_track (demux, track);
2339 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
2342 /* we can only seek on time */
2343 if (format != GST_FORMAT_TIME) {
2344 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
2348 /* copy segment, we need this because we still need the old
2349 * segment when we close the current segment. */
2350 memcpy (&seeksegment, &demux->segment, sizeof (GstSegment));
2353 GST_DEBUG_OBJECT (demux, "configuring seek");
2354 gst_segment_set_seek (&seeksegment, rate, format, flags,
2355 cur_type, cur, stop_type, stop, &update);
2358 GST_DEBUG_OBJECT (demux, "New segment %" GST_SEGMENT_FORMAT, &seeksegment);
2360 /* check sanity before we start flushing and all that */
2361 GST_OBJECT_LOCK (demux);
2362 if ((entry = gst_matroskademux_do_index_seek (demux, track,
2363 seeksegment.last_stop, &demux->seek_index, &demux->seek_entry)) ==
2365 GST_DEBUG_OBJECT (demux, "No matching seek entry in index");
2366 GST_OBJECT_UNLOCK (demux);
2369 GST_DEBUG_OBJECT (demux, "Seek position looks sane");
2370 GST_OBJECT_UNLOCK (demux);
2372 if (demux->streaming) {
2373 /* need to seek to cluster start to pick up cluster time */
2374 /* upstream takes care of flushing and all that
2375 * ... and newsegment event handling takes care of the rest */
2376 return perform_seek_to_offset (demux,
2377 entry->pos + demux->ebml_segment_start);
2380 flush = !!(flags & GST_SEEK_FLAG_FLUSH);
2381 keyunit = !!(flags & GST_SEEK_FLAG_KEY_UNIT);
2384 GST_DEBUG_OBJECT (demux, "Starting flush");
2385 gst_pad_push_event (demux->sinkpad, gst_event_new_flush_start ());
2386 gst_matroska_demux_send_event (demux, gst_event_new_flush_start ());
2388 GST_DEBUG_OBJECT (demux, "Non-flushing seek, pausing task");
2389 gst_pad_pause_task (demux->sinkpad);
2392 /* now grab the stream lock so that streaming cannot continue, for
2393 * non flushing seeks when the element is in PAUSED this could block
2395 GST_DEBUG_OBJECT (demux, "Waiting for streaming to stop");
2396 GST_PAD_STREAM_LOCK (demux->sinkpad);
2399 GST_DEBUG_OBJECT (demux, "seek to key unit, adjusting segment start to %"
2400 GST_TIME_FORMAT, GST_TIME_ARGS (entry->time));
2401 seeksegment.start = entry->time;
2402 seeksegment.last_stop = entry->time;
2403 seeksegment.time = entry->time;
2407 GST_DEBUG_OBJECT (demux, "Stopping flush");
2408 gst_pad_push_event (demux->sinkpad, gst_event_new_flush_stop ());
2409 gst_matroska_demux_send_event (demux, gst_event_new_flush_stop ());
2410 } else if (demux->segment_running) {
2411 GST_DEBUG_OBJECT (demux, "Closing currently running segment");
2413 GST_OBJECT_LOCK (demux);
2414 if (demux->close_segment)
2415 gst_event_unref (demux->close_segment);
2417 demux->close_segment = gst_event_new_new_segment (TRUE,
2418 demux->segment.rate, GST_FORMAT_TIME, demux->segment.start,
2419 demux->segment.last_stop, demux->segment.time);
2420 GST_OBJECT_UNLOCK (demux);
2423 GST_OBJECT_LOCK (demux);
2424 /* now update the real segment info */
2425 GST_DEBUG_OBJECT (demux, "Committing new seek segment");
2426 memcpy (&demux->segment, &seeksegment, sizeof (GstSegment));
2427 GST_OBJECT_UNLOCK (demux);
2429 /* update some (segment) state */
2430 if (!gst_matroska_demux_move_to_entry (demux, entry, TRUE))
2433 /* notify start of new segment */
2434 if (demux->segment.flags & GST_SEEK_FLAG_SEGMENT) {
2437 msg = gst_message_new_segment_start (GST_OBJECT (demux),
2438 GST_FORMAT_TIME, demux->segment.start);
2439 gst_element_post_message (GST_ELEMENT (demux), msg);
2442 GST_OBJECT_LOCK (demux);
2443 if (demux->new_segment)
2444 gst_event_unref (demux->new_segment);
2445 demux->new_segment = gst_event_new_new_segment_full (FALSE,
2446 demux->segment.rate, demux->segment.applied_rate, demux->segment.format,
2447 demux->segment.start, demux->segment.stop, demux->segment.time);
2448 GST_OBJECT_UNLOCK (demux);
2450 /* restart our task since it might have been stopped when we did the
2452 demux->segment_running = TRUE;
2453 gst_pad_start_task (demux->sinkpad, (GstTaskFunction) gst_matroska_demux_loop,
2456 /* streaming can continue now */
2457 GST_PAD_STREAM_UNLOCK (demux->sinkpad);
2463 GST_OBJECT_UNLOCK (demux);
2464 GST_PAD_STREAM_UNLOCK (demux->sinkpad);
2465 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Got a seek error"));
2471 * Handle whether we can perform the seek event or if we have to let the chain
2472 * function handle seeks to build the seek indexes first.
2475 gst_matroska_demux_handle_seek_push (GstMatroskaDemux * demux, GstPad * pad,
2479 GstSeekType cur_type, stop_type;
2484 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
2489 /* we can only seek on time */
2490 if (format != GST_FORMAT_TIME) {
2491 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
2495 if (stop_type != GST_SEEK_TYPE_NONE && stop != GST_CLOCK_TIME_NONE) {
2496 GST_DEBUG_OBJECT (demux, "Seek end-time not supported in streaming mode");
2500 if (!(flags & GST_SEEK_FLAG_FLUSH)) {
2501 GST_DEBUG_OBJECT (demux,
2502 "Non-flushing seek not supported in streaming mode");
2506 if (flags & GST_SEEK_FLAG_SEGMENT) {
2507 GST_DEBUG_OBJECT (demux, "Segment seek not supported in streaming mode");
2511 /* check for having parsed index already */
2512 if (!demux->index_parsed) {
2513 gboolean building_index;
2516 if (!demux->index_offset) {
2517 GST_DEBUG_OBJECT (demux, "no index (location); no seek in push mode");
2521 GST_OBJECT_LOCK (demux);
2522 /* handle the seek event in the chain function */
2523 demux->state = GST_MATROSKA_DEMUX_STATE_SEEK;
2524 /* no more seek can be issued until state reset to _DATA */
2526 /* copy the event */
2527 if (demux->seek_event)
2528 gst_event_unref (demux->seek_event);
2529 demux->seek_event = gst_event_ref (event);
2531 /* set the building_index flag so that only one thread can setup the
2532 * structures for index seeking. */
2533 building_index = demux->building_index;
2534 if (!building_index) {
2535 demux->building_index = TRUE;
2536 offset = demux->index_offset;
2538 GST_OBJECT_UNLOCK (demux);
2540 if (!building_index) {
2541 /* seek to the first subindex or legacy index */
2542 GST_INFO_OBJECT (demux, "Seeking to Cues at %" G_GUINT64_FORMAT, offset);
2543 return perform_seek_to_offset (demux, offset);
2546 /* well, we are handling it already */
2550 /* delegate to tweaked regular seek */
2551 return gst_matroska_demux_handle_seek_event (demux, pad, event);
2555 gst_matroska_demux_handle_src_event (GstPad * pad, GstEvent * event)
2557 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (gst_pad_get_parent (pad));
2558 gboolean res = TRUE;
2560 switch (GST_EVENT_TYPE (event)) {
2561 case GST_EVENT_SEEK:
2562 /* no seeking until we are (safely) ready */
2563 if (demux->state != GST_MATROSKA_DEMUX_STATE_DATA) {
2564 GST_DEBUG_OBJECT (demux, "not ready for seeking yet");
2567 if (!demux->streaming)
2568 res = gst_matroska_demux_handle_seek_event (demux, pad, event);
2570 res = gst_matroska_demux_handle_seek_push (demux, pad, event);
2571 gst_event_unref (event);
2576 GstMatroskaTrackContext *context = gst_pad_get_element_private (pad);
2577 if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
2578 GstMatroskaTrackVideoContext *videocontext =
2579 (GstMatroskaTrackVideoContext *) context;
2581 GstClockTimeDiff diff;
2582 GstClockTime timestamp;
2584 gst_event_parse_qos (event, &proportion, &diff, ×tamp);
2586 GST_OBJECT_LOCK (demux);
2587 videocontext->earliest_time = timestamp + diff;
2588 GST_OBJECT_UNLOCK (demux);
2591 gst_event_unref (event);
2595 /* events we don't need to handle */
2596 case GST_EVENT_NAVIGATION:
2597 gst_event_unref (event);
2601 case GST_EVENT_LATENCY:
2603 res = gst_pad_push_event (demux->sinkpad, event);
2607 gst_object_unref (demux);
2612 static GstFlowReturn
2613 gst_matroska_demux_seek_to_previous_keyframe (GstMatroskaDemux * demux)
2615 GstFlowReturn ret = GST_FLOW_UNEXPECTED;
2616 gboolean done = TRUE;
2619 g_return_val_if_fail (demux->seek_index, GST_FLOW_UNEXPECTED);
2620 g_return_val_if_fail (demux->seek_entry < demux->seek_index->len,
2621 GST_FLOW_UNEXPECTED);
2623 GST_DEBUG_OBJECT (demux, "locating previous keyframe");
2625 if (!demux->seek_entry) {
2626 GST_DEBUG_OBJECT (demux, "no earlier index entry");
2630 for (i = 0; i < demux->src->len; i++) {
2631 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->src, i);
2633 GST_DEBUG_OBJECT (demux, "segment start %" GST_TIME_FORMAT
2634 ", stream %d at %" GST_TIME_FORMAT,
2635 GST_TIME_ARGS (demux->segment.start), stream->index,
2636 GST_TIME_ARGS (stream->from_time));
2637 if (GST_CLOCK_TIME_IS_VALID (stream->from_time)) {
2638 if (stream->from_time > demux->segment.start) {
2639 GST_DEBUG_OBJECT (demux, "stream %d not finished yet", stream->index);
2643 /* nothing pushed for this stream;
2644 * likely seek entry did not start at keyframe, so all was skipped.
2645 * So we need an earlier entry */
2651 GstMatroskaIndex *entry;
2653 entry = &g_array_index (demux->seek_index, GstMatroskaIndex,
2654 --demux->seek_entry);
2655 if (!gst_matroska_demux_move_to_entry (demux, entry, FALSE))
2665 /* skip unknown or alike element */
2666 static GstFlowReturn
2667 gst_matroska_demux_parse_skip (GstMatroskaDemux * demux, GstEbmlRead * ebml,
2668 const gchar * parent_name, guint id)
2670 if (id == GST_EBML_ID_VOID) {
2671 GST_DEBUG_OBJECT (demux, "Skipping EBML Void element");
2672 } else if (id == GST_EBML_ID_CRC32) {
2673 GST_DEBUG_OBJECT (demux, "Skipping EBML CRC32 element");
2675 GST_WARNING_OBJECT (demux,
2676 "Unknown %s subelement 0x%x - ignoring", parent_name, id);
2679 return gst_ebml_read_skip (ebml);
2682 static GstFlowReturn
2683 gst_matroska_demux_parse_header (GstMatroskaDemux * demux, GstEbmlRead * ebml)
2690 /* this function is the first to be called */
2696 ret = gst_ebml_peek_id (ebml, &id);
2697 if (ret != GST_FLOW_OK)
2700 GST_DEBUG_OBJECT (demux, "id: %08x", id);
2702 if (id != GST_EBML_ID_HEADER) {
2703 GST_ERROR_OBJECT (demux, "Failed to read header");
2707 ret = gst_ebml_read_master (ebml, &id);
2708 if (ret != GST_FLOW_OK)
2711 while (gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
2712 ret = gst_ebml_peek_id (ebml, &id);
2713 if (ret != GST_FLOW_OK)
2717 /* is our read version uptodate? */
2718 case GST_EBML_ID_EBMLREADVERSION:{
2721 ret = gst_ebml_read_uint (ebml, &id, &num);
2722 if (ret != GST_FLOW_OK)
2724 g_assert (id == GST_EBML_ID_EBMLREADVERSION);
2725 if (num != GST_EBML_VERSION) {
2726 GST_ERROR_OBJECT (ebml, "Unsupported EBML version %" G_GUINT64_FORMAT,
2728 return GST_FLOW_ERROR;
2731 GST_DEBUG_OBJECT (ebml, "EbmlReadVersion: %" G_GUINT64_FORMAT, num);
2735 /* we only handle 8 byte lengths at max */
2736 case GST_EBML_ID_EBMLMAXSIZELENGTH:{
2739 ret = gst_ebml_read_uint (ebml, &id, &num);
2740 if (ret != GST_FLOW_OK)
2742 g_assert (id == GST_EBML_ID_EBMLMAXSIZELENGTH);
2743 if (num > sizeof (guint64)) {
2744 GST_ERROR_OBJECT (ebml,
2745 "Unsupported EBML maximum size %" G_GUINT64_FORMAT, num);
2746 return GST_FLOW_ERROR;
2748 GST_DEBUG_OBJECT (ebml, "EbmlMaxSizeLength: %" G_GUINT64_FORMAT, num);
2752 /* we handle 4 byte IDs at max */
2753 case GST_EBML_ID_EBMLMAXIDLENGTH:{
2756 ret = gst_ebml_read_uint (ebml, &id, &num);
2757 if (ret != GST_FLOW_OK)
2759 g_assert (id == GST_EBML_ID_EBMLMAXIDLENGTH);
2760 if (num > sizeof (guint32)) {
2761 GST_ERROR_OBJECT (ebml,
2762 "Unsupported EBML maximum ID %" G_GUINT64_FORMAT, num);
2763 return GST_FLOW_ERROR;
2765 GST_DEBUG_OBJECT (ebml, "EbmlMaxIdLength: %" G_GUINT64_FORMAT, num);
2769 case GST_EBML_ID_DOCTYPE:{
2772 ret = gst_ebml_read_ascii (ebml, &id, &text);
2773 if (ret != GST_FLOW_OK)
2775 g_assert (id == GST_EBML_ID_DOCTYPE);
2777 GST_DEBUG_OBJECT (ebml, "EbmlDocType: %s", GST_STR_NULL (text));
2785 case GST_EBML_ID_DOCTYPEREADVERSION:{
2788 ret = gst_ebml_read_uint (ebml, &id, &num);
2789 if (ret != GST_FLOW_OK)
2791 g_assert (id == GST_EBML_ID_DOCTYPEREADVERSION);
2793 GST_DEBUG_OBJECT (ebml, "EbmlReadVersion: %" G_GUINT64_FORMAT, num);
2798 ret = gst_matroska_demux_parse_skip (demux, ebml, "EBML header", id);
2799 if (ret != GST_FLOW_OK)
2803 /* we ignore these two, as they don't tell us anything we care about */
2804 case GST_EBML_ID_EBMLVERSION:
2805 case GST_EBML_ID_DOCTYPEVERSION:
2806 ret = gst_ebml_read_skip (ebml);
2807 if (ret != GST_FLOW_OK)
2814 ret = GST_FLOW_ERROR;
2816 if (g_str_equal (doctype, GST_MATROSKA_DOCTYPE_MATROSKA) ||
2817 g_str_equal (doctype, GST_MATROSKA_DOCTYPE_WEBM)) {
2819 GST_INFO_OBJECT (demux, "Input is %s version %d", doctype, version);
2822 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
2823 ("Demuxer version (2) is too old to read %s version %d",
2827 GST_ELEMENT_ERROR (demux, STREAM, WRONG_TYPE, (NULL),
2828 ("Input is not a matroska stream (doctype=%s)", doctype));
2832 GST_ELEMENT_ERROR (demux, STREAM, WRONG_TYPE, (NULL),
2833 ("Input is not a matroska stream"));
2839 static GstFlowReturn
2840 gst_matroska_demux_parse_tracks (GstMatroskaDemux * demux, GstEbmlRead * ebml)
2842 GstFlowReturn ret = GST_FLOW_OK;
2845 DEBUG_ELEMENT_START (demux, ebml, "Tracks");
2847 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2848 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
2852 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
2853 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
2857 /* one track within the "all-tracks" header */
2858 case GST_MATROSKA_ID_TRACKENTRY:
2859 ret = gst_matroska_demux_add_stream (demux, ebml);
2863 ret = gst_matroska_demux_parse_skip (demux, ebml, "Track", id);
2867 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
2869 demux->tracks_parsed = TRUE;
2874 static GstFlowReturn
2875 gst_matroska_demux_parse_index_cuetrack (GstMatroskaDemux * demux,
2876 GstEbmlRead * ebml, guint * nentries)
2880 GstMatroskaIndex idx;
2882 idx.pos = (guint64) - 1;
2884 idx.time = GST_CLOCK_TIME_NONE;
2887 DEBUG_ELEMENT_START (demux, ebml, "CueTrackPositions");
2889 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2890 DEBUG_ELEMENT_STOP (demux, ebml, "CueTrackPositions", ret);
2894 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
2895 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
2900 case GST_MATROSKA_ID_CUETRACK:
2904 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
2909 GST_WARNING_OBJECT (demux, "Invalid CueTrack 0");
2913 GST_DEBUG_OBJECT (demux, "CueTrack: %" G_GUINT64_FORMAT, num);
2918 /* position in file */
2919 case GST_MATROSKA_ID_CUECLUSTERPOSITION:
2923 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
2926 if (num > G_MAXINT64) {
2927 GST_WARNING_OBJECT (demux, "CueClusterPosition %" G_GUINT64_FORMAT
2936 /* number of block in the cluster */
2937 case GST_MATROSKA_ID_CUEBLOCKNUMBER:
2941 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
2945 GST_WARNING_OBJECT (demux, "Invalid CueBlockNumber 0");
2949 GST_DEBUG_OBJECT (demux, "CueBlockNumber: %" G_GUINT64_FORMAT, num);
2952 /* mild sanity check, disregard strange cases ... */
2953 if (idx.block > G_MAXUINT16) {
2954 GST_DEBUG_OBJECT (demux, "... looks suspicious, ignoring");
2961 ret = gst_matroska_demux_parse_skip (demux, ebml, "CueTrackPositions",
2965 case GST_MATROSKA_ID_CUECODECSTATE:
2966 case GST_MATROSKA_ID_CUEREFERENCE:
2967 ret = gst_ebml_read_skip (ebml);
2972 DEBUG_ELEMENT_STOP (demux, ebml, "CueTrackPositions", ret);
2974 if ((ret == GST_FLOW_OK || ret == GST_FLOW_UNEXPECTED)
2975 && idx.pos != (guint64) - 1 && idx.track > 0) {
2976 g_array_append_val (demux->index, idx);
2978 } else if (ret == GST_FLOW_OK || ret == GST_FLOW_UNEXPECTED) {
2979 GST_DEBUG_OBJECT (demux, "CueTrackPositions without valid content");
2985 static GstFlowReturn
2986 gst_matroska_demux_parse_index_pointentry (GstMatroskaDemux * demux,
2991 GstClockTime time = GST_CLOCK_TIME_NONE;
2994 DEBUG_ELEMENT_START (demux, ebml, "CuePoint");
2996 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2997 DEBUG_ELEMENT_STOP (demux, ebml, "CuePoint", ret);
3001 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3002 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3006 /* one single index entry ('point') */
3007 case GST_MATROSKA_ID_CUETIME:
3009 if ((ret = gst_ebml_read_uint (ebml, &id, &time)) != GST_FLOW_OK)
3012 GST_DEBUG_OBJECT (demux, "CueTime: %" G_GUINT64_FORMAT, time);
3013 time = time * demux->time_scale;
3017 /* position in the file + track to which it belongs */
3018 case GST_MATROSKA_ID_CUETRACKPOSITIONS:
3021 gst_matroska_demux_parse_index_cuetrack (demux, ebml,
3022 &nentries)) != GST_FLOW_OK)
3028 ret = gst_matroska_demux_parse_skip (demux, ebml, "CuePoint", id);
3033 DEBUG_ELEMENT_STOP (demux, ebml, "CuePoint", ret);
3036 if (time == GST_CLOCK_TIME_NONE) {
3037 GST_WARNING_OBJECT (demux, "CuePoint without valid time");
3038 g_array_remove_range (demux->index, demux->index->len - nentries,
3043 for (i = demux->index->len - nentries; i < demux->index->len; i++) {
3044 GstMatroskaIndex *idx =
3045 &g_array_index (demux->index, GstMatroskaIndex, i);
3048 GST_DEBUG_OBJECT (demux, "Index entry: pos=%" G_GUINT64_FORMAT
3049 ", time=%" GST_TIME_FORMAT ", track=%u, block=%u", idx->pos,
3050 GST_TIME_ARGS (idx->time), (guint) idx->track, (guint) idx->block);
3054 GST_DEBUG_OBJECT (demux, "Empty CuePoint");
3061 gst_matroska_index_compare (GstMatroskaIndex * i1, GstMatroskaIndex * i2)
3063 if (i1->time < i2->time)
3065 else if (i1->time > i2->time)
3067 else if (i1->block < i2->block)
3069 else if (i1->block > i2->block)
3075 static GstFlowReturn
3076 gst_matroska_demux_parse_index (GstMatroskaDemux * demux, GstEbmlRead * ebml)
3079 GstFlowReturn ret = GST_FLOW_OK;
3083 g_array_free (demux->index, TRUE);
3085 g_array_sized_new (FALSE, FALSE, sizeof (GstMatroskaIndex), 128);
3087 DEBUG_ELEMENT_START (demux, ebml, "Cues");
3089 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3090 DEBUG_ELEMENT_STOP (demux, ebml, "Cues", ret);
3094 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3095 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3099 /* one single index entry ('point') */
3100 case GST_MATROSKA_ID_POINTENTRY:
3101 ret = gst_matroska_demux_parse_index_pointentry (demux, ebml);
3105 ret = gst_matroska_demux_parse_skip (demux, ebml, "Cues", id);
3109 DEBUG_ELEMENT_STOP (demux, ebml, "Cues", ret);
3111 /* Sort index by time, smallest time first, for easier searching */
3112 g_array_sort (demux->index, (GCompareFunc) gst_matroska_index_compare);
3114 /* Now sort the track specific index entries into their own arrays */
3115 for (i = 0; i < demux->index->len; i++) {
3116 GstMatroskaIndex *idx = &g_array_index (demux->index, GstMatroskaIndex, i);
3118 GstMatroskaTrackContext *ctx;
3120 if (demux->element_index) {
3123 if (idx->track != 0 &&
3125 gst_matroska_demux_stream_from_num (demux, idx->track)) != -1) {
3126 ctx = g_ptr_array_index (demux->src, track_num);
3128 if (ctx->index_writer_id == -1)
3129 gst_index_get_writer_id (demux->element_index, GST_OBJECT (ctx->pad),
3130 &ctx->index_writer_id);
3131 writer_id = ctx->index_writer_id;
3133 if (demux->element_index_writer_id == -1)
3134 gst_index_get_writer_id (demux->element_index, GST_OBJECT (demux),
3135 &demux->element_index_writer_id);
3136 writer_id = demux->element_index_writer_id;
3139 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
3140 G_GUINT64_FORMAT " for writer id %d", GST_TIME_ARGS (idx->time),
3141 idx->pos, writer_id);
3142 gst_index_add_association (demux->element_index, writer_id,
3143 GST_ASSOCIATION_FLAG_KEY_UNIT, GST_FORMAT_TIME, idx->time,
3144 GST_FORMAT_BYTES, idx->pos + demux->ebml_segment_start, NULL);
3147 if (idx->track == 0)
3150 track_num = gst_matroska_demux_stream_from_num (demux, idx->track);
3151 if (track_num == -1)
3154 ctx = g_ptr_array_index (demux->src, track_num);
3156 if (ctx->index_table == NULL)
3158 g_array_sized_new (FALSE, FALSE, sizeof (GstMatroskaIndex), 128);
3160 g_array_append_vals (ctx->index_table, idx, 1);
3163 demux->index_parsed = TRUE;
3168 static GstFlowReturn
3169 gst_matroska_demux_parse_info (GstMatroskaDemux * demux, GstEbmlRead * ebml)
3171 GstFlowReturn ret = GST_FLOW_OK;
3174 DEBUG_ELEMENT_START (demux, ebml, "SegmentInfo");
3176 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3177 DEBUG_ELEMENT_STOP (demux, ebml, "SegmentInfo", ret);
3181 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3182 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3186 /* cluster timecode */
3187 case GST_MATROSKA_ID_TIMECODESCALE:{
3190 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
3194 GST_DEBUG_OBJECT (demux, "TimeCodeScale: %" G_GUINT64_FORMAT, num);
3195 demux->time_scale = num;
3199 case GST_MATROSKA_ID_DURATION:{
3203 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
3207 GST_WARNING_OBJECT (demux, "Invalid duration %lf", num);
3211 GST_DEBUG_OBJECT (demux, "Duration: %lf", num);
3213 dur = gst_gdouble_to_guint64 (num *
3214 gst_guint64_to_gdouble (demux->time_scale));
3215 if (GST_CLOCK_TIME_IS_VALID (dur) && dur <= G_MAXINT64)
3216 gst_segment_set_duration (&demux->segment, GST_FORMAT_TIME, dur);
3220 case GST_MATROSKA_ID_WRITINGAPP:{
3223 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
3226 GST_DEBUG_OBJECT (demux, "WritingApp: %s", GST_STR_NULL (text));
3227 demux->writing_app = text;
3231 case GST_MATROSKA_ID_MUXINGAPP:{
3234 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
3237 GST_DEBUG_OBJECT (demux, "MuxingApp: %s", GST_STR_NULL (text));
3238 demux->muxing_app = text;
3242 case GST_MATROSKA_ID_DATEUTC:{
3245 if ((ret = gst_ebml_read_date (ebml, &id, &time)) != GST_FLOW_OK)
3248 GST_DEBUG_OBJECT (demux, "DateUTC: %" G_GINT64_FORMAT, time);
3249 demux->created = time;
3253 case GST_MATROSKA_ID_TITLE:{
3255 GstTagList *taglist;
3257 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
3260 GST_DEBUG_OBJECT (demux, "Title: %s", GST_STR_NULL (text));
3261 taglist = gst_tag_list_new ();
3262 gst_tag_list_add (taglist, GST_TAG_MERGE_APPEND, GST_TAG_TITLE, text,
3264 gst_matroska_demux_found_global_tag (demux, taglist);
3270 ret = gst_matroska_demux_parse_skip (demux, ebml, "SegmentInfo", id);
3274 case GST_MATROSKA_ID_SEGMENTUID:
3275 case GST_MATROSKA_ID_SEGMENTFILENAME:
3276 case GST_MATROSKA_ID_PREVUID:
3277 case GST_MATROSKA_ID_PREVFILENAME:
3278 case GST_MATROSKA_ID_NEXTUID:
3279 case GST_MATROSKA_ID_NEXTFILENAME:
3280 case GST_MATROSKA_ID_SEGMENTFAMILY:
3281 case GST_MATROSKA_ID_CHAPTERTRANSLATE:
3282 ret = gst_ebml_read_skip (ebml);
3287 DEBUG_ELEMENT_STOP (demux, ebml, "SegmentInfo", ret);
3289 demux->segmentinfo_parsed = TRUE;
3294 static GstFlowReturn
3295 gst_matroska_demux_parse_metadata_id_simple_tag (GstMatroskaDemux * demux,
3296 GstEbmlRead * ebml, GstTagList ** p_taglist)
3298 /* FIXME: check if there are more useful mappings */
3301 const gchar *matroska_tagname;
3302 const gchar *gstreamer_tagname;
3306 GST_MATROSKA_TAG_ID_TITLE, GST_TAG_TITLE}, {
3307 GST_MATROSKA_TAG_ID_AUTHOR, GST_TAG_ARTIST}, {
3308 GST_MATROSKA_TAG_ID_ALBUM, GST_TAG_ALBUM}, {
3309 GST_MATROSKA_TAG_ID_COMMENTS, GST_TAG_COMMENT}, {
3310 GST_MATROSKA_TAG_ID_BITSPS, GST_TAG_BITRATE}, {
3311 GST_MATROSKA_TAG_ID_BPS, GST_TAG_BITRATE}, {
3312 GST_MATROSKA_TAG_ID_ENCODER, GST_TAG_ENCODER}, {
3313 GST_MATROSKA_TAG_ID_DATE, GST_TAG_DATE}, {
3314 GST_MATROSKA_TAG_ID_ISRC, GST_TAG_ISRC}, {
3315 GST_MATROSKA_TAG_ID_COPYRIGHT, GST_TAG_COPYRIGHT}, {
3316 GST_MATROSKA_TAG_ID_BPM, GST_TAG_BEATS_PER_MINUTE}, {
3317 GST_MATROSKA_TAG_ID_TERMS_OF_USE, GST_TAG_LICENSE}, {
3318 GST_MATROSKA_TAG_ID_COMPOSER, GST_TAG_COMPOSER}, {
3319 GST_MATROSKA_TAG_ID_LEAD_PERFORMER, GST_TAG_PERFORMER}, {
3320 GST_MATROSKA_TAG_ID_GENRE, GST_TAG_GENRE}
3324 gchar *value = NULL;
3327 DEBUG_ELEMENT_START (demux, ebml, "SimpleTag");
3329 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3330 DEBUG_ELEMENT_STOP (demux, ebml, "SimpleTag", ret);
3334 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3335 /* read all sub-entries */
3337 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3341 case GST_MATROSKA_ID_TAGNAME:
3344 ret = gst_ebml_read_ascii (ebml, &id, &tag);
3345 GST_DEBUG_OBJECT (demux, "TagName: %s", GST_STR_NULL (tag));
3348 case GST_MATROSKA_ID_TAGSTRING:
3351 ret = gst_ebml_read_utf8 (ebml, &id, &value);
3352 GST_DEBUG_OBJECT (demux, "TagString: %s", GST_STR_NULL (value));
3356 ret = gst_matroska_demux_parse_skip (demux, ebml, "SimpleTag", id);
3360 case GST_MATROSKA_ID_TAGLANGUAGE:
3361 case GST_MATROSKA_ID_TAGDEFAULT:
3362 case GST_MATROSKA_ID_TAGBINARY:
3363 ret = gst_ebml_read_skip (ebml);
3368 DEBUG_ELEMENT_STOP (demux, ebml, "SimpleTag", ret);
3373 for (i = 0; i < G_N_ELEMENTS (tag_conv); i++) {
3374 const gchar *tagname_gst = tag_conv[i].gstreamer_tagname;
3376 const gchar *tagname_mkv = tag_conv[i].matroska_tagname;
3378 if (strcmp (tagname_mkv, tag) == 0) {
3379 GValue dest = { 0, };
3380 GType dest_type = gst_tag_get_type (tagname_gst);
3382 g_value_init (&dest, dest_type);
3383 if (gst_value_deserialize (&dest, value)) {
3384 gst_tag_list_add_values (*p_taglist, GST_TAG_MERGE_APPEND,
3385 tagname_gst, &dest, NULL);
3387 GST_WARNING_OBJECT (demux, "Can't transform tag '%s' with "
3388 "value '%s' to target type '%s'", tag, value,
3389 g_type_name (dest_type));
3391 g_value_unset (&dest);
3403 static GstFlowReturn
3404 gst_matroska_demux_parse_metadata_id_tag (GstMatroskaDemux * demux,
3405 GstEbmlRead * ebml, GstTagList ** p_taglist)
3410 DEBUG_ELEMENT_START (demux, ebml, "Tag");
3412 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3413 DEBUG_ELEMENT_STOP (demux, ebml, "Tag", ret);
3417 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3418 /* read all sub-entries */
3420 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3424 case GST_MATROSKA_ID_SIMPLETAG:
3425 ret = gst_matroska_demux_parse_metadata_id_simple_tag (demux, ebml,
3430 ret = gst_matroska_demux_parse_skip (demux, ebml, "Tag", id);
3435 DEBUG_ELEMENT_STOP (demux, ebml, "Tag", ret);
3440 static GstFlowReturn
3441 gst_matroska_demux_parse_metadata (GstMatroskaDemux * demux, GstEbmlRead * ebml)
3443 GstTagList *taglist;
3444 GstFlowReturn ret = GST_FLOW_OK;
3449 curpos = gst_ebml_read_get_pos (ebml);
3451 /* Make sure we don't parse a tags element twice and
3452 * post it's tags twice */
3453 curpos = gst_ebml_read_get_pos (ebml);
3454 for (l = demux->tags_parsed; l; l = l->next) {
3455 guint64 *pos = l->data;
3457 if (*pos == curpos) {
3458 GST_DEBUG_OBJECT (demux, "Skipping already parsed Tags at offset %"
3459 G_GUINT64_FORMAT, curpos);
3464 demux->tags_parsed =
3465 g_list_prepend (demux->tags_parsed, g_slice_new (guint64));
3466 *((guint64 *) demux->tags_parsed->data) = curpos;
3469 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3470 DEBUG_ELEMENT_STOP (demux, ebml, "Tags", ret);
3474 taglist = gst_tag_list_new ();
3476 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3477 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3481 case GST_MATROSKA_ID_TAG:
3482 ret = gst_matroska_demux_parse_metadata_id_tag (demux, ebml, &taglist);
3486 ret = gst_matroska_demux_parse_skip (demux, ebml, "Tags", id);
3488 /* FIXME: Use to limit the tags to specific pads */
3489 case GST_MATROSKA_ID_TARGETS:
3490 ret = gst_ebml_read_skip (ebml);
3495 DEBUG_ELEMENT_STOP (demux, ebml, "Tags", ret);
3497 gst_matroska_demux_found_global_tag (demux, taglist);
3502 static GstFlowReturn
3503 gst_matroska_demux_parse_attached_file (GstMatroskaDemux * demux,
3504 GstEbmlRead * ebml, GstTagList * taglist)
3508 gchar *description = NULL;
3509 gchar *filename = NULL;
3510 gchar *mimetype = NULL;
3511 guint8 *data = NULL;
3512 guint64 datalen = 0;
3514 DEBUG_ELEMENT_START (demux, ebml, "AttachedFile");
3516 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3517 DEBUG_ELEMENT_STOP (demux, ebml, "AttachedFile", ret);
3521 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3522 /* read all sub-entries */
3524 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3528 case GST_MATROSKA_ID_FILEDESCRIPTION:
3530 GST_WARNING_OBJECT (demux, "FileDescription can only appear once");
3534 ret = gst_ebml_read_utf8 (ebml, &id, &description);
3535 GST_DEBUG_OBJECT (demux, "FileDescription: %s",
3536 GST_STR_NULL (description));
3538 case GST_MATROSKA_ID_FILENAME:
3540 GST_WARNING_OBJECT (demux, "FileName can only appear once");
3544 ret = gst_ebml_read_utf8 (ebml, &id, &filename);
3546 GST_DEBUG_OBJECT (demux, "FileName: %s", GST_STR_NULL (filename));
3548 case GST_MATROSKA_ID_FILEMIMETYPE:
3550 GST_WARNING_OBJECT (demux, "FileMimeType can only appear once");
3554 ret = gst_ebml_read_ascii (ebml, &id, &mimetype);
3555 GST_DEBUG_OBJECT (demux, "FileMimeType: %s", GST_STR_NULL (mimetype));
3557 case GST_MATROSKA_ID_FILEDATA:
3559 GST_WARNING_OBJECT (demux, "FileData can only appear once");
3563 ret = gst_ebml_read_binary (ebml, &id, &data, &datalen);
3564 GST_DEBUG_OBJECT (demux, "FileData of size %" G_GUINT64_FORMAT,
3569 ret = gst_matroska_demux_parse_skip (demux, ebml, "AttachedFile", id);
3571 case GST_MATROSKA_ID_FILEUID:
3572 ret = gst_ebml_read_skip (ebml);
3577 DEBUG_ELEMENT_STOP (demux, ebml, "AttachedFile", ret);
3579 if (filename && mimetype && data && datalen > 0) {
3580 GstTagImageType image_type = GST_TAG_IMAGE_TYPE_NONE;
3581 GstBuffer *tagbuffer = NULL;
3583 gchar *filename_lc = g_utf8_strdown (filename, -1);
3585 GST_DEBUG_OBJECT (demux, "Creating tag for attachment with filename '%s', "
3586 "mimetype '%s', description '%s', size %" G_GUINT64_FORMAT, filename,
3587 mimetype, GST_STR_NULL (description), datalen);
3589 /* TODO: better heuristics for different image types */
3590 if (strstr (filename_lc, "cover")) {
3591 if (strstr (filename_lc, "back"))
3592 image_type = GST_TAG_IMAGE_TYPE_BACK_COVER;
3594 image_type = GST_TAG_IMAGE_TYPE_FRONT_COVER;
3595 } else if (g_str_has_prefix (mimetype, "image/") ||
3596 g_str_has_suffix (filename_lc, "png") ||
3597 g_str_has_suffix (filename_lc, "jpg") ||
3598 g_str_has_suffix (filename_lc, "jpeg") ||
3599 g_str_has_suffix (filename_lc, "gif") ||
3600 g_str_has_suffix (filename_lc, "bmp")) {
3601 image_type = GST_TAG_IMAGE_TYPE_UNDEFINED;
3603 g_free (filename_lc);
3605 /* First try to create an image tag buffer from this */
3606 if (image_type != GST_TAG_IMAGE_TYPE_NONE) {
3608 gst_tag_image_data_to_image_buffer (data, datalen, image_type);
3611 image_type = GST_TAG_IMAGE_TYPE_NONE;
3614 /* if this failed create an attachment buffer */
3616 tagbuffer = gst_buffer_new_and_alloc (datalen);
3618 memcpy (GST_BUFFER_DATA (tagbuffer), data, datalen);
3619 GST_BUFFER_SIZE (tagbuffer) = datalen;
3621 caps = gst_type_find_helper_for_buffer (NULL, tagbuffer, NULL);
3623 caps = gst_caps_new_simple (mimetype, NULL);
3624 gst_buffer_set_caps (tagbuffer, caps);
3625 gst_caps_unref (caps);
3628 /* Set filename and description on the caps */
3629 caps = GST_BUFFER_CAPS (tagbuffer);
3630 gst_caps_set_simple (caps, "filename", G_TYPE_STRING, filename, NULL);
3632 gst_caps_set_simple (caps, "description", G_TYPE_STRING, description,
3635 GST_DEBUG_OBJECT (demux,
3636 "Created attachment buffer with caps: %" GST_PTR_FORMAT, caps);
3638 /* and append to the tag list */
3639 if (image_type != GST_TAG_IMAGE_TYPE_NONE)
3640 gst_tag_list_add (taglist, GST_TAG_MERGE_APPEND, GST_TAG_IMAGE, tagbuffer,
3643 gst_tag_list_add (taglist, GST_TAG_MERGE_APPEND, GST_TAG_ATTACHMENT,
3650 g_free (description);
3655 static GstFlowReturn
3656 gst_matroska_demux_parse_attachments (GstMatroskaDemux * demux,
3660 GstFlowReturn ret = GST_FLOW_OK;
3661 GstTagList *taglist;
3663 DEBUG_ELEMENT_START (demux, ebml, "Attachments");
3665 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3666 DEBUG_ELEMENT_STOP (demux, ebml, "Attachments", ret);
3670 taglist = gst_tag_list_new ();
3672 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3673 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3677 case GST_MATROSKA_ID_ATTACHEDFILE:
3678 ret = gst_matroska_demux_parse_attached_file (demux, ebml, taglist);
3682 ret = gst_matroska_demux_parse_skip (demux, ebml, "Attachments", id);
3686 DEBUG_ELEMENT_STOP (demux, ebml, "Attachments", ret);
3688 if (gst_structure_n_fields (GST_STRUCTURE (taglist)) > 0) {
3689 GST_DEBUG_OBJECT (demux, "Storing attachment tags");
3690 gst_matroska_demux_found_global_tag (demux, taglist);
3692 GST_DEBUG_OBJECT (demux, "No valid attachments found");
3693 gst_tag_list_free (taglist);
3696 demux->attachments_parsed = TRUE;
3701 static GstFlowReturn
3702 gst_matroska_demux_parse_chapters (GstMatroskaDemux * demux, GstEbmlRead * ebml)
3705 GstFlowReturn ret = GST_FLOW_OK;
3707 GST_WARNING_OBJECT (demux, "Parsing of chapters not implemented yet");
3709 /* TODO: implement parsing of chapters */
3711 DEBUG_ELEMENT_START (demux, ebml, "Chapters");
3713 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3714 DEBUG_ELEMENT_STOP (demux, ebml, "Chapters", ret);
3718 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3719 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3724 ret = gst_ebml_read_skip (ebml);
3729 DEBUG_ELEMENT_STOP (demux, ebml, "Chapters", ret);
3734 * Read signed/unsigned "EBML" numbers.
3735 * Return: number of bytes processed.
3739 gst_matroska_ebmlnum_uint (guint8 * data, guint size, guint64 * num)
3741 gint len_mask = 0x80, read = 1, n = 1, num_ffs = 0;
3749 while (read <= 8 && !(total & len_mask)) {
3756 if ((total &= (len_mask - 1)) == len_mask - 1)
3761 if (data[n] == 0xff)
3763 total = (total << 8) | data[n];
3767 if (read == num_ffs && total != 0)
3776 gst_matroska_ebmlnum_sint (guint8 * data, guint size, gint64 * num)
3781 /* read as unsigned number first */
3782 if ((res = gst_matroska_ebmlnum_uint (data, size, &unum)) < 0)
3786 if (unum == G_MAXUINT64)
3789 *num = unum - ((1 << ((7 * res) - 1)) - 1);
3795 * Mostly used for subtitles. We add void filler data for each
3796 * lagging stream to make sure we don't deadlock.
3800 gst_matroska_demux_sync_streams (GstMatroskaDemux * demux)
3804 GST_LOG_OBJECT (demux, "Sync to %" GST_TIME_FORMAT,
3805 GST_TIME_ARGS (demux->segment.last_stop));
3807 g_assert (demux->num_streams == demux->src->len);
3808 for (stream_nr = 0; stream_nr < demux->src->len; stream_nr++) {
3809 GstMatroskaTrackContext *context;
3811 context = g_ptr_array_index (demux->src, stream_nr);
3813 GST_LOG_OBJECT (demux,
3814 "Checking for resync on stream %d (%" GST_TIME_FORMAT ")", stream_nr,
3815 GST_TIME_ARGS (context->pos));
3817 if (G_LIKELY (context->type != GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
3818 GST_LOG_OBJECT (demux, "Skipping sync on non-subtitle stream");
3822 /* does it lag? 0.5 seconds is a random threshold...
3823 * lag need only be considered if we have advanced into requested segment */
3824 if (GST_CLOCK_TIME_IS_VALID (context->pos) &&
3825 GST_CLOCK_TIME_IS_VALID (demux->segment.last_stop) &&
3826 demux->segment.last_stop > demux->segment.start &&
3827 context->pos + (GST_SECOND / 2) < demux->segment.last_stop) {
3830 new_start = demux->segment.last_stop - (GST_SECOND / 2);
3831 if (GST_CLOCK_TIME_IS_VALID (demux->segment.stop))
3832 new_start = MIN (new_start, demux->segment.stop);
3833 GST_DEBUG_OBJECT (demux,
3834 "Synchronizing stream %d with others by advancing time " "from %"
3835 GST_TIME_FORMAT " to %" GST_TIME_FORMAT, stream_nr,
3836 GST_TIME_ARGS (context->pos), GST_TIME_ARGS (new_start));
3838 context->pos = new_start;
3840 /* advance stream time */
3841 gst_pad_push_event (context->pad,
3842 gst_event_new_new_segment (TRUE, demux->segment.rate,
3843 demux->segment.format, new_start,
3844 demux->segment.stop, new_start));
3849 static GstFlowReturn
3850 gst_matroska_demux_push_hdr_buf (GstMatroskaDemux * demux,
3851 GstMatroskaTrackContext * stream, guint8 * data, guint len)
3853 GstFlowReturn ret, cret;
3854 GstBuffer *header_buf = NULL;
3856 ret = gst_pad_alloc_buffer_and_set_caps (stream->pad,
3857 GST_BUFFER_OFFSET_NONE, len, stream->caps, &header_buf);
3859 /* we combine but don't use the combined value to check if we have a buffer
3860 * or not. The combined value is what we return. */
3861 cret = gst_matroska_demux_combine_flows (demux, stream, ret);
3862 if (ret != GST_FLOW_OK)
3865 memcpy (GST_BUFFER_DATA (header_buf), data, len);
3867 if (stream->set_discont) {
3868 GST_BUFFER_FLAG_SET (header_buf, GST_BUFFER_FLAG_DISCONT);
3869 stream->set_discont = FALSE;
3872 ret = gst_pad_push (stream->pad, header_buf);
3875 cret = gst_matroska_demux_combine_flows (demux, stream, ret);
3882 GST_DEBUG_OBJECT (demux, "could not alloc buffer: %s, combined %s",
3883 gst_flow_get_name (ret), gst_flow_get_name (cret));
3888 static GstFlowReturn
3889 gst_matroska_demux_push_flac_codec_priv_data (GstMatroskaDemux * demux,
3890 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 < ((4) + (4 + 34))) {
3902 GST_WARNING_OBJECT (demux, "not enough codec priv data for flac headers");
3903 return GST_FLOW_ERROR;
3906 if (memcmp (pdata, "fLaC", 4) != 0) {
3907 GST_WARNING_OBJECT (demux, "no flac marker at start of stream headers");
3908 return GST_FLOW_ERROR;
3911 ret = gst_matroska_demux_push_hdr_buf (demux, stream, pdata, 4);
3912 if (ret != GST_FLOW_OK)
3915 off = 4; /* skip fLaC marker */
3916 while (off < stream->codec_priv_size) {
3917 len = GST_READ_UINT8 (pdata + off + 1) << 16;
3918 len |= GST_READ_UINT8 (pdata + off + 2) << 8;
3919 len |= GST_READ_UINT8 (pdata + off + 3);
3921 GST_DEBUG_OBJECT (demux, "header packet: len=%u bytes, flags=0x%02x",
3922 len, (guint) pdata[off]);
3924 ret = gst_matroska_demux_push_hdr_buf (demux, stream, pdata + off, len + 4);
3925 if (ret != GST_FLOW_OK)
3933 static GstFlowReturn
3934 gst_matroska_demux_push_speex_codec_priv_data (GstMatroskaDemux * demux,
3935 GstMatroskaTrackContext * stream)
3940 GST_LOG_OBJECT (demux, "priv data size = %u", stream->codec_priv_size);
3942 pdata = (guint8 *) stream->codec_priv;
3944 /* need at least 'fLaC' marker + STREAMINFO metadata block */
3945 if (stream->codec_priv_size < 80) {
3946 GST_WARNING_OBJECT (demux, "not enough codec priv data for speex headers");
3947 return GST_FLOW_ERROR;
3950 if (memcmp (pdata, "Speex ", 8) != 0) {
3951 GST_WARNING_OBJECT (demux, "no Speex marker at start of stream headers");
3952 return GST_FLOW_ERROR;
3955 ret = gst_matroska_demux_push_hdr_buf (demux, stream, pdata, 80);
3956 if (ret != GST_FLOW_OK)
3959 if (stream->codec_priv_size == 80)
3962 return gst_matroska_demux_push_hdr_buf (demux, stream, pdata + 80,
3963 stream->codec_priv_size - 80);
3966 static GstFlowReturn
3967 gst_matroska_demux_push_xiph_codec_priv_data (GstMatroskaDemux * demux,
3968 GstMatroskaTrackContext * stream)
3971 guint8 *p = (guint8 *) stream->codec_priv;
3972 gint i, offset, num_packets;
3973 guint *length, last;
3975 /* start of the stream and vorbis audio or theora video, need to
3976 * send the codec_priv data as first three packets */
3977 num_packets = p[0] + 1;
3978 GST_DEBUG_OBJECT (demux, "%u stream headers, total length=%u bytes",
3979 (guint) num_packets, stream->codec_priv_size);
3981 length = g_alloca (num_packets * sizeof (guint));
3985 /* first packets, read length values */
3986 for (i = 0; i < num_packets - 1; i++) {
3988 while (offset < stream->codec_priv_size) {
3989 length[i] += p[offset];
3990 if (p[offset++] != 0xff)
3995 if (offset + last > stream->codec_priv_size)
3996 return GST_FLOW_ERROR;
3998 /* last packet is the remaining size */
3999 length[i] = stream->codec_priv_size - offset - last;
4001 for (i = 0; i < num_packets; i++) {
4002 GST_DEBUG_OBJECT (demux, "buffer %d: length=%u bytes", i,
4004 if (offset + length[i] > stream->codec_priv_size)
4005 return GST_FLOW_ERROR;
4008 gst_matroska_demux_push_hdr_buf (demux, stream, p + offset, length[i]);
4009 if (ret != GST_FLOW_OK)
4012 offset += length[i];
4018 gst_matroska_demux_push_dvd_clut_change_event (GstMatroskaDemux * demux,
4019 GstMatroskaTrackContext * stream)
4023 g_assert (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB));
4025 if (!stream->codec_priv)
4028 /* ideally, VobSub private data should be parsed and stored more convenient
4029 * elsewhere, but for now, only interested in a small part */
4031 /* make sure we have terminating 0 */
4032 buf = g_strndup ((gchar *) stream->codec_priv, stream->codec_priv_size);
4034 /* just locate and parse palette part */
4035 start = strstr (buf, "palette:");
4040 guint8 r, g, b, y, u, v;
4043 while (g_ascii_isspace (*start))
4045 for (i = 0; i < 16; i++) {
4046 if (sscanf (start, "%06x", &col) != 1)
4049 while ((*start == ',') || g_ascii_isspace (*start))
4051 /* sigh, need to convert this from vobsub pseudo-RGB to YUV */
4052 r = (col >> 16) & 0xff;
4053 g = (col >> 8) & 0xff;
4055 y = CLAMP ((0.1494 * r + 0.6061 * g + 0.2445 * b) * 219 / 255 + 16, 0,
4057 u = CLAMP (0.6066 * r - 0.4322 * g - 0.1744 * b + 128, 0, 255);
4058 v = CLAMP (-0.08435 * r - 0.3422 * g + 0.4266 * b + 128, 0, 255);
4059 clut[i] = (y << 16) | (u << 8) | v;
4062 /* got them all without problems; build and send event */
4066 s = gst_structure_new ("application/x-gst-dvd", "event", G_TYPE_STRING,
4067 "dvd-spu-clut-change", "clut00", G_TYPE_INT, clut[0], "clut01",
4068 G_TYPE_INT, clut[1], "clut02", G_TYPE_INT, clut[2], "clut03",
4069 G_TYPE_INT, clut[3], "clut04", G_TYPE_INT, clut[4], "clut05",
4070 G_TYPE_INT, clut[5], "clut06", G_TYPE_INT, clut[6], "clut07",
4071 G_TYPE_INT, clut[7], "clut08", G_TYPE_INT, clut[8], "clut09",
4072 G_TYPE_INT, clut[9], "clut10", G_TYPE_INT, clut[10], "clut11",
4073 G_TYPE_INT, clut[11], "clut12", G_TYPE_INT, clut[12], "clut13",
4074 G_TYPE_INT, clut[13], "clut14", G_TYPE_INT, clut[14], "clut15",
4075 G_TYPE_INT, clut[15], NULL);
4077 gst_pad_push_event (stream->pad,
4078 gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM, s));
4084 static GstFlowReturn
4085 gst_matroska_demux_add_mpeg_seq_header (GstElement * element,
4086 GstMatroskaTrackContext * stream, GstBuffer ** buf)
4088 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
4090 guint seq_header_len;
4093 if (stream->codec_state) {
4094 seq_header = stream->codec_state;
4095 seq_header_len = stream->codec_state_size;
4096 } else if (stream->codec_priv) {
4097 seq_header = stream->codec_priv;
4098 seq_header_len = stream->codec_priv_size;
4103 /* Sequence header only needed for keyframes */
4104 if (GST_BUFFER_FLAG_IS_SET (*buf, GST_BUFFER_FLAG_DELTA_UNIT))
4107 if (GST_BUFFER_SIZE (*buf) < 4)
4110 header = GST_READ_UINT32_BE (GST_BUFFER_DATA (*buf));
4111 /* Sequence start code, if not found prepend */
4112 if (header != 0x000001b3) {
4114 GstFlowReturn ret, cret;
4116 ret = gst_pad_alloc_buffer_and_set_caps (stream->pad,
4117 GST_BUFFER_OFFSET_NONE, GST_BUFFER_SIZE (*buf) + seq_header_len,
4118 stream->caps, &newbuf);
4119 cret = gst_matroska_demux_combine_flows (demux, stream, ret);
4120 if (ret != GST_FLOW_OK) {
4121 GST_WARNING_OBJECT (demux, "Reallocating buffer for sequence header "
4122 "failed: %s, combined flow return: %s", gst_flow_get_name (ret),
4123 gst_flow_get_name (cret));
4127 GST_DEBUG_OBJECT (demux, "Prepending MPEG sequence header");
4128 gst_buffer_copy_metadata (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
4129 GST_BUFFER_COPY_FLAGS);
4130 g_memmove (GST_BUFFER_DATA (newbuf), seq_header, seq_header_len);
4131 g_memmove (GST_BUFFER_DATA (newbuf) + seq_header_len,
4132 GST_BUFFER_DATA (*buf), GST_BUFFER_SIZE (*buf));
4133 gst_buffer_unref (*buf);
4140 static GstFlowReturn
4141 gst_matroska_demux_add_wvpk_header (GstElement * element,
4142 GstMatroskaTrackContext * stream, GstBuffer ** buf)
4144 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
4145 GstMatroskaTrackAudioContext *audiocontext =
4146 (GstMatroskaTrackAudioContext *) stream;
4147 GstBuffer *newbuf = NULL;
4150 GstFlowReturn ret, cret = GST_FLOW_OK;
4158 wvh.version = GST_READ_UINT16_LE (stream->codec_priv);
4161 wvh.total_samples = -1;
4162 wvh.block_index = audiocontext->wvpk_block_index;
4164 if (audiocontext->channels <= 2) {
4165 guint32 block_samples;
4167 block_samples = GST_READ_UINT32_LE (GST_BUFFER_DATA (*buf));
4168 /* we need to reconstruct the header of the wavpack block */
4170 /* -20 because ck_size is the size of the wavpack block -8
4171 * and lace_size is the size of the wavpack block + 12
4172 * (the three guint32 of the header that already are in the buffer) */
4173 wvh.ck_size = GST_BUFFER_SIZE (*buf) + sizeof (Wavpack4Header) - 20;
4175 /* block_samples, flags and crc are already in the buffer */
4176 newlen = GST_BUFFER_SIZE (*buf) + sizeof (Wavpack4Header) - 12;
4178 gst_pad_alloc_buffer_and_set_caps (stream->pad, GST_BUFFER_OFFSET_NONE,
4179 newlen, stream->caps, &newbuf);
4180 cret = gst_matroska_demux_combine_flows (demux, stream, ret);
4181 if (ret != GST_FLOW_OK) {
4182 GST_DEBUG_OBJECT (demux, "pad_alloc failed %s, combined %s",
4183 gst_flow_get_name (ret), gst_flow_get_name (cret));
4187 data = GST_BUFFER_DATA (newbuf);
4192 GST_WRITE_UINT32_LE (data + 4, wvh.ck_size);
4193 GST_WRITE_UINT16_LE (data + 8, wvh.version);
4194 GST_WRITE_UINT8 (data + 10, wvh.track_no);
4195 GST_WRITE_UINT8 (data + 11, wvh.index_no);
4196 GST_WRITE_UINT32_LE (data + 12, wvh.total_samples);
4197 GST_WRITE_UINT32_LE (data + 16, wvh.block_index);
4198 g_memmove (data + 20, GST_BUFFER_DATA (*buf), GST_BUFFER_SIZE (*buf));
4199 gst_buffer_copy_metadata (newbuf, *buf,
4200 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS);
4201 gst_buffer_unref (*buf);
4203 audiocontext->wvpk_block_index += block_samples;
4208 guint32 block_samples, flags, crc, blocksize;
4210 data = GST_BUFFER_DATA (*buf);
4211 size = GST_BUFFER_SIZE (*buf);
4214 GST_ERROR_OBJECT (demux, "Too small wavpack buffer");
4215 return GST_FLOW_ERROR;
4218 block_samples = GST_READ_UINT32_LE (data);
4223 flags = GST_READ_UINT32_LE (data);
4226 crc = GST_READ_UINT32_LE (data);
4229 blocksize = GST_READ_UINT32_LE (data);
4233 if (blocksize == 0 || size < blocksize)
4236 if (newbuf == NULL) {
4237 newbuf = gst_buffer_new_and_alloc (sizeof (Wavpack4Header) + blocksize);
4238 gst_buffer_set_caps (newbuf, stream->caps);
4240 gst_buffer_copy_metadata (newbuf, *buf,
4241 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS);
4244 outdata = GST_BUFFER_DATA (newbuf);
4246 GST_BUFFER_SIZE (newbuf) += sizeof (Wavpack4Header) + blocksize;
4247 GST_BUFFER_DATA (newbuf) =
4248 g_realloc (GST_BUFFER_DATA (newbuf), GST_BUFFER_SIZE (newbuf));
4249 GST_BUFFER_MALLOCDATA (newbuf) = GST_BUFFER_DATA (newbuf);
4250 outdata = GST_BUFFER_DATA (newbuf);
4253 outdata[outpos] = 'w';
4254 outdata[outpos + 1] = 'v';
4255 outdata[outpos + 2] = 'p';
4256 outdata[outpos + 3] = 'k';
4259 GST_WRITE_UINT32_LE (outdata + outpos,
4260 blocksize + sizeof (Wavpack4Header) - 8);
4261 GST_WRITE_UINT16_LE (outdata + outpos + 4, wvh.version);
4262 GST_WRITE_UINT8 (outdata + outpos + 6, wvh.track_no);
4263 GST_WRITE_UINT8 (outdata + outpos + 7, wvh.index_no);
4264 GST_WRITE_UINT32_LE (outdata + outpos + 8, wvh.total_samples);
4265 GST_WRITE_UINT32_LE (outdata + outpos + 12, wvh.block_index);
4266 GST_WRITE_UINT32_LE (outdata + outpos + 16, block_samples);
4267 GST_WRITE_UINT32_LE (outdata + outpos + 20, flags);
4268 GST_WRITE_UINT32_LE (outdata + outpos + 24, crc);
4271 g_memmove (outdata + outpos, data, blocksize);
4272 outpos += blocksize;
4276 gst_buffer_unref (*buf);
4278 audiocontext->wvpk_block_index += block_samples;
4284 static GstFlowReturn
4285 gst_matroska_demux_check_subtitle_buffer (GstElement * element,
4286 GstMatroskaTrackContext * stream, GstBuffer ** buf)
4288 GstMatroskaTrackSubtitleContext *sub_stream;
4289 const gchar *encoding, *data;
4295 sub_stream = (GstMatroskaTrackSubtitleContext *) stream;
4297 data = (const gchar *) GST_BUFFER_DATA (*buf);
4298 size = GST_BUFFER_SIZE (*buf);
4300 if (!sub_stream->invalid_utf8) {
4301 if (g_utf8_validate (data, size, NULL)) {
4304 GST_WARNING_OBJECT (element, "subtitle stream %d is not valid UTF-8, this "
4305 "is broken according to the matroska specification", stream->num);
4306 sub_stream->invalid_utf8 = TRUE;
4309 /* file with broken non-UTF8 subtitle, do the best we can do to fix it */
4310 encoding = g_getenv ("GST_SUBTITLE_ENCODING");
4311 if (encoding == NULL || *encoding == '\0') {
4312 /* if local encoding is UTF-8 and no encoding specified
4313 * via the environment variable, assume ISO-8859-15 */
4314 if (g_get_charset (&encoding)) {
4315 encoding = "ISO-8859-15";
4319 utf8 = g_convert_with_fallback (data, size, "UTF-8", encoding, (char *) "*",
4323 GST_LOG_OBJECT (element, "could not convert string from '%s' to UTF-8: %s",
4324 encoding, err->message);
4328 /* invalid input encoding, fall back to ISO-8859-15 (always succeeds) */
4329 encoding = "ISO-8859-15";
4330 utf8 = g_convert_with_fallback (data, size, "UTF-8", encoding, (char *) "*",
4334 GST_LOG_OBJECT (element, "converted subtitle text from %s to UTF-8 %s",
4335 encoding, (err) ? "(using ISO-8859-15 as fallback)" : "");
4338 utf8 = g_strdup ("invalid subtitle");
4340 newbuf = gst_buffer_new ();
4341 GST_BUFFER_MALLOCDATA (newbuf) = (guint8 *) utf8;
4342 GST_BUFFER_DATA (newbuf) = (guint8 *) utf8;
4343 GST_BUFFER_SIZE (newbuf) = strlen (utf8);
4344 gst_buffer_copy_metadata (newbuf, *buf,
4345 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS);
4346 gst_buffer_unref (*buf);
4352 static GstFlowReturn
4353 gst_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux,
4354 GstEbmlRead * ebml, guint64 cluster_time, guint64 cluster_offset,
4355 gboolean is_simpleblock)
4357 GstMatroskaTrackContext *stream = NULL;
4358 GstFlowReturn ret = GST_FLOW_OK;
4359 gboolean readblock = FALSE;
4361 guint64 block_duration = 0;
4362 GstBuffer *buf = NULL;
4363 gint stream_num = -1, n, laces = 0;
4365 gint *lace_size = NULL;
4368 gint64 referenceblock = 0;
4371 offset = gst_ebml_read_get_offset (ebml);
4373 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
4374 if (!is_simpleblock) {
4375 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
4378 id = GST_MATROSKA_ID_SIMPLEBLOCK;
4382 /* one block inside the group. Note, block parsing is one
4383 * of the harder things, so this code is a bit complicated.
4384 * See http://www.matroska.org/ for documentation. */
4385 case GST_MATROSKA_ID_SIMPLEBLOCK:
4386 case GST_MATROSKA_ID_BLOCK:
4392 gst_buffer_unref (buf);
4395 if ((ret = gst_ebml_read_buffer (ebml, &id, &buf)) != GST_FLOW_OK)
4398 data = GST_BUFFER_DATA (buf);
4399 size = GST_BUFFER_SIZE (buf);
4401 /* first byte(s): blocknum */
4402 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0) {
4403 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Data error"));
4404 gst_buffer_unref (buf);
4406 ret = GST_FLOW_ERROR;
4412 /* fetch stream from num */
4413 stream_num = gst_matroska_demux_stream_from_num (demux, num);
4414 if (size < 3 || stream_num < 0 || stream_num >= demux->num_streams) {
4415 gst_buffer_unref (buf);
4417 GST_WARNING_OBJECT (demux, "Invalid stream %d or size %u", stream_num,
4419 ret = GST_FLOW_ERROR;
4423 stream = g_ptr_array_index (demux->src, stream_num);
4425 /* time (relative to cluster time) */
4426 time = ((gint16) GST_READ_UINT16_BE (data));
4429 flags = GST_READ_UINT8 (data);
4433 GST_LOG_OBJECT (demux, "time %" G_GUINT64_FORMAT ", flags %d", time,
4436 switch ((flags & 0x06) >> 1) {
4437 case 0x0: /* no lacing */
4439 lace_size = g_new (gint, 1);
4440 lace_size[0] = size;
4443 case 0x1: /* xiph lacing */
4444 case 0x2: /* fixed-size lacing */
4445 case 0x3: /* EBML lacing */
4447 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4448 ("Invalid lacing size"));
4449 ret = GST_FLOW_ERROR;
4452 laces = GST_READ_UINT8 (data) + 1;
4455 lace_size = g_new0 (gint, laces);
4457 switch ((flags & 0x06) >> 1) {
4458 case 0x1: /* xiph lacing */ {
4459 guint temp, total = 0;
4461 for (n = 0; ret == GST_FLOW_OK && n < laces - 1; n++) {
4464 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4465 ("Invalid lacing size"));
4466 ret = GST_FLOW_ERROR;
4469 temp = GST_READ_UINT8 (data);
4470 lace_size[n] += temp;
4476 total += lace_size[n];
4478 lace_size[n] = size - total;
4482 case 0x2: /* fixed-size lacing */
4483 for (n = 0; n < laces; n++)
4484 lace_size[n] = size / laces;
4487 case 0x3: /* EBML lacing */ {
4490 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0) {
4491 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4493 ret = GST_FLOW_ERROR;
4498 total = lace_size[0] = num;
4499 for (n = 1; ret == GST_FLOW_OK && n < laces - 1; n++) {
4503 if ((r = gst_matroska_ebmlnum_sint (data, size, &snum)) < 0) {
4504 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4506 ret = GST_FLOW_ERROR;
4511 lace_size[n] = lace_size[n - 1] + snum;
4512 total += lace_size[n];
4515 lace_size[n] = size - total;
4522 if (stream->send_xiph_headers) {
4523 ret = gst_matroska_demux_push_xiph_codec_priv_data (demux, stream);
4524 stream->send_xiph_headers = FALSE;
4527 if (stream->send_flac_headers) {
4528 ret = gst_matroska_demux_push_flac_codec_priv_data (demux, stream);
4529 stream->send_flac_headers = FALSE;
4532 if (stream->send_speex_headers) {
4533 ret = gst_matroska_demux_push_speex_codec_priv_data (demux, stream);
4534 stream->send_speex_headers = FALSE;
4537 if (stream->send_dvd_event) {
4538 gst_matroska_demux_push_dvd_clut_change_event (demux, stream);
4539 /* FIXME: should we send this event again after (flushing) seek ? */
4540 stream->send_dvd_event = FALSE;
4543 if (ret != GST_FLOW_OK)
4550 case GST_MATROSKA_ID_BLOCKDURATION:{
4551 ret = gst_ebml_read_uint (ebml, &id, &block_duration);
4552 GST_DEBUG_OBJECT (demux, "BlockDuration: %" G_GUINT64_FORMAT,
4557 case GST_MATROSKA_ID_REFERENCEBLOCK:{
4558 ret = gst_ebml_read_sint (ebml, &id, &referenceblock);
4559 GST_DEBUG_OBJECT (demux, "ReferenceBlock: %" G_GINT64_FORMAT,
4564 case GST_MATROSKA_ID_CODECSTATE:{
4566 guint64 data_len = 0;
4569 gst_ebml_read_binary (ebml, &id, &data,
4570 &data_len)) != GST_FLOW_OK)
4573 if (G_UNLIKELY (stream == NULL)) {
4574 GST_WARNING_OBJECT (demux,
4575 "Unexpected CodecState subelement - ignoring");
4579 g_free (stream->codec_state);
4580 stream->codec_state = data;
4581 stream->codec_state_size = data_len;
4583 /* Decode if necessary */
4584 if (stream->encodings && stream->encodings->len > 0
4585 && stream->codec_state && stream->codec_state_size > 0) {
4586 if (!gst_matroska_decode_data (stream->encodings,
4587 &stream->codec_state, &stream->codec_state_size,
4588 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
4589 GST_WARNING_OBJECT (demux, "Decoding codec state failed");
4593 GST_DEBUG_OBJECT (demux, "CodecState of %u bytes",
4594 stream->codec_state_size);
4599 ret = gst_matroska_demux_parse_skip (demux, ebml, "BlockGroup", id);
4602 case GST_MATROSKA_ID_BLOCKVIRTUAL:
4603 case GST_MATROSKA_ID_BLOCKADDITIONS:
4604 case GST_MATROSKA_ID_REFERENCEPRIORITY:
4605 case GST_MATROSKA_ID_REFERENCEVIRTUAL:
4606 case GST_MATROSKA_ID_SLICES:
4607 GST_DEBUG_OBJECT (demux,
4608 "Skipping BlockGroup subelement 0x%x - ignoring", id);
4609 ret = gst_ebml_read_skip (ebml);
4617 if (ret == GST_FLOW_OK && readblock) {
4618 guint64 duration = 0;
4619 gint64 lace_time = 0;
4621 stream = g_ptr_array_index (demux->src, stream_num);
4623 if (cluster_time != GST_CLOCK_TIME_NONE) {
4624 /* FIXME: What to do with negative timestamps? Give timestamp 0 or -1?
4625 * Drop unless the lace contains timestamp 0? */
4626 if (time < 0 && (-time) > cluster_time) {
4629 if (stream->timecodescale == 1.0)
4630 lace_time = (cluster_time + time) * demux->time_scale;
4633 gst_util_guint64_to_gdouble ((cluster_time + time) *
4634 demux->time_scale) * stream->timecodescale;
4637 lace_time = GST_CLOCK_TIME_NONE;
4640 /* need to refresh segment info ASAP */
4641 if (GST_CLOCK_TIME_IS_VALID (lace_time) && demux->need_newsegment) {
4642 GST_DEBUG_OBJECT (demux,
4643 "generating segment starting at %" GST_TIME_FORMAT,
4644 GST_TIME_ARGS (lace_time));
4645 /* pretend we seeked here */
4646 gst_segment_set_seek (&demux->segment, demux->segment.rate,
4647 GST_FORMAT_TIME, 0, GST_SEEK_TYPE_SET, lace_time,
4648 GST_SEEK_TYPE_SET, GST_CLOCK_TIME_NONE, NULL);
4649 /* now convey our segment notion downstream */
4650 gst_matroska_demux_send_event (demux, gst_event_new_new_segment (FALSE,
4651 demux->segment.rate, demux->segment.format, demux->segment.start,
4652 demux->segment.stop, demux->segment.start));
4653 demux->need_newsegment = FALSE;
4656 if (block_duration) {
4657 if (stream->timecodescale == 1.0)
4658 duration = block_duration * demux->time_scale;
4661 gst_util_gdouble_to_guint64 (gst_util_guint64_to_gdouble
4662 (block_duration * demux->time_scale) * stream->timecodescale);
4663 } else if (stream->default_duration) {
4664 duration = stream->default_duration * laces;
4666 /* else duration is diff between timecode of this and next block */
4667 for (n = 0; n < laces; n++) {
4670 if (G_UNLIKELY (lace_size[n] > size)) {
4671 GST_WARNING_OBJECT (demux, "Invalid lace size");
4675 /* QoS for video track with an index. the assumption is that
4676 index entries point to keyframes, but if that is not true we
4677 will instad skip until the next keyframe. */
4678 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
4679 stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
4680 stream->index_table) {
4681 GstMatroskaTrackVideoContext *videocontext =
4682 (GstMatroskaTrackVideoContext *) stream;
4683 GstClockTime earliest_time;
4684 GstClockTime earliest_stream_time;
4686 GST_OBJECT_LOCK (demux);
4687 earliest_time = videocontext->earliest_time;
4688 GST_OBJECT_UNLOCK (demux);
4689 earliest_stream_time = gst_segment_to_position (&demux->segment,
4690 GST_FORMAT_TIME, earliest_time);
4692 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
4693 GST_CLOCK_TIME_IS_VALID (earliest_stream_time) &&
4694 lace_time <= earliest_stream_time) {
4695 /* find index entry (keyframe) <= earliest_stream_time */
4696 GstMatroskaIndex *entry =
4697 gst_util_array_binary_search (stream->index_table->data,
4698 stream->index_table->len, sizeof (GstMatroskaIndex),
4699 (GCompareDataFunc) gst_matroska_index_seek_find,
4700 GST_SEARCH_MODE_BEFORE, &earliest_stream_time, NULL);
4702 /* if that entry (keyframe) is after the current the current
4703 buffer, we can skip pushing (and thus decoding) all
4704 buffers until that keyframe. */
4705 if (entry && GST_CLOCK_TIME_IS_VALID (entry->time) &&
4706 entry->time > lace_time) {
4707 GST_LOG_OBJECT (demux, "Skipping lace before late keyframe");
4708 stream->set_discont = TRUE;
4714 sub = gst_buffer_create_sub (buf,
4715 GST_BUFFER_SIZE (buf) - size, lace_size[n]);
4716 GST_DEBUG_OBJECT (demux, "created subbuffer %p", sub);
4718 if (stream->encodings != NULL && stream->encodings->len > 0)
4719 sub = gst_matroska_decode_buffer (stream, sub);
4722 GST_WARNING_OBJECT (demux, "Decoding buffer failed");
4726 GST_BUFFER_TIMESTAMP (sub) = lace_time;
4728 if (GST_CLOCK_TIME_IS_VALID (lace_time)) {
4729 GstClockTime last_stop_end;
4731 /* Check if this stream is after segment stop */
4732 if (GST_CLOCK_TIME_IS_VALID (demux->segment.stop) &&
4733 lace_time >= demux->segment.stop) {
4734 GST_DEBUG_OBJECT (demux,
4735 "Stream %d after segment stop %" GST_TIME_FORMAT, stream->index,
4736 GST_TIME_ARGS (demux->segment.stop));
4737 gst_buffer_unref (sub);
4740 if (offset >= stream->to_offset) {
4741 GST_DEBUG_OBJECT (demux, "Stream %d after playback section",
4743 gst_buffer_unref (sub);
4747 /* handle gaps, e.g. non-zero start-time, or an cue index entry
4748 * that landed us with timestamps not quite intended */
4749 if (GST_CLOCK_TIME_IS_VALID (demux->segment.last_stop) &&
4750 demux->segment.rate > 0.0) {
4751 GstClockTimeDiff diff;
4753 /* only send newsegments with increasing start times,
4754 * otherwise if these go back and forth downstream (sinks) increase
4755 * accumulated time and running_time */
4756 diff = GST_CLOCK_DIFF (demux->segment.last_stop, lace_time);
4757 if (diff > 2 * GST_SECOND && lace_time > demux->segment.start &&
4758 (!GST_CLOCK_TIME_IS_VALID (demux->segment.stop) ||
4759 lace_time < demux->segment.stop)) {
4760 GST_DEBUG_OBJECT (demux,
4761 "Gap of %" G_GINT64_FORMAT " ns detected in"
4762 "stream %d (%" GST_TIME_FORMAT " -> %" GST_TIME_FORMAT "). "
4763 "Sending updated NEWSEGMENT events", diff,
4764 stream->index, GST_TIME_ARGS (stream->pos),
4765 GST_TIME_ARGS (lace_time));
4766 /* send newsegment events such that the gap is not accounted in
4767 * accum time, hence running_time */
4768 /* close ahead of gap */
4769 gst_matroska_demux_send_event (demux,
4770 gst_event_new_new_segment (TRUE, demux->segment.rate,
4771 demux->segment.format, demux->segment.last_stop,
4772 demux->segment.last_stop, demux->segment.last_stop));
4774 gst_matroska_demux_send_event (demux,
4775 gst_event_new_new_segment (FALSE, demux->segment.rate,
4776 demux->segment.format, lace_time, demux->segment.stop,
4778 /* align segment view with downstream,
4779 * prevents double-counting accum when closing segment */
4780 gst_segment_set_newsegment (&demux->segment, FALSE,
4781 demux->segment.rate, demux->segment.format, lace_time,
4782 demux->segment.stop, lace_time);
4783 demux->segment.last_stop = lace_time;
4787 if (!GST_CLOCK_TIME_IS_VALID (demux->segment.last_stop)
4788 || demux->segment.last_stop < lace_time) {
4789 demux->segment.last_stop = lace_time;
4792 last_stop_end = lace_time;
4794 GST_BUFFER_DURATION (sub) = duration / laces;
4795 last_stop_end += GST_BUFFER_DURATION (sub);
4798 if (!GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) ||
4799 demux->last_stop_end < last_stop_end)
4800 demux->last_stop_end = last_stop_end;
4802 if (demux->segment.duration == -1 ||
4803 demux->segment.duration < lace_time) {
4804 gst_segment_set_duration (&demux->segment, GST_FORMAT_TIME,
4806 gst_element_post_message (GST_ELEMENT_CAST (demux),
4807 gst_message_new_duration (GST_OBJECT_CAST (demux),
4808 GST_FORMAT_TIME, GST_CLOCK_TIME_NONE));
4812 stream->pos = lace_time;
4814 gst_matroska_demux_sync_streams (demux);
4816 if (is_simpleblock) {
4818 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
4820 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
4822 if (referenceblock) {
4823 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
4825 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
4829 if (GST_BUFFER_FLAG_IS_SET (sub, GST_BUFFER_FLAG_DELTA_UNIT)
4830 && stream->set_discont) {
4831 /* When doing seeks or such, we need to restart on key frames or
4832 * decoders might choke. */
4833 GST_DEBUG_OBJECT (demux, "skipping delta unit");
4834 gst_buffer_unref (sub);
4838 if (stream->set_discont) {
4839 GST_DEBUG_OBJECT (demux, "marking DISCONT");
4840 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DISCONT);
4841 stream->set_discont = FALSE;
4844 /* reverse playback book-keeping */
4845 if (!GST_CLOCK_TIME_IS_VALID (stream->from_time))
4846 stream->from_time = lace_time;
4847 if (stream->from_offset == -1)
4848 stream->from_offset = offset;
4850 GST_DEBUG_OBJECT (demux,
4851 "Pushing lace %d, data of size %d for stream %d, time=%"
4852 GST_TIME_FORMAT " and duration=%" GST_TIME_FORMAT, n,
4853 GST_BUFFER_SIZE (sub), stream_num,
4854 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (sub)),
4855 GST_TIME_ARGS (GST_BUFFER_DURATION (sub)));
4857 if (demux->element_index) {
4858 if (stream->index_writer_id == -1)
4859 gst_index_get_writer_id (demux->element_index,
4860 GST_OBJECT (stream->pad), &stream->index_writer_id);
4862 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
4863 G_GUINT64_FORMAT " for writer id %d",
4864 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (sub)), cluster_offset,
4865 stream->index_writer_id);
4866 gst_index_add_association (demux->element_index,
4867 stream->index_writer_id, GST_BUFFER_FLAG_IS_SET (sub,
4868 GST_BUFFER_FLAG_DELTA_UNIT) ? 0 : GST_ASSOCIATION_FLAG_KEY_UNIT,
4869 GST_FORMAT_TIME, GST_BUFFER_TIMESTAMP (sub), GST_FORMAT_BYTES,
4870 cluster_offset, NULL);
4873 gst_buffer_set_caps (sub, GST_PAD_CAPS (stream->pad));
4875 /* Postprocess the buffers depending on the codec used */
4876 if (stream->postprocess_frame) {
4877 GST_LOG_OBJECT (demux, "running post process");
4878 ret = stream->postprocess_frame (GST_ELEMENT (demux), stream, &sub);
4881 ret = gst_pad_push (stream->pad, sub);
4882 if (demux->segment.rate < 0) {
4883 if (lace_time > demux->segment.stop && ret == GST_FLOW_UNEXPECTED) {
4884 /* In reverse playback we can get a GST_FLOW_UNEXPECTED when
4885 * we are at the end of the segment, so we just need to jump
4886 * back to the previous section. */
4887 GST_DEBUG_OBJECT (demux, "downstream has reached end of segment");
4892 ret = gst_matroska_demux_combine_flows (demux, stream, ret);
4895 size -= lace_size[n];
4896 if (lace_time != GST_CLOCK_TIME_NONE && duration)
4897 lace_time += duration / laces;
4899 lace_time = GST_CLOCK_TIME_NONE;
4905 gst_buffer_unref (buf);
4916 ret = gst_matroska_demux_combine_flows (demux, stream, ret);
4921 /* return FALSE if block(group) should be skipped (due to a seek) */
4922 static inline gboolean
4923 gst_matroska_demux_seek_block (GstMatroskaDemux * demux)
4925 if (G_UNLIKELY (demux->seek_block)) {
4926 if (!(--demux->seek_block)) {
4929 GST_LOG_OBJECT (demux, "should skip block due to seek");
4937 static GstFlowReturn
4938 gst_matroska_demux_parse_contents_seekentry (GstMatroskaDemux * demux,
4942 guint64 seek_pos = (guint64) - 1;
4943 guint32 seek_id = 0;
4946 DEBUG_ELEMENT_START (demux, ebml, "Seek");
4948 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
4949 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
4953 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
4954 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
4958 case GST_MATROSKA_ID_SEEKID:
4962 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
4965 GST_DEBUG_OBJECT (demux, "SeekID: %" G_GUINT64_FORMAT, t);
4970 case GST_MATROSKA_ID_SEEKPOSITION:
4974 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
4977 if (t > G_MAXINT64) {
4978 GST_WARNING_OBJECT (demux,
4979 "Too large SeekPosition %" G_GUINT64_FORMAT, t);
4983 GST_DEBUG_OBJECT (demux, "SeekPosition: %" G_GUINT64_FORMAT, t);
4989 ret = gst_matroska_demux_parse_skip (demux, ebml, "SeekHead", id);
4994 if (ret != GST_FLOW_OK && ret != GST_FLOW_UNEXPECTED)
4997 if (!seek_id || seek_pos == (guint64) - 1) {
4998 GST_WARNING_OBJECT (demux, "Incomplete seekhead entry (0x%x/%"
4999 G_GUINT64_FORMAT ")", seek_id, seek_pos);
5004 case GST_MATROSKA_ID_SEEKHEAD:
5007 case GST_MATROSKA_ID_CUES:
5008 case GST_MATROSKA_ID_TAGS:
5009 case GST_MATROSKA_ID_TRACKS:
5010 case GST_MATROSKA_ID_SEGMENTINFO:
5011 case GST_MATROSKA_ID_ATTACHMENTS:
5012 case GST_MATROSKA_ID_CHAPTERS:
5014 guint64 before_pos, length;
5018 length = gst_matroska_demux_get_length (demux);
5019 before_pos = demux->offset;
5021 /* check for validity */
5022 if (seek_pos + demux->ebml_segment_start + 12 >= length) {
5023 GST_WARNING_OBJECT (demux,
5024 "SeekHead reference lies outside file!" " (%"
5025 G_GUINT64_FORMAT "+%" G_GUINT64_FORMAT "+12 >= %"
5026 G_GUINT64_FORMAT ")", seek_pos, demux->ebml_segment_start, length);
5030 /* only pick up index location when streaming */
5031 if (demux->streaming) {
5032 if (seek_id == GST_MATROSKA_ID_CUES) {
5033 demux->index_offset = seek_pos + demux->ebml_segment_start;
5034 GST_DEBUG_OBJECT (demux, "Cues located at offset %" G_GUINT64_FORMAT,
5035 demux->index_offset);
5041 demux->offset = seek_pos + demux->ebml_segment_start;
5044 if ((ret = gst_matroska_demux_peek_id_length_pull (demux, &id, &length,
5045 &needed)) != GST_FLOW_OK)
5048 if (id != seek_id) {
5049 GST_WARNING_OBJECT (demux,
5050 "We looked for ID=0x%x but got ID=0x%x (pos=%" G_GUINT64_FORMAT ")",
5051 seek_id, id, seek_pos + demux->ebml_segment_start);
5054 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
5059 demux->offset = before_pos;
5064 GST_DEBUG_OBJECT (demux, "Ignoring Seek entry for ID=0x%x", seek_id);
5067 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
5072 static GstFlowReturn
5073 gst_matroska_demux_parse_contents (GstMatroskaDemux * demux, GstEbmlRead * ebml)
5075 GstFlowReturn ret = GST_FLOW_OK;
5078 DEBUG_ELEMENT_START (demux, ebml, "SeekHead");
5080 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
5081 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
5085 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
5086 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
5090 case GST_MATROSKA_ID_SEEKENTRY:
5092 ret = gst_matroska_demux_parse_contents_seekentry (demux, ebml);
5093 /* Ignore EOS and errors here */
5094 if (ret != GST_FLOW_OK) {
5095 GST_DEBUG_OBJECT (demux, "Ignoring %s", gst_flow_get_name (ret));
5102 ret = gst_matroska_demux_parse_skip (demux, ebml, "SeekHead", id);
5107 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
5112 static inline GstFlowReturn
5113 gst_matroska_demux_check_read_size (GstMatroskaDemux * demux, guint64 bytes)
5115 if (G_UNLIKELY (bytes > 10 * 1024 * 1024)) {
5116 /* only a few blocks are expected/allowed to be large,
5117 * and will be recursed into, whereas others will be read and must fit */
5118 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
5119 ("reading large block of size %" G_GUINT64_FORMAT " not supported; "
5120 "file might be corrupt.", bytes));
5121 return GST_FLOW_ERROR;
5127 /* initializes @ebml with @bytes from input stream at current offset.
5128 * Returns UNEXPECTED if insufficient available,
5129 * ERROR if too much was attempted to read. */
5130 static inline GstFlowReturn
5131 gst_matroska_demux_take (GstMatroskaDemux * demux, guint64 bytes,
5134 GstBuffer *buffer = NULL;
5135 GstFlowReturn ret = GST_FLOW_OK;
5137 GST_LOG_OBJECT (demux, "taking %" G_GUINT64_FORMAT " bytes for parsing",
5139 ret = gst_matroska_demux_check_read_size (demux, bytes);
5140 if (ret != GST_FLOW_OK)
5142 if (demux->streaming) {
5143 if (gst_adapter_available (demux->adapter) >= bytes)
5144 buffer = gst_adapter_take_buffer (demux->adapter, bytes);
5146 ret = GST_FLOW_UNEXPECTED;
5148 ret = gst_matroska_demux_peek_bytes (demux, demux->offset, bytes, &buffer,
5150 if (G_LIKELY (buffer)) {
5151 gst_ebml_read_init (ebml, GST_ELEMENT_CAST (demux), buffer, demux->offset);
5152 demux->offset += bytes;
5158 static inline GstFlowReturn
5159 gst_matroska_demux_flush (GstMatroskaDemux * demux, guint flush)
5161 GST_LOG_OBJECT (demux, "skipping %d bytes", flush);
5162 demux->offset += flush;
5163 if (demux->streaming) {
5166 /* hard to skip large blocks when streaming */
5167 ret = gst_matroska_demux_check_read_size (demux, flush);
5168 if (ret != GST_FLOW_OK)
5170 if (flush <= gst_adapter_available (demux->adapter))
5171 gst_adapter_flush (demux->adapter, flush);
5173 return GST_FLOW_UNEXPECTED;
5179 gst_matroska_demux_check_seekability (GstMatroskaDemux * demux)
5182 gboolean seekable = FALSE;
5183 gint64 start = -1, stop = -1;
5185 query = gst_query_new_seeking (GST_FORMAT_BYTES);
5186 if (!gst_pad_peer_query (demux->sinkpad, query)) {
5187 GST_DEBUG_OBJECT (demux, "seeking query failed");
5191 gst_query_parse_seeking (query, NULL, &seekable, &start, &stop);
5193 /* try harder to query upstream size if we didn't get it the first time */
5194 if (seekable && stop == -1) {
5195 GstFormat fmt = GST_FORMAT_BYTES;
5197 GST_DEBUG_OBJECT (demux, "doing duration query to fix up unset stop");
5198 gst_pad_query_peer_duration (demux->sinkpad, &fmt, &stop);
5201 /* if upstream doesn't know the size, it's likely that it's not seekable in
5202 * practice even if it technically may be seekable */
5203 if (seekable && (start != 0 || stop <= start)) {
5204 GST_DEBUG_OBJECT (demux, "seekable but unknown start/stop -> disable");
5209 GST_INFO_OBJECT (demux, "seekable: %d (%" G_GUINT64_FORMAT " - %"
5210 G_GUINT64_FORMAT ")", seekable, start, stop);
5211 demux->seekable = seekable;
5213 gst_query_unref (query);
5216 static GstFlowReturn
5217 gst_matroska_demux_find_tracks (GstMatroskaDemux * demux)
5223 GstFlowReturn ret = GST_FLOW_OK;
5225 GST_WARNING_OBJECT (demux,
5226 "Found Cluster element before Tracks, searching Tracks");
5229 before_pos = demux->offset;
5231 /* Search Tracks element */
5233 ret = gst_matroska_demux_peek_id_length_pull (demux, &id, &length, &needed);
5234 if (ret != GST_FLOW_OK)
5237 if (id != GST_MATROSKA_ID_TRACKS) {
5238 /* we may be skipping large cluster here, so forego size check etc */
5239 /* ... but we can't skip undefined size; force error */
5240 if (length == G_MAXUINT64) {
5241 ret = gst_matroska_demux_check_read_size (demux, length);
5244 demux->offset += needed;
5245 demux->offset += length;
5250 /* will lead to track parsing ... */
5251 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
5256 demux->offset = before_pos;
5261 #define GST_READ_CHECK(stmt) \
5263 if (G_UNLIKELY ((ret = (stmt)) != GST_FLOW_OK)) \
5267 static GstFlowReturn
5268 gst_matroska_demux_parse_id (GstMatroskaDemux * demux, guint32 id,
5269 guint64 length, guint needed)
5271 GstEbmlRead ebml = { 0, };
5272 GstFlowReturn ret = GST_FLOW_OK;
5275 /* if we plan to read and parse this element, we need prefix (id + length)
5276 * and the contents */
5277 /* mind about overflow wrap-around when dealing with undefined size */
5279 if (G_LIKELY (length != G_MAXUINT64))
5282 switch (demux->state) {
5283 case GST_MATROSKA_DEMUX_STATE_START:
5285 case GST_EBML_ID_HEADER:
5286 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5287 ret = gst_matroska_demux_parse_header (demux, &ebml);
5288 if (ret != GST_FLOW_OK)
5290 demux->state = GST_MATROSKA_DEMUX_STATE_SEGMENT;
5291 gst_matroska_demux_check_seekability (demux);
5294 goto invalid_header;
5298 case GST_MATROSKA_DEMUX_STATE_SEGMENT:
5300 case GST_MATROSKA_ID_SEGMENT:
5301 /* eat segment prefix */
5302 GST_READ_CHECK (gst_matroska_demux_flush (demux, needed));
5303 GST_DEBUG_OBJECT (demux,
5304 "Found Segment start at offset %" G_GUINT64_FORMAT,
5306 /* seeks are from the beginning of the segment,
5307 * after the segment ID/length */
5308 demux->ebml_segment_start = demux->offset;
5309 demux->state = GST_MATROSKA_DEMUX_STATE_HEADER;
5312 GST_WARNING_OBJECT (demux,
5313 "Expected a Segment ID (0x%x), but received 0x%x!",
5314 GST_MATROSKA_ID_SEGMENT, id);
5315 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
5319 case GST_MATROSKA_DEMUX_STATE_HEADER:
5320 case GST_MATROSKA_DEMUX_STATE_DATA:
5321 case GST_MATROSKA_DEMUX_STATE_SEEK:
5323 case GST_MATROSKA_ID_SEGMENTINFO:
5324 if (!demux->segmentinfo_parsed) {
5325 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5326 ret = gst_matroska_demux_parse_info (demux, &ebml);
5328 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
5331 case GST_MATROSKA_ID_TRACKS:
5332 if (!demux->tracks_parsed) {
5333 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5334 ret = gst_matroska_demux_parse_tracks (demux, &ebml);
5336 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
5339 case GST_MATROSKA_ID_CLUSTER:
5340 if (G_UNLIKELY (!demux->tracks_parsed)) {
5341 if (demux->streaming) {
5342 GST_DEBUG_OBJECT (demux, "Cluster before Track");
5343 goto not_streamable;
5345 ret = gst_matroska_demux_find_tracks (demux);
5346 if (!demux->tracks_parsed)
5350 if (G_UNLIKELY (demux->state == GST_MATROSKA_DEMUX_STATE_HEADER)) {
5351 demux->state = GST_MATROSKA_DEMUX_STATE_DATA;
5352 GST_DEBUG_OBJECT (demux, "signaling no more pads");
5353 gst_element_no_more_pads (GST_ELEMENT (demux));
5354 /* send initial newsegment */
5355 gst_matroska_demux_send_event (demux,
5356 gst_event_new_new_segment (FALSE, 1.0,
5358 (demux->segment.duration >
5359 0) ? demux->segment.duration : -1, 0));
5361 demux->cluster_time = GST_CLOCK_TIME_NONE;
5362 demux->cluster_offset = demux->offset;
5363 if (G_UNLIKELY (!demux->seek_first && demux->seek_block)) {
5364 GST_DEBUG_OBJECT (demux, "seek target block %" G_GUINT64_FORMAT
5365 " not found in Cluster, trying next Cluster's first block instead",
5367 demux->seek_block = 0;
5369 demux->seek_first = FALSE;
5370 /* eat cluster prefix */
5371 gst_matroska_demux_flush (demux, needed);
5373 case GST_MATROSKA_ID_CLUSTERTIMECODE:
5377 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5378 if ((ret = gst_ebml_read_uint (&ebml, &id, &num)) != GST_FLOW_OK)
5380 GST_DEBUG_OBJECT (demux, "ClusterTimeCode: %" G_GUINT64_FORMAT, num);
5381 demux->cluster_time = num;
5382 if (demux->element_index) {
5383 if (demux->element_index_writer_id == -1)
5384 gst_index_get_writer_id (demux->element_index,
5385 GST_OBJECT (demux), &demux->element_index_writer_id);
5386 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
5387 G_GUINT64_FORMAT " for writer id %d",
5388 GST_TIME_ARGS (demux->cluster_time), demux->cluster_offset,
5389 demux->element_index_writer_id);
5390 gst_index_add_association (demux->element_index,
5391 demux->element_index_writer_id, GST_ASSOCIATION_FLAG_KEY_UNIT,
5392 GST_FORMAT_TIME, demux->cluster_time,
5393 GST_FORMAT_BYTES, demux->cluster_offset, NULL);
5397 case GST_MATROSKA_ID_BLOCKGROUP:
5398 if (!gst_matroska_demux_seek_block (demux))
5400 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5401 DEBUG_ELEMENT_START (demux, &ebml, "BlockGroup");
5402 if ((ret = gst_ebml_read_master (&ebml, &id)) == GST_FLOW_OK) {
5403 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
5404 &ebml, demux->cluster_time, demux->cluster_offset, FALSE);
5406 DEBUG_ELEMENT_STOP (demux, &ebml, "BlockGroup", ret);
5408 case GST_MATROSKA_ID_SIMPLEBLOCK:
5409 if (!gst_matroska_demux_seek_block (demux))
5411 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5412 DEBUG_ELEMENT_START (demux, &ebml, "SimpleBlock");
5413 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
5414 &ebml, demux->cluster_time, demux->cluster_offset, TRUE);
5415 DEBUG_ELEMENT_STOP (demux, &ebml, "SimpleBlock", ret);
5417 case GST_MATROSKA_ID_ATTACHMENTS:
5418 if (!demux->attachments_parsed) {
5419 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5420 ret = gst_matroska_demux_parse_attachments (demux, &ebml);
5422 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
5425 case GST_MATROSKA_ID_TAGS:
5426 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5427 ret = gst_matroska_demux_parse_metadata (demux, &ebml);
5429 case GST_MATROSKA_ID_CHAPTERS:
5430 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5431 ret = gst_matroska_demux_parse_chapters (demux, &ebml);
5433 case GST_MATROSKA_ID_SEEKHEAD:
5434 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5435 ret = gst_matroska_demux_parse_contents (demux, &ebml);
5437 case GST_MATROSKA_ID_CUES:
5438 if (demux->index_parsed) {
5439 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
5442 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5443 ret = gst_matroska_demux_parse_index (demux, &ebml);
5444 /* only push based; delayed index building */
5445 if (demux->state == GST_MATROSKA_DEMUX_STATE_SEEK) {
5448 GST_OBJECT_LOCK (demux);
5449 event = demux->seek_event;
5450 demux->seek_event = NULL;
5451 GST_OBJECT_UNLOCK (demux);
5454 /* unlikely to fail, since we managed to seek to this point */
5455 if (!gst_matroska_demux_handle_seek_event (demux, NULL, event))
5457 /* resume data handling, main thread clear to seek again */
5458 GST_OBJECT_LOCK (demux);
5459 demux->state = GST_MATROSKA_DEMUX_STATE_DATA;
5460 GST_OBJECT_UNLOCK (demux);
5463 case GST_MATROSKA_ID_POSITION:
5464 case GST_MATROSKA_ID_PREVSIZE:
5465 case GST_MATROSKA_ID_ENCRYPTEDBLOCK:
5466 case GST_MATROSKA_ID_SILENTTRACKS:
5467 GST_DEBUG_OBJECT (demux,
5468 "Skipping Cluster subelement 0x%x - ignoring", id);
5472 GST_DEBUG_OBJECT (demux, "skipping Element 0x%x", id);
5473 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
5479 if (ret == GST_FLOW_PARSE)
5483 gst_ebml_read_clear (&ebml);
5489 /* simply exit, maybe not enough data yet */
5490 /* no ebml to clear if read error */
5495 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
5496 ("Failed to parse Element 0x%x", id));
5497 ret = GST_FLOW_ERROR;
5502 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
5503 ("File layout does not permit streaming"));
5504 ret = GST_FLOW_ERROR;
5509 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
5510 ("No Tracks element found"));
5511 ret = GST_FLOW_ERROR;
5516 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Invalid header"));
5517 ret = GST_FLOW_ERROR;
5522 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Failed to seek"));
5523 ret = GST_FLOW_ERROR;
5529 gst_matroska_demux_loop (GstPad * pad)
5531 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (pad));
5537 /* If we have to close a segment, send a new segment to do this now */
5538 if (G_LIKELY (demux->state == GST_MATROSKA_DEMUX_STATE_DATA)) {
5539 if (G_UNLIKELY (demux->close_segment)) {
5540 gst_matroska_demux_send_event (demux, demux->close_segment);
5541 demux->close_segment = NULL;
5543 if (G_UNLIKELY (demux->new_segment)) {
5544 gst_matroska_demux_send_event (demux, demux->new_segment);
5545 demux->new_segment = NULL;
5549 ret = gst_matroska_demux_peek_id_length_pull (demux, &id, &length, &needed);
5550 if (ret == GST_FLOW_UNEXPECTED)
5552 if (ret != GST_FLOW_OK)
5555 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
5556 "size %" G_GUINT64_FORMAT ", needed %d", demux->offset, id,
5559 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
5560 if (ret == GST_FLOW_UNEXPECTED)
5562 if (ret != GST_FLOW_OK)
5565 /* check if we're at the end of a configured segment */
5566 if (G_LIKELY (demux->src->len)) {
5569 g_assert (demux->num_streams == demux->src->len);
5570 for (i = 0; i < demux->src->len; i++) {
5571 GstMatroskaTrackContext *context = g_ptr_array_index (demux->src, i);
5572 GST_DEBUG_OBJECT (context->pad, "pos %" GST_TIME_FORMAT,
5573 GST_TIME_ARGS (context->pos));
5574 if (context->eos == FALSE)
5578 GST_INFO_OBJECT (demux, "All streams are EOS");
5579 ret = GST_FLOW_UNEXPECTED;
5584 if (G_UNLIKELY (demux->offset == gst_matroska_demux_get_length (demux))) {
5585 GST_LOG_OBJECT (demux, "Reached end of stream");
5586 ret = GST_FLOW_UNEXPECTED;
5595 if (demux->segment.rate < 0.0) {
5596 ret = gst_matroska_demux_seek_to_previous_keyframe (demux);
5597 if (ret == GST_FLOW_OK)
5604 const gchar *reason = gst_flow_get_name (ret);
5606 GST_LOG_OBJECT (demux, "pausing task, reason %s", reason);
5607 demux->segment_running = FALSE;
5608 gst_pad_pause_task (demux->sinkpad);
5610 if (GST_FLOW_IS_FATAL (ret) || ret == GST_FLOW_NOT_LINKED) {
5611 gboolean push_eos = TRUE;
5613 if (ret == GST_FLOW_UNEXPECTED) {
5614 /* perform EOS logic */
5616 /* Close the segment, i.e. update segment stop with the duration
5617 * if no stop was set */
5618 if (GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) &&
5619 !GST_CLOCK_TIME_IS_VALID (demux->segment.stop)) {
5621 gst_event_new_new_segment_full (TRUE, demux->segment.rate,
5622 demux->segment.applied_rate, demux->segment.format,
5623 demux->segment.start,
5624 MAX (demux->last_stop_end, demux->segment.start),
5625 demux->segment.time);
5626 gst_matroska_demux_send_event (demux, event);
5629 if (demux->segment.flags & GST_SEEK_FLAG_SEGMENT) {
5632 /* for segment playback we need to post when (in stream time)
5633 * we stopped, this is either stop (when set) or the duration. */
5634 if ((stop = demux->segment.stop) == -1)
5635 stop = demux->last_stop_end;
5637 GST_LOG_OBJECT (demux, "Sending segment done, at end of segment");
5638 gst_element_post_message (GST_ELEMENT (demux),
5639 gst_message_new_segment_done (GST_OBJECT (demux), GST_FORMAT_TIME,
5644 /* for fatal errors we post an error message */
5645 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
5646 ("stream stopped, reason %s", reason));
5649 /* send EOS, and prevent hanging if no streams yet */
5650 GST_LOG_OBJECT (demux, "Sending EOS, at end of stream");
5651 if (!gst_matroska_demux_send_event (demux, gst_event_new_eos ()) &&
5652 (ret == GST_FLOW_UNEXPECTED)) {
5653 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
5654 (NULL), ("got eos but no streams (yet)"));
5663 * Create and push a flushing seek event upstream
5666 perform_seek_to_offset (GstMatroskaDemux * demux, guint64 offset)
5671 GST_DEBUG_OBJECT (demux, "Seeking to %" G_GUINT64_FORMAT, offset);
5674 gst_event_new_seek (1.0, GST_FORMAT_BYTES,
5675 GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, GST_SEEK_TYPE_SET, offset,
5676 GST_SEEK_TYPE_NONE, -1);
5678 res = gst_pad_push_event (demux->sinkpad, event);
5680 /* newsegment event will update offset */
5684 static const guint8 *
5685 gst_matroska_demux_peek_adapter (GstMatroskaDemux * demux, guint peek)
5687 return gst_adapter_peek (demux->adapter, peek);
5690 static GstFlowReturn
5691 gst_matroska_demux_peek_id_length_push (GstMatroskaDemux * demux, guint32 * _id,
5692 guint64 * _length, guint * _needed)
5694 return gst_ebml_peek_id_length (_id, _length, _needed,
5695 (GstPeekData) gst_matroska_demux_peek_adapter, (gpointer) demux,
5696 GST_ELEMENT_CAST (demux), demux->offset);
5699 static GstFlowReturn
5700 gst_matroska_demux_chain (GstPad * pad, GstBuffer * buffer)
5702 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (pad));
5704 GstFlowReturn ret = GST_FLOW_OK;
5709 if (G_UNLIKELY (GST_BUFFER_IS_DISCONT (buffer))) {
5710 GST_DEBUG_OBJECT (demux, "got DISCONT");
5711 gst_adapter_clear (demux->adapter);
5712 GST_OBJECT_LOCK (demux);
5713 gst_matroska_demux_reset_streams (demux, GST_CLOCK_TIME_NONE, FALSE);
5714 GST_OBJECT_UNLOCK (demux);
5717 gst_adapter_push (demux->adapter, buffer);
5721 available = gst_adapter_available (demux->adapter);
5723 ret = gst_matroska_demux_peek_id_length_push (demux, &id, &length, &needed);
5724 if (G_UNLIKELY (ret != GST_FLOW_OK && ret != GST_FLOW_UNEXPECTED))
5727 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
5728 "size %" G_GUINT64_FORMAT ", needed %d, available %d", demux->offset, id,
5729 length, needed, available);
5731 if (needed > available)
5734 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
5735 if (ret == GST_FLOW_UNEXPECTED) {
5736 /* need more data */
5738 } else if (ret != GST_FLOW_OK) {
5745 gst_matroska_demux_handle_sink_event (GstPad * pad, GstEvent * event)
5747 gboolean res = TRUE;
5748 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (pad));
5750 GST_DEBUG_OBJECT (demux,
5751 "have event type %s: %p on sink pad", GST_EVENT_TYPE_NAME (event), event);
5753 switch (GST_EVENT_TYPE (event)) {
5754 case GST_EVENT_NEWSEGMENT:
5757 gdouble rate, arate;
5758 gint64 start, stop, time = 0;
5762 /* some debug output */
5763 gst_segment_init (&segment, GST_FORMAT_UNDEFINED);
5764 gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format,
5765 &start, &stop, &time);
5766 gst_segment_set_newsegment_full (&segment, update, rate, arate, format,
5768 GST_DEBUG_OBJECT (demux,
5769 "received format %d newsegment %" GST_SEGMENT_FORMAT, format,
5772 if (demux->state < GST_MATROSKA_DEMUX_STATE_DATA) {
5773 GST_DEBUG_OBJECT (demux, "still starting");
5777 /* we only expect a BYTE segment, e.g. following a seek */
5778 if (format != GST_FORMAT_BYTES) {
5779 GST_DEBUG_OBJECT (demux, "unsupported segment format, ignoring");
5783 GST_DEBUG_OBJECT (demux, "clearing segment state");
5784 /* clear current segment leftover */
5785 gst_adapter_clear (demux->adapter);
5786 /* and some streaming setup */
5787 demux->offset = start;
5788 /* do not know where we are;
5789 * need to come across a cluster and generate newsegment */
5790 demux->segment.last_stop = GST_CLOCK_TIME_NONE;
5791 demux->cluster_time = GST_CLOCK_TIME_NONE;
5792 demux->cluster_offset = 0;
5793 demux->need_newsegment = TRUE;
5794 /* but keep some of the upstream segment */
5795 demux->segment.rate = rate;
5797 /* chain will send initial newsegment after pads have been added,
5798 * or otherwise come up with one */
5799 GST_DEBUG_OBJECT (demux, "eating event");
5800 gst_event_unref (event);
5806 if (demux->state != GST_MATROSKA_DEMUX_STATE_DATA) {
5807 gst_event_unref (event);
5808 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
5809 (NULL), ("got eos and didn't receive a complete header object"));
5810 } else if (demux->num_streams == 0) {
5811 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
5812 (NULL), ("got eos but no streams (yet)"));
5814 gst_matroska_demux_send_event (demux, event);
5818 case GST_EVENT_FLUSH_STOP:
5820 gst_adapter_clear (demux->adapter);
5821 GST_OBJECT_LOCK (demux);
5822 gst_matroska_demux_reset_streams (demux, GST_CLOCK_TIME_NONE, TRUE);
5823 GST_OBJECT_UNLOCK (demux);
5824 demux->segment.last_stop = GST_CLOCK_TIME_NONE;
5825 demux->cluster_time = GST_CLOCK_TIME_NONE;
5826 demux->cluster_offset = 0;
5830 res = gst_pad_event_default (pad, event);
5838 gst_matroska_demux_sink_activate (GstPad * sinkpad)
5840 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (sinkpad));
5842 if (gst_pad_check_pull_range (sinkpad)) {
5843 GST_DEBUG ("going to pull mode");
5844 demux->streaming = FALSE;
5845 return gst_pad_activate_pull (sinkpad, TRUE);
5847 GST_DEBUG ("going to push (streaming) mode");
5848 demux->streaming = TRUE;
5849 return gst_pad_activate_push (sinkpad, TRUE);
5856 gst_matroska_demux_sink_activate_pull (GstPad * sinkpad, gboolean active)
5858 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (sinkpad));
5861 /* if we have a scheduler we can start the task */
5862 demux->segment_running = TRUE;
5863 gst_pad_start_task (sinkpad, (GstTaskFunction) gst_matroska_demux_loop,
5866 demux->segment_running = FALSE;
5867 gst_pad_stop_task (sinkpad);
5874 * XXX: This code is duplicated in gst/qtdemux/qtdemux.c. Please replicate any
5875 * changes you make over there as well.
5878 avc_profile_idc_to_string (guint profile_idc, guint constraint_set_flags)
5880 const gchar *profile = NULL;
5883 csf1 = (constraint_set_flags & 0x40) >> 6;
5884 csf3 = (constraint_set_flags & 0x10) >> 4;
5886 switch (profile_idc) {
5889 profile = "constrained-baseline";
5891 profile = "baseline";
5897 profile = "extended";
5904 profile = "high-10-intra";
5906 profile = "high-10";
5910 profile = "high-4:2:2-intra";
5912 profile = "high-4:2:2";
5916 profile = "high-4:4:4-intra";
5918 profile = "high-4:4:4";
5921 profile = "cavlc-4:4:4-intra";
5927 return g_strdup (profile);
5931 avc_level_idc_to_string (guint level_idc, guint constraint_set_flags)
5935 csf3 = (constraint_set_flags & 0x10) >> 4;
5937 if (level_idc == 11 && csf3)
5938 return g_strdup ("1b");
5939 else if (level_idc % 10 == 0)
5940 return g_strdup_printf ("%u", level_idc / 10);
5942 return g_strdup_printf ("%u.%u", level_idc / 10, level_idc % 10);
5946 avc_get_profile_and_level_string (const guint8 * avc_data, gint size,
5947 gchar ** profile, gchar ** level)
5950 /* First byte is the version, second is the profile indication,
5951 * and third is the 5 contraint_set_flags and 3 reserved bits */
5952 *profile = avc_profile_idc_to_string (GST_READ_UINT8 (avc_data + 1),
5953 GST_READ_UINT8 (avc_data + 2));
5956 /* Fourth byte is the level indication */
5957 *level = avc_level_idc_to_string (GST_READ_UINT8 (avc_data + 3),
5958 GST_READ_UINT8 (avc_data + 2));
5962 gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext *
5963 videocontext, const gchar * codec_id, guint8 * data, guint size,
5964 gchar ** codec_name)
5966 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) videocontext;
5967 GstCaps *caps = NULL;
5969 g_assert (videocontext != NULL);
5970 g_assert (codec_name != NULL);
5972 context->send_xiph_headers = FALSE;
5973 context->send_flac_headers = FALSE;
5974 context->send_speex_headers = FALSE;
5976 /* TODO: check if we have all codec types from matroska-ids.h
5977 * check if we have to do more special things with codec_private
5980 * GST_MATROSKA_CODEC_ID_VIDEO_QUICKTIME
5981 * GST_MATROSKA_CODEC_ID_VIDEO_SNOW
5984 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VFW_FOURCC)) {
5985 gst_riff_strf_vids *vids = NULL;
5988 GstBuffer *buf = NULL;
5990 vids = (gst_riff_strf_vids *) data;
5992 /* assure size is big enough */
5994 GST_WARNING ("Too small BITMAPINFOHEADER (%d bytes)", size);
5997 if (size < sizeof (gst_riff_strf_vids)) {
5998 vids = g_new (gst_riff_strf_vids, 1);
5999 memcpy (vids, data, size);
6002 /* little-endian -> byte-order */
6003 vids->size = GUINT32_FROM_LE (vids->size);
6004 vids->width = GUINT32_FROM_LE (vids->width);
6005 vids->height = GUINT32_FROM_LE (vids->height);
6006 vids->planes = GUINT16_FROM_LE (vids->planes);
6007 vids->bit_cnt = GUINT16_FROM_LE (vids->bit_cnt);
6008 vids->compression = GUINT32_FROM_LE (vids->compression);
6009 vids->image_size = GUINT32_FROM_LE (vids->image_size);
6010 vids->xpels_meter = GUINT32_FROM_LE (vids->xpels_meter);
6011 vids->ypels_meter = GUINT32_FROM_LE (vids->ypels_meter);
6012 vids->num_colors = GUINT32_FROM_LE (vids->num_colors);
6013 vids->imp_colors = GUINT32_FROM_LE (vids->imp_colors);
6015 if (size > sizeof (gst_riff_strf_vids)) { /* some extra_data */
6016 buf = gst_buffer_new_and_alloc (size - sizeof (gst_riff_strf_vids));
6017 memcpy (GST_BUFFER_DATA (buf),
6018 (guint8 *) vids + sizeof (gst_riff_strf_vids),
6019 GST_BUFFER_SIZE (buf));
6022 caps = gst_riff_create_video_caps (vids->compression, NULL, vids,
6023 buf, NULL, codec_name);
6026 gst_buffer_unref (buf);
6028 if (vids != (gst_riff_strf_vids *) data)
6031 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_UNCOMPRESSED)) {
6034 switch (videocontext->fourcc) {
6035 case GST_MAKE_FOURCC ('I', '4', '2', '0'):
6036 *codec_name = g_strdup ("Raw planar YUV 4:2:0");
6037 fourcc = videocontext->fourcc;
6039 case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
6040 *codec_name = g_strdup ("Raw packed YUV 4:2:2");
6041 fourcc = videocontext->fourcc;
6043 case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
6044 *codec_name = g_strdup ("Raw packed YUV 4:2:0");
6045 fourcc = videocontext->fourcc;
6047 case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
6048 *codec_name = g_strdup ("Raw packed YUV 4:2:2");
6049 fourcc = videocontext->fourcc;
6051 case GST_MAKE_FOURCC ('A', 'Y', 'U', 'V'):
6052 *codec_name = g_strdup ("Raw packed YUV 4:4:4 with alpha channel");
6053 fourcc = videocontext->fourcc;
6057 GST_DEBUG ("Unknown fourcc %" GST_FOURCC_FORMAT,
6058 GST_FOURCC_ARGS (videocontext->fourcc));
6062 caps = gst_caps_new_simple ("video/x-raw-yuv",
6063 "format", GST_TYPE_FOURCC, fourcc, NULL);
6064 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_SP)) {
6065 caps = gst_caps_new_simple ("video/x-divx",
6066 "divxversion", G_TYPE_INT, 4, NULL);
6067 *codec_name = g_strdup ("MPEG-4 simple profile");
6068 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP) ||
6069 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AP)) {
6071 caps = gst_caps_new_full (gst_structure_new ("video/x-divx",
6072 "divxversion", G_TYPE_INT, 5, NULL),
6073 gst_structure_new ("video/x-xvid", NULL),
6074 gst_structure_new ("video/mpeg",
6075 "mpegversion", G_TYPE_INT, 4,
6076 "systemstream", G_TYPE_BOOLEAN, FALSE, NULL), NULL);
6078 caps = gst_caps_new_simple ("video/mpeg",
6079 "mpegversion", G_TYPE_INT, 4,
6080 "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
6082 GstBuffer *priv = gst_buffer_new_and_alloc (size);
6084 memcpy (GST_BUFFER_DATA (priv), data, size);
6085 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
6086 gst_buffer_unref (priv);
6088 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP))
6089 *codec_name = g_strdup ("MPEG-4 advanced simple profile");
6091 *codec_name = g_strdup ("MPEG-4 advanced profile");
6092 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MSMPEG4V3)) {
6094 caps = gst_caps_new_full (gst_structure_new ("video/x-divx",
6095 "divxversion", G_TYPE_INT, 3, NULL),
6096 gst_structure_new ("video/x-msmpeg",
6097 "msmpegversion", G_TYPE_INT, 43, NULL), NULL);
6099 caps = gst_caps_new_simple ("video/x-msmpeg",
6100 "msmpegversion", G_TYPE_INT, 43, NULL);
6101 *codec_name = g_strdup ("Microsoft MPEG-4 v.3");
6102 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1) ||
6103 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG2)) {
6104 gint mpegversion = -1;
6106 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1))
6108 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG2))
6111 g_assert_not_reached ();
6113 caps = gst_caps_new_simple ("video/mpeg",
6114 "systemstream", G_TYPE_BOOLEAN, FALSE,
6115 "mpegversion", G_TYPE_INT, mpegversion, NULL);
6116 *codec_name = g_strdup_printf ("MPEG-%d video", mpegversion);
6117 context->postprocess_frame = gst_matroska_demux_add_mpeg_seq_header;
6118 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MJPEG)) {
6119 caps = gst_caps_new_simple ("image/jpeg", NULL);
6120 *codec_name = g_strdup ("Motion-JPEG");
6121 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AVC)) {
6122 caps = gst_caps_new_simple ("video/x-h264", NULL);
6124 GstBuffer *priv = gst_buffer_new_and_alloc (size);
6125 gchar *profile = NULL, *level = NULL;
6127 avc_get_profile_and_level_string (data, size, &profile, &level);
6129 gst_caps_set_simple (caps, "profile", G_TYPE_STRING, profile, NULL);
6133 gst_caps_set_simple (caps, "level", G_TYPE_STRING, level, NULL);
6137 memcpy (GST_BUFFER_DATA (priv), data, size);
6138 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
6139 gst_buffer_unref (priv);
6142 *codec_name = g_strdup ("H264");
6143 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1)) ||
6144 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2)) ||
6145 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3)) ||
6146 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))) {
6147 gint rmversion = -1;
6149 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1))
6151 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2))
6153 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3))
6155 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))
6158 caps = gst_caps_new_simple ("video/x-pn-realvideo",
6159 "rmversion", G_TYPE_INT, rmversion, NULL);
6160 GST_DEBUG ("data:%p, size:0x%x", data, size);
6161 /* We need to extract the extradata ! */
6162 if (data && (size >= 0x22)) {
6167 subformat = GST_READ_UINT32_BE (data + 0x1a);
6168 rformat = GST_READ_UINT32_BE (data + 0x1e);
6170 priv = gst_buffer_new_and_alloc (size - 0x1a);
6172 memcpy (GST_BUFFER_DATA (priv), data + 0x1a, size - 0x1a);
6173 gst_caps_set_simple (caps,
6174 "codec_data", GST_TYPE_BUFFER, priv,
6175 "format", G_TYPE_INT, rformat,
6176 "subformat", G_TYPE_INT, subformat, NULL);
6177 gst_buffer_unref (priv);
6180 *codec_name = g_strdup_printf ("RealVideo %d.0", rmversion);
6181 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_THEORA)) {
6182 caps = gst_caps_new_simple ("video/x-theora", NULL);
6183 context->send_xiph_headers = TRUE;
6184 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_DIRAC)) {
6185 caps = gst_caps_new_simple ("video/x-dirac", NULL);
6186 context->send_xiph_headers = FALSE;
6187 *codec_name = g_strdup_printf ("Dirac");
6188 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8)) {
6189 caps = gst_caps_new_simple ("video/x-vp8", NULL);
6190 *codec_name = g_strdup_printf ("On2 VP8");
6192 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
6198 GstStructure *structure;
6200 for (i = 0; i < gst_caps_get_size (caps); i++) {
6201 structure = gst_caps_get_structure (caps, i);
6203 /* FIXME: use the real unit here! */
6204 GST_DEBUG ("video size %dx%d, target display size %dx%d (any unit)",
6205 videocontext->pixel_width,
6206 videocontext->pixel_height,
6207 videocontext->display_width, videocontext->display_height);
6209 /* pixel width and height are the w and h of the video in pixels */
6210 if (videocontext->pixel_width > 0 && videocontext->pixel_height > 0) {
6211 gint w = videocontext->pixel_width;
6213 gint h = videocontext->pixel_height;
6215 gst_structure_set (structure,
6216 "width", G_TYPE_INT, w, "height", G_TYPE_INT, h, NULL);
6219 if (videocontext->display_width > 0 && videocontext->display_height > 0) {
6222 /* calculate the pixel aspect ratio using the display and pixel w/h */
6223 n = videocontext->display_width * videocontext->pixel_height;
6224 d = videocontext->display_height * videocontext->pixel_width;
6225 GST_DEBUG ("setting PAR to %d/%d", n, d);
6226 gst_structure_set (structure, "pixel-aspect-ratio",
6228 videocontext->display_width * videocontext->pixel_height,
6229 videocontext->display_height * videocontext->pixel_width, NULL);
6232 if (videocontext->default_fps > 0.0) {
6233 GValue fps_double = { 0, };
6234 GValue fps_fraction = { 0, };
6236 g_value_init (&fps_double, G_TYPE_DOUBLE);
6237 g_value_init (&fps_fraction, GST_TYPE_FRACTION);
6238 g_value_set_double (&fps_double, videocontext->default_fps);
6239 g_value_transform (&fps_double, &fps_fraction);
6241 GST_DEBUG ("using default fps %f", videocontext->default_fps);
6243 gst_structure_set_value (structure, "framerate", &fps_fraction);
6244 g_value_unset (&fps_double);
6245 g_value_unset (&fps_fraction);
6246 } else if (context->default_duration > 0) {
6247 GValue fps_double = { 0, };
6248 GValue fps_fraction = { 0, };
6250 g_value_init (&fps_double, G_TYPE_DOUBLE);
6251 g_value_init (&fps_fraction, GST_TYPE_FRACTION);
6252 g_value_set_double (&fps_double, (gdouble) GST_SECOND /
6253 gst_guint64_to_gdouble (context->default_duration));
6254 g_value_transform (&fps_double, &fps_fraction);
6256 GST_DEBUG ("using default duration %" G_GUINT64_FORMAT,
6257 context->default_duration);
6259 gst_structure_set_value (structure, "framerate", &fps_fraction);
6260 g_value_unset (&fps_double);
6261 g_value_unset (&fps_fraction);
6263 /* sort of a hack to get most codecs to support,
6264 * even if the default_duration is missing */
6265 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
6269 if (videocontext->parent.flags & GST_MATROSKA_VIDEOTRACK_INTERLACED)
6270 gst_structure_set (structure, "interlaced", G_TYPE_BOOLEAN, TRUE, NULL);
6273 gst_caps_do_simplify (caps);
6280 * Some AAC specific code... *sigh*
6281 * FIXME: maybe we should use '15' and code the sample rate explicitly
6282 * if the sample rate doesn't match the predefined rates exactly? (tpm)
6286 aac_rate_idx (gint rate)
6290 else if (75132 <= rate)
6292 else if (55426 <= rate)
6294 else if (46009 <= rate)
6296 else if (37566 <= rate)
6298 else if (27713 <= rate)
6300 else if (23004 <= rate)
6302 else if (18783 <= rate)
6304 else if (13856 <= rate)
6306 else if (11502 <= rate)
6308 else if (9391 <= rate)
6315 aac_profile_idx (const gchar * codec_id)
6319 if (strlen (codec_id) <= 12)
6321 else if (!strncmp (&codec_id[12], "MAIN", 4))
6323 else if (!strncmp (&codec_id[12], "LC", 2))
6325 else if (!strncmp (&codec_id[12], "SSR", 3))
6333 #define AAC_SYNC_EXTENSION_TYPE 0x02b7
6336 gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext *
6337 audiocontext, const gchar * codec_id, guint8 * data, guint size,
6338 gchar ** codec_name)
6340 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) audiocontext;
6341 GstCaps *caps = NULL;
6343 g_assert (audiocontext != NULL);
6344 g_assert (codec_name != NULL);
6346 context->send_xiph_headers = FALSE;
6347 context->send_flac_headers = FALSE;
6348 context->send_speex_headers = FALSE;
6350 /* TODO: check if we have all codec types from matroska-ids.h
6351 * check if we have to do more special things with codec_private
6352 * check if we need bitdepth in different places too
6353 * implement channel position magic
6355 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID9
6356 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID10
6357 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDMC
6358 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDM2
6361 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1) ||
6362 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2) ||
6363 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L3)) {
6366 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1))
6368 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2))
6370 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L3))
6373 g_assert_not_reached ();
6375 caps = gst_caps_new_simple ("audio/mpeg",
6376 "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, layer, NULL);
6377 *codec_name = g_strdup_printf ("MPEG-1 layer %d", layer);
6378 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE) ||
6379 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_LE)) {
6380 gint endianness = -1;
6382 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE))
6383 endianness = G_BIG_ENDIAN;
6384 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_LE))
6385 endianness = G_LITTLE_ENDIAN;
6387 g_assert_not_reached ();
6389 caps = gst_caps_new_simple ("audio/x-raw-int",
6390 "width", G_TYPE_INT, audiocontext->bitdepth,
6391 "depth", G_TYPE_INT, audiocontext->bitdepth,
6392 "signed", G_TYPE_BOOLEAN, audiocontext->bitdepth != 8,
6393 "endianness", G_TYPE_INT, endianness, NULL);
6395 *codec_name = g_strdup_printf ("Raw %d-bit PCM audio",
6396 audiocontext->bitdepth);
6397 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_FLOAT)) {
6398 caps = gst_caps_new_simple ("audio/x-raw-float",
6399 "endianness", G_TYPE_INT, G_LITTLE_ENDIAN,
6400 "width", G_TYPE_INT, audiocontext->bitdepth, NULL);
6401 *codec_name = g_strdup_printf ("Raw %d-bit floating-point audio",
6402 audiocontext->bitdepth);
6403 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AC3,
6404 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AC3))) {
6405 caps = gst_caps_new_simple ("audio/x-ac3", NULL);
6406 *codec_name = g_strdup ("AC-3 audio");
6407 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_EAC3,
6408 strlen (GST_MATROSKA_CODEC_ID_AUDIO_EAC3))) {
6409 caps = gst_caps_new_simple ("audio/x-eac3", NULL);
6410 *codec_name = g_strdup ("E-AC-3 audio");
6411 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_DTS)) {
6412 caps = gst_caps_new_simple ("audio/x-dts", NULL);
6413 *codec_name = g_strdup ("DTS audio");
6414 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_VORBIS)) {
6415 caps = gst_caps_new_simple ("audio/x-vorbis", NULL);
6416 context->send_xiph_headers = TRUE;
6417 /* vorbis decoder does tags */
6418 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_FLAC)) {
6419 caps = gst_caps_new_simple ("audio/x-flac", NULL);
6420 context->send_flac_headers = TRUE;
6421 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_SPEEX)) {
6422 caps = gst_caps_new_simple ("audio/x-speex", NULL);
6423 context->send_speex_headers = TRUE;
6424 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_ACM)) {
6425 gst_riff_strf_auds auds;
6428 GstBuffer *codec_data = gst_buffer_new ();
6430 /* little-endian -> byte-order */
6431 auds.format = GST_READ_UINT16_LE (data);
6432 auds.channels = GST_READ_UINT16_LE (data + 2);
6433 auds.rate = GST_READ_UINT32_LE (data + 4);
6434 auds.av_bps = GST_READ_UINT32_LE (data + 8);
6435 auds.blockalign = GST_READ_UINT16_LE (data + 12);
6436 auds.size = GST_READ_UINT16_LE (data + 16);
6438 /* 18 is the waveformatex size */
6439 gst_buffer_set_data (codec_data, data + 18, auds.size);
6441 caps = gst_riff_create_audio_caps (auds.format, NULL, &auds, NULL,
6442 codec_data, codec_name);
6443 gst_buffer_unref (codec_data);
6445 } else if (g_str_has_prefix (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC)) {
6446 GstBuffer *priv = NULL;
6447 gint mpegversion = -1;
6448 gint rate_idx, profile;
6449 guint8 *data = NULL;
6451 /* unspecified AAC profile with opaque private codec data */
6452 if (strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC) == 0) {
6453 if (context->codec_priv_size >= 2) {
6454 guint obj_type, freq_index, explicit_freq_bytes = 0;
6456 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
6457 freq_index = (GST_READ_UINT16_BE (context->codec_priv) & 0x780) >> 7;
6458 obj_type = (GST_READ_UINT16_BE (context->codec_priv) & 0xF800) >> 11;
6459 if (freq_index == 15)
6460 explicit_freq_bytes = 3;
6461 GST_DEBUG ("obj_type = %u, freq_index = %u", obj_type, freq_index);
6462 priv = gst_buffer_new_and_alloc (context->codec_priv_size);
6463 memcpy (GST_BUFFER_DATA (priv), context->codec_priv,
6464 context->codec_priv_size);
6465 /* assume SBR if samplerate <= 24kHz */
6466 if (obj_type == 5 || (freq_index >= 6 && freq_index != 15) ||
6467 (context->codec_priv_size == (5 + explicit_freq_bytes))) {
6468 audiocontext->samplerate *= 2;
6471 GST_WARNING ("Opaque A_AAC codec ID, but no codec private data");
6472 /* just try this and see what happens ... */
6473 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
6477 /* make up decoder-specific data if it is not supplied */
6479 priv = gst_buffer_new_and_alloc (5);
6480 data = GST_BUFFER_DATA (priv);
6481 rate_idx = aac_rate_idx (audiocontext->samplerate);
6482 profile = aac_profile_idx (codec_id);
6484 data[0] = ((profile + 1) << 3) | ((rate_idx & 0xE) >> 1);
6485 data[1] = ((rate_idx & 0x1) << 7) | (audiocontext->channels << 3);
6486 GST_BUFFER_SIZE (priv) = 2;
6489 if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2,
6490 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2))) {
6492 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4,
6493 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4))) {
6496 if (g_strrstr (codec_id, "SBR")) {
6497 /* HE-AAC (aka SBR AAC) */
6498 audiocontext->samplerate *= 2;
6499 rate_idx = aac_rate_idx (audiocontext->samplerate);
6500 data[2] = AAC_SYNC_EXTENSION_TYPE >> 3;
6501 data[3] = ((AAC_SYNC_EXTENSION_TYPE & 0x07) << 5) | 5;
6502 data[4] = (1 << 7) | (rate_idx << 3);
6503 GST_BUFFER_SIZE (priv) = 5;
6506 g_assert_not_reached ();
6509 caps = gst_caps_new_simple ("audio/mpeg",
6510 "mpegversion", G_TYPE_INT, mpegversion,
6511 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
6513 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
6515 *codec_name = g_strdup_printf ("MPEG-%d AAC audio", mpegversion);
6516 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TTA)) {
6517 caps = gst_caps_new_simple ("audio/x-tta",
6518 "width", G_TYPE_INT, audiocontext->bitdepth, NULL);
6519 *codec_name = g_strdup ("TTA audio");
6520 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_WAVPACK4)) {
6521 caps = gst_caps_new_simple ("audio/x-wavpack",
6522 "width", G_TYPE_INT, audiocontext->bitdepth,
6523 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
6524 *codec_name = g_strdup ("Wavpack audio");
6525 context->postprocess_frame = gst_matroska_demux_add_wvpk_header;
6526 audiocontext->wvpk_block_index = 0;
6527 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4)) ||
6528 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4)) ||
6529 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))) {
6530 gint raversion = -1;
6532 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4))
6534 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))
6539 caps = gst_caps_new_simple ("audio/x-pn-realaudio",
6540 "raversion", G_TYPE_INT, raversion, NULL);
6541 /* Extract extra information from caps, mapping varies based on codec */
6542 if (data && (size >= 0x50)) {
6549 guint extra_data_size;
6551 GST_ERROR ("real audio raversion:%d", raversion);
6552 if (raversion == 8) {
6554 flavor = GST_READ_UINT16_BE (data + 22);
6555 packet_size = GST_READ_UINT32_BE (data + 24);
6556 height = GST_READ_UINT16_BE (data + 40);
6557 leaf_size = GST_READ_UINT16_BE (data + 44);
6558 sample_width = GST_READ_UINT16_BE (data + 58);
6559 extra_data_size = GST_READ_UINT32_BE (data + 74);
6562 ("flavor:%d, packet_size:%d, height:%d, leaf_size:%d, sample_width:%d, extra_data_size:%d",
6563 flavor, packet_size, height, leaf_size, sample_width,
6565 gst_caps_set_simple (caps, "flavor", G_TYPE_INT, flavor, "packet_size",
6566 G_TYPE_INT, packet_size, "height", G_TYPE_INT, height, "leaf_size",
6567 G_TYPE_INT, leaf_size, "width", G_TYPE_INT, sample_width, NULL);
6569 if ((size - 78) >= extra_data_size) {
6570 priv = gst_buffer_new_and_alloc (extra_data_size);
6571 memcpy (GST_BUFFER_DATA (priv), data + 78, extra_data_size);
6572 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
6573 gst_buffer_unref (priv);
6578 *codec_name = g_strdup_printf ("RealAudio %d.0", raversion);
6579 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_SIPR)) {
6580 caps = gst_caps_new_simple ("audio/x-sipro", NULL);
6581 *codec_name = g_strdup ("Sipro/ACELP.NET Voice Codec");
6582 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_RALF)) {
6583 caps = gst_caps_new_simple ("audio/x-ralf-mpeg4-generic", NULL);
6584 *codec_name = g_strdup ("Real Audio Lossless");
6585 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_ATRC)) {
6586 caps = gst_caps_new_simple ("audio/x-vnd.sony.atrac3", NULL);
6587 *codec_name = g_strdup ("Sony ATRAC3");
6589 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
6594 if (audiocontext->samplerate > 0 && audiocontext->channels > 0) {
6597 for (i = 0; i < gst_caps_get_size (caps); i++) {
6598 gst_structure_set (gst_caps_get_structure (caps, i),
6599 "channels", G_TYPE_INT, audiocontext->channels,
6600 "rate", G_TYPE_INT, audiocontext->samplerate, NULL);
6604 gst_caps_do_simplify (caps);
6611 gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
6612 subtitlecontext, const gchar * codec_id, gpointer data, guint size)
6614 GstCaps *caps = NULL;
6615 GstMatroskaTrackContext *context =
6616 (GstMatroskaTrackContext *) subtitlecontext;
6618 /* for backwards compatibility */
6619 if (!g_ascii_strcasecmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASCII))
6620 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8;
6621 else if (!g_ascii_strcasecmp (codec_id, "S_SSA"))
6622 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_SSA;
6623 else if (!g_ascii_strcasecmp (codec_id, "S_ASS"))
6624 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_ASS;
6625 else if (!g_ascii_strcasecmp (codec_id, "S_USF"))
6626 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_USF;
6628 /* TODO: Add GST_MATROSKA_CODEC_ID_SUBTITLE_BMP support
6629 * Check if we have to do something with codec_private */
6630 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8)) {
6631 caps = gst_caps_new_simple ("text/plain", NULL);
6632 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
6633 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_SSA)) {
6634 caps = gst_caps_new_simple ("application/x-ssa", NULL);
6635 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
6636 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASS)) {
6637 caps = gst_caps_new_simple ("application/x-ass", NULL);
6638 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
6639 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_USF)) {
6640 caps = gst_caps_new_simple ("application/x-usf", NULL);
6641 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
6642 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB)) {
6643 caps = gst_caps_new_simple ("video/x-dvd-subpicture", NULL);
6644 ((GstMatroskaTrackContext *) subtitlecontext)->send_dvd_event = TRUE;
6645 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_HDMVPGS)) {
6646 caps = gst_caps_new_simple ("subpicture/x-pgs", NULL);
6647 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_KATE)) {
6648 caps = gst_caps_new_simple ("subtitle/x-kate", NULL);
6649 context->send_xiph_headers = TRUE;
6651 GST_DEBUG ("Unknown subtitle stream: codec_id='%s'", codec_id);
6652 caps = gst_caps_new_simple ("application/x-subtitle-unknown", NULL);
6655 if (data != NULL && size > 0) {
6658 buf = gst_buffer_new_and_alloc (size);
6659 memcpy (GST_BUFFER_DATA (buf), data, size);
6660 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, buf, NULL);
6661 gst_buffer_unref (buf);
6668 gst_matroska_demux_set_index (GstElement * element, GstIndex * index)
6670 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
6672 GST_OBJECT_LOCK (demux);
6673 if (demux->element_index)
6674 gst_object_unref (demux->element_index);
6675 demux->element_index = index ? gst_object_ref (index) : NULL;
6676 GST_OBJECT_UNLOCK (demux);
6677 GST_DEBUG_OBJECT (demux, "Set index %" GST_PTR_FORMAT, demux->element_index);
6681 gst_matroska_demux_get_index (GstElement * element)
6683 GstIndex *result = NULL;
6684 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
6686 GST_OBJECT_LOCK (demux);
6687 if (demux->element_index)
6688 result = gst_object_ref (demux->element_index);
6689 GST_OBJECT_UNLOCK (demux);
6691 GST_DEBUG_OBJECT (demux, "Returning index %" GST_PTR_FORMAT, result);
6696 static GstStateChangeReturn
6697 gst_matroska_demux_change_state (GstElement * element,
6698 GstStateChange transition)
6700 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
6701 GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
6703 /* handle upwards state changes here */
6704 switch (transition) {
6709 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
6711 /* handle downwards state changes */
6712 switch (transition) {
6713 case GST_STATE_CHANGE_PAUSED_TO_READY:
6714 gst_matroska_demux_reset (GST_ELEMENT (demux));
6724 gst_matroska_demux_plugin_init (GstPlugin * plugin)
6728 /* create an elementfactory for the matroska_demux element */
6729 if (!gst_element_register (plugin, "matroskademux",
6730 GST_RANK_PRIMARY, GST_TYPE_MATROSKA_DEMUX))