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>
73 #include <gst/pbutils/pbutils.h>
77 #include "matroska-demux.h"
78 #include "matroska-ids.h"
80 GST_DEBUG_CATEGORY_STATIC (matroskademux_debug);
81 #define GST_CAT_DEFAULT matroskademux_debug
83 #define DEBUG_ELEMENT_START(demux, ebml, element) \
84 GST_DEBUG_OBJECT (demux, "Parsing " element " element at offset %" \
85 G_GUINT64_FORMAT, gst_ebml_read_get_pos (ebml))
87 #define DEBUG_ELEMENT_STOP(demux, ebml, element, ret) \
88 GST_DEBUG_OBJECT (demux, "Parsing " element " element " \
89 " finished with '%s'", gst_flow_get_name (ret))
98 static GstStaticPadTemplate sink_templ = GST_STATIC_PAD_TEMPLATE ("sink",
101 GST_STATIC_CAPS ("video/x-matroska; video/webm")
104 /* TODO: fill in caps! */
106 static GstStaticPadTemplate audio_src_templ =
107 GST_STATIC_PAD_TEMPLATE ("audio_%02d",
110 GST_STATIC_CAPS ("ANY")
113 static GstStaticPadTemplate video_src_templ =
114 GST_STATIC_PAD_TEMPLATE ("video_%02d",
117 GST_STATIC_CAPS ("ANY")
120 static GstStaticPadTemplate subtitle_src_templ =
121 GST_STATIC_PAD_TEMPLATE ("subtitle_%02d",
124 GST_STATIC_CAPS ("text/plain; application/x-ssa; application/x-ass; "
125 "application/x-usf; video/x-dvd-subpicture; "
126 "subpicture/x-pgs; subtitle/x-kate; " "application/x-subtitle-unknown")
129 static GstFlowReturn gst_matroska_demux_parse_id (GstMatroskaDemux * demux,
130 guint32 id, guint64 length, guint needed);
132 /* element functions */
133 static void gst_matroska_demux_loop (GstPad * pad);
135 static gboolean gst_matroska_demux_element_send_event (GstElement * element,
137 static gboolean gst_matroska_demux_element_query (GstElement * element,
141 static gboolean gst_matroska_demux_sink_activate_pull (GstPad * sinkpad,
143 static gboolean gst_matroska_demux_sink_activate (GstPad * sinkpad);
145 static gboolean gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
146 GstPad * pad, GstEvent * event);
147 static gboolean gst_matroska_demux_handle_src_event (GstPad * pad,
149 static const GstQueryType *gst_matroska_demux_get_src_query_types (GstPad *
151 static gboolean gst_matroska_demux_handle_src_query (GstPad * pad,
154 static gboolean gst_matroska_demux_handle_sink_event (GstPad * pad,
156 static GstFlowReturn gst_matroska_demux_chain (GstPad * pad,
159 static GstStateChangeReturn
160 gst_matroska_demux_change_state (GstElement * element,
161 GstStateChange transition);
163 gst_matroska_demux_set_index (GstElement * element, GstIndex * index);
164 static GstIndex *gst_matroska_demux_get_index (GstElement * element);
167 static GstCaps *gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext
168 * videocontext, const gchar * codec_id, guint8 * data, guint size,
169 gchar ** codec_name, guint32 * riff_fourcc);
170 static GstCaps *gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext
171 * audiocontext, const gchar * codec_id, guint8 * data, guint size,
172 gchar ** codec_name, guint16 * riff_audio_fmt);
174 * gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
175 subtitlecontext, const gchar * codec_id, gpointer data, guint size);
178 static void gst_matroska_demux_reset (GstElement * element);
179 static gboolean perform_seek_to_offset (GstMatroskaDemux * demux,
182 GType gst_matroska_demux_get_type (void);
183 GST_BOILERPLATE (GstMatroskaDemux, gst_matroska_demux, GstElement,
187 gst_matroska_demux_base_init (gpointer klass)
189 GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
191 gst_element_class_add_pad_template (element_class,
192 gst_static_pad_template_get (&video_src_templ));
193 gst_element_class_add_pad_template (element_class,
194 gst_static_pad_template_get (&audio_src_templ));
195 gst_element_class_add_pad_template (element_class,
196 gst_static_pad_template_get (&subtitle_src_templ));
197 gst_element_class_add_pad_template (element_class,
198 gst_static_pad_template_get (&sink_templ));
200 gst_element_class_set_details_simple (element_class, "Matroska demuxer",
202 "Demuxes Matroska/WebM streams into video/audio/subtitles",
203 "GStreamer maintainers <gstreamer-devel@lists.sourceforge.net>");
207 gst_matroska_demux_finalize (GObject * object)
209 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (object);
212 g_ptr_array_free (demux->src, TRUE);
216 if (demux->global_tags) {
217 gst_tag_list_free (demux->global_tags);
218 demux->global_tags = NULL;
221 g_object_unref (demux->adapter);
223 G_OBJECT_CLASS (parent_class)->finalize (object);
227 gst_matroska_demux_class_init (GstMatroskaDemuxClass * klass)
229 GObjectClass *gobject_class = (GObjectClass *) klass;
230 GstElementClass *gstelement_class = (GstElementClass *) klass;
232 /* parser helper separate debug */
233 GST_DEBUG_CATEGORY_INIT (ebmlread_debug, "ebmlread",
234 0, "EBML stream helper class");
236 GST_DEBUG_CATEGORY_INIT (matroskademux_debug, "matroskademux", 0,
239 gobject_class->finalize = gst_matroska_demux_finalize;
241 gstelement_class->change_state =
242 GST_DEBUG_FUNCPTR (gst_matroska_demux_change_state);
243 gstelement_class->send_event =
244 GST_DEBUG_FUNCPTR (gst_matroska_demux_element_send_event);
245 gstelement_class->query =
246 GST_DEBUG_FUNCPTR (gst_matroska_demux_element_query);
248 gstelement_class->set_index =
249 GST_DEBUG_FUNCPTR (gst_matroska_demux_set_index);
250 gstelement_class->get_index =
251 GST_DEBUG_FUNCPTR (gst_matroska_demux_get_index);
255 gst_matroska_demux_init (GstMatroskaDemux * demux,
256 GstMatroskaDemuxClass * klass)
258 demux->sinkpad = gst_pad_new_from_static_template (&sink_templ, "sink");
259 gst_pad_set_activate_function (demux->sinkpad,
260 GST_DEBUG_FUNCPTR (gst_matroska_demux_sink_activate));
261 gst_pad_set_activatepull_function (demux->sinkpad,
262 GST_DEBUG_FUNCPTR (gst_matroska_demux_sink_activate_pull));
263 gst_pad_set_chain_function (demux->sinkpad,
264 GST_DEBUG_FUNCPTR (gst_matroska_demux_chain));
265 gst_pad_set_event_function (demux->sinkpad,
266 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_sink_event));
267 gst_element_add_pad (GST_ELEMENT (demux), demux->sinkpad);
269 /* initial stream no. */
272 demux->writing_app = NULL;
273 demux->muxing_app = NULL;
275 demux->global_tags = NULL;
277 demux->adapter = gst_adapter_new ();
280 gst_matroska_demux_reset (GST_ELEMENT (demux));
284 gst_matroska_track_free (GstMatroskaTrackContext * track)
286 g_free (track->codec_id);
287 g_free (track->codec_name);
288 g_free (track->name);
289 g_free (track->language);
290 g_free (track->codec_priv);
291 g_free (track->codec_state);
293 if (track->encodings != NULL) {
296 for (i = 0; i < track->encodings->len; ++i) {
297 GstMatroskaTrackEncoding *enc = &g_array_index (track->encodings,
298 GstMatroskaTrackEncoding,
301 g_free (enc->comp_settings);
303 g_array_free (track->encodings, TRUE);
306 if (track->pending_tags)
307 gst_tag_list_free (track->pending_tags);
309 if (track->index_table)
310 g_array_free (track->index_table, TRUE);
316 * Returns the aggregated GstFlowReturn.
319 gst_matroska_demux_combine_flows (GstMatroskaDemux * demux,
320 GstMatroskaTrackContext * track, GstFlowReturn ret)
324 /* store the value */
325 track->last_flow = ret;
327 /* any other error that is not-linked can be returned right away */
328 if (ret != GST_FLOW_NOT_LINKED)
331 /* only return NOT_LINKED if all other pads returned NOT_LINKED */
332 g_assert (demux->src->len == demux->num_streams);
333 for (i = 0; i < demux->src->len; i++) {
334 GstMatroskaTrackContext *ostream = g_ptr_array_index (demux->src, i);
339 ret = ostream->last_flow;
340 /* some other return value (must be SUCCESS but we can return
341 * other values as well) */
342 if (ret != GST_FLOW_NOT_LINKED)
345 /* if we get here, all other pads were unlinked and we return
348 GST_LOG_OBJECT (demux, "combined return %s", gst_flow_get_name (ret));
353 gst_matroska_demux_free_parsed_el (gpointer mem, gpointer user_data)
355 g_slice_free (guint64, mem);
359 gst_matroska_demux_reset (GstElement * element)
361 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
364 GST_DEBUG_OBJECT (demux, "Resetting state");
367 demux->state = GST_MATROSKA_DEMUX_STATE_START;
369 /* clean up existing streams */
371 g_assert (demux->src->len == demux->num_streams);
372 for (i = 0; i < demux->src->len; i++) {
373 GstMatroskaTrackContext *context = g_ptr_array_index (demux->src, i);
375 if (context->pad != NULL)
376 gst_element_remove_pad (GST_ELEMENT (demux), context->pad);
378 gst_caps_replace (&context->caps, NULL);
379 gst_matroska_track_free (context);
381 g_ptr_array_free (demux->src, TRUE);
383 demux->src = g_ptr_array_new ();
385 demux->num_streams = 0;
386 demux->num_a_streams = 0;
387 demux->num_t_streams = 0;
388 demux->num_v_streams = 0;
390 /* reset media info */
391 g_free (demux->writing_app);
392 demux->writing_app = NULL;
393 g_free (demux->muxing_app);
394 demux->muxing_app = NULL;
398 g_array_free (demux->index, TRUE);
404 demux->time_scale = 1000000;
405 demux->created = G_MININT64;
407 demux->index_parsed = FALSE;
408 demux->tracks_parsed = FALSE;
409 demux->segmentinfo_parsed = FALSE;
410 demux->attachments_parsed = FALSE;
412 g_list_foreach (demux->tags_parsed,
413 (GFunc) gst_matroska_demux_free_parsed_el, NULL);
414 g_list_free (demux->tags_parsed);
415 demux->tags_parsed = NULL;
417 g_list_foreach (demux->seek_parsed,
418 (GFunc) gst_matroska_demux_free_parsed_el, NULL);
419 g_list_free (demux->seek_parsed);
420 demux->seek_parsed = NULL;
422 gst_segment_init (&demux->segment, GST_FORMAT_TIME);
423 demux->last_stop_end = GST_CLOCK_TIME_NONE;
424 demux->seek_block = 0;
427 demux->cluster_time = GST_CLOCK_TIME_NONE;
428 demux->cluster_offset = 0;
429 demux->next_cluster_offset = 0;
430 demux->index_offset = 0;
431 demux->seekable = FALSE;
432 demux->need_newsegment = FALSE;
433 demux->building_index = FALSE;
434 if (demux->seek_event) {
435 gst_event_unref (demux->seek_event);
436 demux->seek_event = NULL;
439 demux->seek_index = NULL;
440 demux->seek_entry = 0;
442 if (demux->close_segment) {
443 gst_event_unref (demux->close_segment);
444 demux->close_segment = NULL;
447 if (demux->new_segment) {
448 gst_event_unref (demux->new_segment);
449 demux->new_segment = NULL;
452 if (demux->element_index) {
453 gst_object_unref (demux->element_index);
454 demux->element_index = NULL;
456 demux->element_index_writer_id = -1;
458 if (demux->global_tags) {
459 gst_tag_list_free (demux->global_tags);
461 demux->global_tags = gst_tag_list_new ();
463 if (demux->cached_buffer) {
464 gst_buffer_unref (demux->cached_buffer);
465 demux->cached_buffer = NULL;
470 * Calls pull_range for (offset,size) without advancing our offset
473 gst_matroska_demux_peek_bytes (GstMatroskaDemux * demux, guint64 offset,
474 guint size, GstBuffer ** p_buf, guint8 ** bytes)
478 /* Caching here actually makes much less difference than one would expect.
479 * We do it mainly to avoid pulling buffers of 1 byte all the time */
480 if (demux->cached_buffer) {
481 guint64 cache_offset = GST_BUFFER_OFFSET (demux->cached_buffer);
482 guint cache_size = GST_BUFFER_SIZE (demux->cached_buffer);
484 if (cache_offset <= demux->offset &&
485 (demux->offset + size) <= (cache_offset + cache_size)) {
487 *p_buf = gst_buffer_create_sub (demux->cached_buffer,
488 demux->offset - cache_offset, size);
490 *bytes = GST_BUFFER_DATA (demux->cached_buffer) + demux->offset -
494 /* not enough data in the cache, free cache and get a new one */
495 gst_buffer_unref (demux->cached_buffer);
496 demux->cached_buffer = NULL;
499 /* refill the cache */
500 ret = gst_pad_pull_range (demux->sinkpad, demux->offset,
501 MAX (size, 64 * 1024), &demux->cached_buffer);
502 if (ret != GST_FLOW_OK) {
503 demux->cached_buffer = NULL;
507 if (GST_BUFFER_SIZE (demux->cached_buffer) >= size) {
509 *p_buf = gst_buffer_create_sub (demux->cached_buffer, 0, size);
511 *bytes = GST_BUFFER_DATA (demux->cached_buffer);
515 /* Not possible to get enough data, try a last time with
516 * requesting exactly the size we need */
517 gst_buffer_unref (demux->cached_buffer);
518 demux->cached_buffer = NULL;
521 gst_pad_pull_range (demux->sinkpad, demux->offset, size,
522 &demux->cached_buffer);
523 if (ret != GST_FLOW_OK) {
524 GST_DEBUG_OBJECT (demux, "pull_range returned %d", ret);
532 if (GST_BUFFER_SIZE (demux->cached_buffer) < size) {
533 GST_WARNING_OBJECT (demux, "Dropping short buffer at offset %"
534 G_GUINT64_FORMAT ": wanted %u bytes, got %u bytes", demux->offset,
535 size, GST_BUFFER_SIZE (demux->cached_buffer));
537 gst_buffer_unref (demux->cached_buffer);
538 demux->cached_buffer = NULL;
543 return GST_FLOW_UNEXPECTED;
547 *p_buf = gst_buffer_create_sub (demux->cached_buffer, 0, size);
549 *bytes = GST_BUFFER_DATA (demux->cached_buffer);
554 static const guint8 *
555 gst_matroska_demux_peek_pull (GstMatroskaDemux * demux, guint peek)
559 gst_matroska_demux_peek_bytes (demux, demux->offset, peek, NULL, &data);
564 gst_matroska_demux_peek_id_length_pull (GstMatroskaDemux * demux, guint32 * _id,
565 guint64 * _length, guint * _needed)
567 return gst_ebml_peek_id_length (_id, _length, _needed,
568 (GstPeekData) gst_matroska_demux_peek_pull, (gpointer) demux,
569 GST_ELEMENT_CAST (demux), demux->offset);
573 gst_matroska_demux_get_length (GstMatroskaDemux * demux)
575 GstFormat fmt = GST_FORMAT_BYTES;
578 if (!gst_pad_query_peer_duration (demux->sinkpad, &fmt, &end) ||
579 fmt != GST_FORMAT_BYTES || end < 0)
580 GST_DEBUG_OBJECT (demux, "no upstream length");
586 gst_matroska_demux_stream_from_num (GstMatroskaDemux * demux, guint track_num)
590 g_assert (demux->src->len == demux->num_streams);
591 for (n = 0; n < demux->src->len; n++) {
592 GstMatroskaTrackContext *context = g_ptr_array_index (demux->src, n);
594 if (context->num == track_num) {
599 if (n == demux->num_streams)
600 GST_WARNING_OBJECT (demux,
601 "Failed to find corresponding pad for tracknum %d", track_num);
607 gst_matroska_demux_encoding_cmp (GstMatroskaTrackEncoding * a,
608 GstMatroskaTrackEncoding * b)
610 if (b->order > a->order)
612 else if (b->order < a->order)
619 gst_matroska_demux_encoding_order_unique (GArray * encodings, guint64 order)
623 if (encodings == NULL || encodings->len == 0)
626 for (i = 0; i < encodings->len; i++)
627 if (g_array_index (encodings, GstMatroskaTrackEncoding, i).order == order)
634 gst_matroska_demux_read_track_encoding (GstMatroskaDemux * demux,
635 GstEbmlRead * ebml, GstMatroskaTrackContext * context)
637 GstMatroskaTrackEncoding enc = { 0, };
641 DEBUG_ELEMENT_START (demux, ebml, "ContentEncoding");
642 /* Set default values */
644 /* All other default values are 0 */
646 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
647 DEBUG_ELEMENT_STOP (demux, ebml, "ContentEncoding", ret);
651 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
652 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
656 case GST_MATROSKA_ID_CONTENTENCODINGORDER:{
659 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
662 if (!gst_matroska_demux_encoding_order_unique (context->encodings, num)) {
663 GST_ERROR_OBJECT (demux, "ContentEncodingOrder %" G_GUINT64_FORMAT
664 "is not unique for track %d", num, context->num);
665 ret = GST_FLOW_ERROR;
669 GST_DEBUG_OBJECT (demux, "ContentEncodingOrder: %" G_GUINT64_FORMAT,
674 case GST_MATROSKA_ID_CONTENTENCODINGSCOPE:{
677 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
680 if (num > 7 && num == 0) {
681 GST_ERROR_OBJECT (demux, "Invalid ContentEncodingScope %"
682 G_GUINT64_FORMAT, num);
683 ret = GST_FLOW_ERROR;
687 GST_DEBUG_OBJECT (demux, "ContentEncodingScope: %" G_GUINT64_FORMAT,
693 case GST_MATROSKA_ID_CONTENTENCODINGTYPE:{
696 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
700 GST_ERROR_OBJECT (demux, "Invalid ContentEncodingType %"
701 G_GUINT64_FORMAT, num);
702 ret = GST_FLOW_ERROR;
704 } else if (num != 0) {
705 GST_ERROR_OBJECT (demux, "Encrypted tracks are not supported yet");
706 ret = GST_FLOW_ERROR;
709 GST_DEBUG_OBJECT (demux, "ContentEncodingType: %" G_GUINT64_FORMAT,
714 case GST_MATROSKA_ID_CONTENTCOMPRESSION:{
716 DEBUG_ELEMENT_START (demux, ebml, "ContentCompression");
718 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
721 while (ret == GST_FLOW_OK &&
722 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
723 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
727 case GST_MATROSKA_ID_CONTENTCOMPALGO:{
730 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK) {
734 GST_ERROR_OBJECT (demux, "Invalid ContentCompAlgo %"
735 G_GUINT64_FORMAT, num);
736 ret = GST_FLOW_ERROR;
739 GST_DEBUG_OBJECT (demux, "ContentCompAlgo: %" G_GUINT64_FORMAT,
745 case GST_MATROSKA_ID_CONTENTCOMPSETTINGS:{
750 gst_ebml_read_binary (ebml, &id, &data,
751 &size)) != GST_FLOW_OK) {
754 enc.comp_settings = data;
755 enc.comp_settings_length = size;
756 GST_DEBUG_OBJECT (demux,
757 "ContentCompSettings of size %" G_GUINT64_FORMAT, size);
761 GST_WARNING_OBJECT (demux,
762 "Unknown ContentCompression subelement 0x%x - ignoring", id);
763 ret = gst_ebml_read_skip (ebml);
767 DEBUG_ELEMENT_STOP (demux, ebml, "ContentCompression", ret);
771 case GST_MATROSKA_ID_CONTENTENCRYPTION:
772 GST_ERROR_OBJECT (demux, "Encrypted tracks not yet supported");
773 gst_ebml_read_skip (ebml);
774 ret = GST_FLOW_ERROR;
777 GST_WARNING_OBJECT (demux,
778 "Unknown ContentEncoding subelement 0x%x - ignoring", id);
779 ret = gst_ebml_read_skip (ebml);
784 DEBUG_ELEMENT_STOP (demux, ebml, "ContentEncoding", ret);
785 if (ret != GST_FLOW_OK && ret != GST_FLOW_UNEXPECTED)
788 /* TODO: Check if the combination of values is valid */
790 g_array_append_val (context->encodings, enc);
796 gst_matroska_decompress_data (GstMatroskaTrackEncoding * enc,
797 guint8 ** data_out, guint * size_out,
798 GstMatroskaTrackCompressionAlgorithm algo)
800 guint8 *new_data = NULL;
802 guint8 *data = *data_out;
803 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 GST_ERROR ("invalid compression algorithm %d", algo);
958 *data_out = new_data;
959 *size_out = new_size;
966 gst_matroska_decode_data (GArray * encodings, guint8 ** data_out,
967 guint * size_out, GstMatroskaTrackEncodingScope scope, gboolean free)
974 g_return_val_if_fail (encodings != NULL, FALSE);
975 g_return_val_if_fail (data_out != NULL && *data_out != NULL, FALSE);
976 g_return_val_if_fail (size_out != NULL, FALSE);
981 for (i = 0; i < encodings->len; i++) {
982 GstMatroskaTrackEncoding *enc =
983 &g_array_index (encodings, GstMatroskaTrackEncoding, i);
984 guint8 *new_data = NULL;
987 if ((enc->scope & scope) == 0)
990 /* Encryption not supported yet */
991 if (enc->type != 0) {
1000 gst_matroska_decompress_data (enc, &new_data, &new_size,
1006 if ((data == *data_out && free) || (data != *data_out))
1014 if ((data == *data_out && free) || (data != *data_out))
1028 gst_matroska_decode_buffer (GstMatroskaTrackContext * context, GstBuffer * buf)
1034 g_return_val_if_fail (GST_IS_BUFFER (buf), NULL);
1036 GST_DEBUG ("decoding buffer %p", buf);
1038 data = GST_BUFFER_DATA (buf);
1039 size = GST_BUFFER_SIZE (buf);
1041 g_return_val_if_fail (data != NULL && size > 0, buf);
1043 if (gst_matroska_decode_data (context->encodings, &data, &size,
1044 GST_MATROSKA_TRACK_ENCODING_SCOPE_FRAME, FALSE)) {
1045 new_buf = gst_buffer_new ();
1046 GST_BUFFER_MALLOCDATA (new_buf) = (guint8 *) data;
1047 GST_BUFFER_DATA (new_buf) = (guint8 *) data;
1048 GST_BUFFER_SIZE (new_buf) = size;
1050 gst_buffer_unref (buf);
1055 GST_DEBUG ("decode data failed");
1056 gst_buffer_unref (buf);
1061 static GstFlowReturn
1062 gst_matroska_decode_content_encodings (GArray * encodings)
1066 if (encodings == NULL)
1069 for (i = 0; i < encodings->len; i++) {
1070 GstMatroskaTrackEncoding *enc =
1071 &g_array_index (encodings, GstMatroskaTrackEncoding, i);
1072 GstMatroskaTrackEncoding *enc2;
1073 guint8 *data = NULL;
1076 if ((enc->scope & GST_MATROSKA_TRACK_ENCODING_SCOPE_NEXT_CONTENT_ENCODING)
1080 /* Encryption not supported yet */
1082 return GST_FLOW_ERROR;
1084 if (i + 1 >= encodings->len)
1085 return GST_FLOW_ERROR;
1087 enc2 = &g_array_index (encodings, GstMatroskaTrackEncoding, i + 1);
1089 if (enc->comp_settings_length == 0)
1092 data = enc->comp_settings;
1093 size = enc->comp_settings_length;
1095 if (!gst_matroska_decompress_data (enc, &data, &size, enc->comp_algo))
1096 return GST_FLOW_ERROR;
1098 g_free (enc->comp_settings);
1100 enc->comp_settings = data;
1101 enc->comp_settings_length = size;
1107 static GstFlowReturn
1108 gst_matroska_demux_read_track_encodings (GstMatroskaDemux * demux,
1109 GstEbmlRead * ebml, GstMatroskaTrackContext * context)
1114 DEBUG_ELEMENT_START (demux, ebml, "ContentEncodings");
1116 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
1117 DEBUG_ELEMENT_STOP (demux, ebml, "ContentEncodings", ret);
1121 context->encodings =
1122 g_array_sized_new (FALSE, FALSE, sizeof (GstMatroskaTrackEncoding), 1);
1124 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1125 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1129 case GST_MATROSKA_ID_CONTENTENCODING:
1130 ret = gst_matroska_demux_read_track_encoding (demux, ebml, context);
1133 GST_WARNING_OBJECT (demux,
1134 "Unknown ContentEncodings subelement 0x%x - ignoring", id);
1135 ret = gst_ebml_read_skip (ebml);
1140 DEBUG_ELEMENT_STOP (demux, ebml, "ContentEncodings", ret);
1141 if (ret != GST_FLOW_OK && ret != GST_FLOW_UNEXPECTED)
1144 /* Sort encodings according to their order */
1145 g_array_sort (context->encodings,
1146 (GCompareFunc) gst_matroska_demux_encoding_cmp);
1148 return gst_matroska_decode_content_encodings (context->encodings);
1152 gst_matroska_demux_tracknumber_unique (GstMatroskaDemux * demux, guint64 num)
1156 g_assert (demux->src->len == demux->num_streams);
1157 for (i = 0; i < demux->src->len; i++) {
1158 GstMatroskaTrackContext *context = g_ptr_array_index (demux->src, i);
1160 if (context->num == num)
1167 static GstFlowReturn
1168 gst_matroska_demux_add_stream (GstMatroskaDemux * demux, GstEbmlRead * ebml)
1170 GstElementClass *klass = GST_ELEMENT_GET_CLASS (demux);
1171 GstMatroskaTrackContext *context;
1172 GstPadTemplate *templ = NULL;
1173 GstCaps *caps = NULL;
1174 gchar *padname = NULL;
1176 guint32 id, riff_fourcc = 0;
1177 guint16 riff_audio_fmt = 0;
1178 GstTagList *list = NULL;
1179 gchar *codec = NULL;
1181 DEBUG_ELEMENT_START (demux, ebml, "TrackEntry");
1183 /* start with the master */
1184 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
1185 DEBUG_ELEMENT_STOP (demux, ebml, "TrackEntry", ret);
1189 /* allocate generic... if we know the type, we'll g_renew()
1190 * with the precise type */
1191 context = g_new0 (GstMatroskaTrackContext, 1);
1192 g_ptr_array_add (demux->src, context);
1193 context->index = demux->num_streams;
1194 context->index_writer_id = -1;
1195 context->type = 0; /* no type yet */
1196 context->default_duration = 0;
1198 context->set_discont = TRUE;
1199 context->timecodescale = 1.0;
1201 GST_MATROSKA_TRACK_ENABLED | GST_MATROSKA_TRACK_DEFAULT |
1202 GST_MATROSKA_TRACK_LACING;
1203 context->last_flow = GST_FLOW_OK;
1204 context->to_offset = G_MAXINT64;
1205 demux->num_streams++;
1206 g_assert (demux->src->len == demux->num_streams);
1208 GST_DEBUG_OBJECT (demux, "Stream number %d", context->index);
1210 /* try reading the trackentry headers */
1211 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1212 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1216 /* track number (unique stream ID) */
1217 case GST_MATROSKA_ID_TRACKNUMBER:{
1220 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1224 GST_ERROR_OBJECT (demux, "Invalid TrackNumber 0");
1225 ret = GST_FLOW_ERROR;
1227 } else if (!gst_matroska_demux_tracknumber_unique (demux, num)) {
1228 GST_ERROR_OBJECT (demux, "TrackNumber %" G_GUINT64_FORMAT
1229 " is not unique", num);
1230 ret = GST_FLOW_ERROR;
1234 GST_DEBUG_OBJECT (demux, "TrackNumber: %" G_GUINT64_FORMAT, num);
1238 /* track UID (unique identifier) */
1239 case GST_MATROSKA_ID_TRACKUID:{
1242 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1246 GST_ERROR_OBJECT (demux, "Invalid TrackUID 0");
1247 ret = GST_FLOW_ERROR;
1251 GST_DEBUG_OBJECT (demux, "TrackUID: %" G_GUINT64_FORMAT, num);
1256 /* track type (video, audio, combined, subtitle, etc.) */
1257 case GST_MATROSKA_ID_TRACKTYPE:{
1260 if ((ret = gst_ebml_read_uint (ebml, &id, &track_type)) != GST_FLOW_OK) {
1264 if (context->type != 0 && context->type != track_type) {
1265 GST_WARNING_OBJECT (demux,
1266 "More than one tracktype defined in a TrackEntry - skipping");
1268 } else if (track_type < 1 || track_type > 254) {
1269 GST_WARNING_OBJECT (demux, "Invalid TrackType %" G_GUINT64_FORMAT,
1274 GST_DEBUG_OBJECT (demux, "TrackType: %" G_GUINT64_FORMAT, track_type);
1276 /* ok, so we're actually going to reallocate this thing */
1277 switch (track_type) {
1278 case GST_MATROSKA_TRACK_TYPE_VIDEO:
1279 gst_matroska_track_init_video_context (&context);
1281 case GST_MATROSKA_TRACK_TYPE_AUDIO:
1282 gst_matroska_track_init_audio_context (&context);
1284 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
1285 gst_matroska_track_init_subtitle_context (&context);
1287 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1288 case GST_MATROSKA_TRACK_TYPE_LOGO:
1289 case GST_MATROSKA_TRACK_TYPE_BUTTONS:
1290 case GST_MATROSKA_TRACK_TYPE_CONTROL:
1292 GST_WARNING_OBJECT (demux,
1293 "Unknown or unsupported TrackType %" G_GUINT64_FORMAT,
1298 g_ptr_array_index (demux->src, demux->num_streams - 1) = context;
1302 /* tracktype specific stuff for video */
1303 case GST_MATROSKA_ID_TRACKVIDEO:{
1304 GstMatroskaTrackVideoContext *videocontext;
1306 DEBUG_ELEMENT_START (demux, ebml, "TrackVideo");
1308 if (!gst_matroska_track_init_video_context (&context)) {
1309 GST_WARNING_OBJECT (demux,
1310 "TrackVideo element in non-video track - ignoring track");
1311 ret = GST_FLOW_ERROR;
1313 } else if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
1316 videocontext = (GstMatroskaTrackVideoContext *) context;
1317 g_ptr_array_index (demux->src, demux->num_streams - 1) = context;
1319 while (ret == GST_FLOW_OK &&
1320 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1321 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1325 /* Should be one level up but some broken muxers write it here. */
1326 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
1329 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1333 GST_WARNING_OBJECT (demux, "Invalid TrackDefaultDuration 0");
1337 GST_DEBUG_OBJECT (demux,
1338 "TrackDefaultDuration: %" G_GUINT64_FORMAT, num);
1339 context->default_duration = num;
1343 /* video framerate */
1344 /* NOTE: This one is here only for backward compatibility.
1345 * Use _TRACKDEFAULDURATION one level up. */
1346 case GST_MATROSKA_ID_VIDEOFRAMERATE:{
1349 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
1353 GST_WARNING_OBJECT (demux, "Invalid TrackVideoFPS %lf", num);
1357 GST_DEBUG_OBJECT (demux, "TrackVideoFrameRate: %lf", num);
1358 if (context->default_duration == 0)
1359 context->default_duration =
1360 gst_gdouble_to_guint64 ((gdouble) GST_SECOND * (1.0 / num));
1361 videocontext->default_fps = num;
1365 /* width of the size to display the video at */
1366 case GST_MATROSKA_ID_VIDEODISPLAYWIDTH:{
1369 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1373 GST_WARNING_OBJECT (demux, "Invalid TrackVideoDisplayWidth 0");
1377 GST_DEBUG_OBJECT (demux,
1378 "TrackVideoDisplayWidth: %" G_GUINT64_FORMAT, num);
1379 videocontext->display_width = num;
1383 /* height of the size to display the video at */
1384 case GST_MATROSKA_ID_VIDEODISPLAYHEIGHT:{
1387 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1391 GST_WARNING_OBJECT (demux, "Invalid TrackVideoDisplayHeight 0");
1395 GST_DEBUG_OBJECT (demux,
1396 "TrackVideoDisplayHeight: %" G_GUINT64_FORMAT, num);
1397 videocontext->display_height = num;
1401 /* width of the video in the file */
1402 case GST_MATROSKA_ID_VIDEOPIXELWIDTH:{
1405 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1409 GST_WARNING_OBJECT (demux, "Invalid TrackVideoPixelWidth 0");
1413 GST_DEBUG_OBJECT (demux,
1414 "TrackVideoPixelWidth: %" G_GUINT64_FORMAT, num);
1415 videocontext->pixel_width = num;
1419 /* height of the video in the file */
1420 case GST_MATROSKA_ID_VIDEOPIXELHEIGHT:{
1423 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1427 GST_WARNING_OBJECT (demux, "Invalid TrackVideoPixelHeight 0");
1431 GST_DEBUG_OBJECT (demux,
1432 "TrackVideoPixelHeight: %" G_GUINT64_FORMAT, num);
1433 videocontext->pixel_height = num;
1437 /* whether the video is interlaced */
1438 case GST_MATROSKA_ID_VIDEOFLAGINTERLACED:{
1441 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1445 context->flags |= GST_MATROSKA_VIDEOTRACK_INTERLACED;
1447 context->flags &= ~GST_MATROSKA_VIDEOTRACK_INTERLACED;
1448 GST_DEBUG_OBJECT (demux, "TrackVideoInterlaced: %d",
1449 (context->flags & GST_MATROSKA_VIDEOTRACK_INTERLACED) ? 1 :
1454 /* aspect ratio behaviour */
1455 case GST_MATROSKA_ID_VIDEOASPECTRATIOTYPE:{
1458 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1461 if (num != GST_MATROSKA_ASPECT_RATIO_MODE_FREE &&
1462 num != GST_MATROSKA_ASPECT_RATIO_MODE_KEEP &&
1463 num != GST_MATROSKA_ASPECT_RATIO_MODE_FIXED) {
1464 GST_WARNING_OBJECT (demux,
1465 "Unknown TrackVideoAspectRatioType 0x%x", (guint) num);
1468 GST_DEBUG_OBJECT (demux,
1469 "TrackVideoAspectRatioType: %" G_GUINT64_FORMAT, num);
1470 videocontext->asr_mode = num;
1474 /* colourspace (only matters for raw video) fourcc */
1475 case GST_MATROSKA_ID_VIDEOCOLOURSPACE:{
1480 gst_ebml_read_binary (ebml, &id, &data,
1481 &datalen)) != GST_FLOW_OK)
1486 GST_WARNING_OBJECT (demux,
1487 "Invalid TrackVideoColourSpace length %" G_GUINT64_FORMAT,
1492 memcpy (&videocontext->fourcc, data, 4);
1493 GST_DEBUG_OBJECT (demux,
1494 "TrackVideoColourSpace: %" GST_FOURCC_FORMAT,
1495 GST_FOURCC_ARGS (videocontext->fourcc));
1501 GST_WARNING_OBJECT (demux,
1502 "Unknown TrackVideo subelement 0x%x - ignoring", id);
1504 case GST_MATROSKA_ID_VIDEOSTEREOMODE:
1505 case GST_MATROSKA_ID_VIDEODISPLAYUNIT:
1506 case GST_MATROSKA_ID_VIDEOPIXELCROPBOTTOM:
1507 case GST_MATROSKA_ID_VIDEOPIXELCROPTOP:
1508 case GST_MATROSKA_ID_VIDEOPIXELCROPLEFT:
1509 case GST_MATROSKA_ID_VIDEOPIXELCROPRIGHT:
1510 case GST_MATROSKA_ID_VIDEOGAMMAVALUE:
1511 ret = gst_ebml_read_skip (ebml);
1516 DEBUG_ELEMENT_STOP (demux, ebml, "TrackVideo", ret);
1520 /* tracktype specific stuff for audio */
1521 case GST_MATROSKA_ID_TRACKAUDIO:{
1522 GstMatroskaTrackAudioContext *audiocontext;
1524 DEBUG_ELEMENT_START (demux, ebml, "TrackAudio");
1526 if (!gst_matroska_track_init_audio_context (&context)) {
1527 GST_WARNING_OBJECT (demux,
1528 "TrackAudio element in non-audio track - ignoring track");
1529 ret = GST_FLOW_ERROR;
1533 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
1536 audiocontext = (GstMatroskaTrackAudioContext *) context;
1537 g_ptr_array_index (demux->src, demux->num_streams - 1) = context;
1539 while (ret == GST_FLOW_OK &&
1540 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1541 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1546 case GST_MATROSKA_ID_AUDIOSAMPLINGFREQ:{
1549 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
1554 GST_WARNING_OBJECT (demux,
1555 "Invalid TrackAudioSamplingFrequency %lf", num);
1559 GST_DEBUG_OBJECT (demux, "TrackAudioSamplingFrequency: %lf", num);
1560 audiocontext->samplerate = num;
1565 case GST_MATROSKA_ID_AUDIOBITDEPTH:{
1568 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1572 GST_WARNING_OBJECT (demux, "Invalid TrackAudioBitDepth 0");
1576 GST_DEBUG_OBJECT (demux, "TrackAudioBitDepth: %" G_GUINT64_FORMAT,
1578 audiocontext->bitdepth = num;
1583 case GST_MATROSKA_ID_AUDIOCHANNELS:{
1586 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1590 GST_WARNING_OBJECT (demux, "Invalid TrackAudioChannels 0");
1594 GST_DEBUG_OBJECT (demux, "TrackAudioChannels: %" G_GUINT64_FORMAT,
1596 audiocontext->channels = num;
1601 GST_WARNING_OBJECT (demux,
1602 "Unknown TrackAudio subelement 0x%x - ignoring", id);
1604 case GST_MATROSKA_ID_AUDIOCHANNELPOSITIONS:
1605 case GST_MATROSKA_ID_AUDIOOUTPUTSAMPLINGFREQ:
1606 ret = gst_ebml_read_skip (ebml);
1611 DEBUG_ELEMENT_STOP (demux, ebml, "TrackAudio", ret);
1616 /* codec identifier */
1617 case GST_MATROSKA_ID_CODECID:{
1620 if ((ret = gst_ebml_read_ascii (ebml, &id, &text)) != GST_FLOW_OK)
1623 GST_DEBUG_OBJECT (demux, "CodecID: %s", GST_STR_NULL (text));
1624 context->codec_id = text;
1628 /* codec private data */
1629 case GST_MATROSKA_ID_CODECPRIVATE:{
1634 gst_ebml_read_binary (ebml, &id, &data, &size)) != GST_FLOW_OK)
1637 context->codec_priv = data;
1638 context->codec_priv_size = size;
1640 GST_DEBUG_OBJECT (demux, "CodecPrivate of size %" G_GUINT64_FORMAT,
1645 /* name of the codec */
1646 case GST_MATROSKA_ID_CODECNAME:{
1649 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1652 GST_DEBUG_OBJECT (demux, "CodecName: %s", GST_STR_NULL (text));
1653 context->codec_name = text;
1657 /* name of this track */
1658 case GST_MATROSKA_ID_TRACKNAME:{
1661 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1664 context->name = text;
1665 GST_DEBUG_OBJECT (demux, "TrackName: %s", GST_STR_NULL (text));
1669 /* language (matters for audio/subtitles, mostly) */
1670 case GST_MATROSKA_ID_TRACKLANGUAGE:{
1673 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1677 context->language = text;
1680 if (strlen (context->language) >= 4 && context->language[3] == '-')
1681 context->language[3] = '\0';
1683 GST_DEBUG_OBJECT (demux, "TrackLanguage: %s",
1684 GST_STR_NULL (context->language));
1688 /* whether this is actually used */
1689 case GST_MATROSKA_ID_TRACKFLAGENABLED:{
1692 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1696 context->flags |= GST_MATROSKA_TRACK_ENABLED;
1698 context->flags &= ~GST_MATROSKA_TRACK_ENABLED;
1700 GST_DEBUG_OBJECT (demux, "TrackEnabled: %d",
1701 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
1705 /* whether it's the default for this track type */
1706 case GST_MATROSKA_ID_TRACKFLAGDEFAULT:{
1709 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1713 context->flags |= GST_MATROSKA_TRACK_DEFAULT;
1715 context->flags &= ~GST_MATROSKA_TRACK_DEFAULT;
1717 GST_DEBUG_OBJECT (demux, "TrackDefault: %d",
1718 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
1722 /* whether the track must be used during playback */
1723 case GST_MATROSKA_ID_TRACKFLAGFORCED:{
1726 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1730 context->flags |= GST_MATROSKA_TRACK_FORCED;
1732 context->flags &= ~GST_MATROSKA_TRACK_FORCED;
1734 GST_DEBUG_OBJECT (demux, "TrackForced: %d",
1735 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
1739 /* lacing (like MPEG, where blocks don't end/start on frame
1741 case GST_MATROSKA_ID_TRACKFLAGLACING:{
1744 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1748 context->flags |= GST_MATROSKA_TRACK_LACING;
1750 context->flags &= ~GST_MATROSKA_TRACK_LACING;
1752 GST_DEBUG_OBJECT (demux, "TrackLacing: %d",
1753 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
1757 /* default length (in time) of one data block in this track */
1758 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
1761 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1766 GST_WARNING_OBJECT (demux, "Invalid TrackDefaultDuration 0");
1770 GST_DEBUG_OBJECT (demux, "TrackDefaultDuration: %" G_GUINT64_FORMAT,
1772 context->default_duration = num;
1776 case GST_MATROSKA_ID_CONTENTENCODINGS:{
1777 ret = gst_matroska_demux_read_track_encodings (demux, ebml, context);
1781 case GST_MATROSKA_ID_TRACKTIMECODESCALE:{
1784 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
1788 GST_WARNING_OBJECT (demux, "Invalid TrackTimeCodeScale %lf", num);
1792 GST_DEBUG_OBJECT (demux, "TrackTimeCodeScale: %lf", num);
1793 context->timecodescale = num;
1798 GST_WARNING ("Unknown TrackEntry subelement 0x%x - ignoring", id);
1801 /* we ignore these because they're nothing useful (i.e. crap)
1802 * or simply not implemented yet. */
1803 case GST_MATROSKA_ID_TRACKMINCACHE:
1804 case GST_MATROSKA_ID_TRACKMAXCACHE:
1805 case GST_MATROSKA_ID_MAXBLOCKADDITIONID:
1806 case GST_MATROSKA_ID_TRACKATTACHMENTLINK:
1807 case GST_MATROSKA_ID_TRACKOVERLAY:
1808 case GST_MATROSKA_ID_TRACKTRANSLATE:
1809 case GST_MATROSKA_ID_TRACKOFFSET:
1810 case GST_MATROSKA_ID_CODECSETTINGS:
1811 case GST_MATROSKA_ID_CODECINFOURL:
1812 case GST_MATROSKA_ID_CODECDOWNLOADURL:
1813 case GST_MATROSKA_ID_CODECDECODEALL:
1814 ret = gst_ebml_read_skip (ebml);
1819 DEBUG_ELEMENT_STOP (demux, ebml, "TrackEntry", ret);
1821 /* Decode codec private data if necessary */
1822 if (context->encodings && context->encodings->len > 0 && context->codec_priv
1823 && context->codec_priv_size > 0) {
1824 if (!gst_matroska_decode_data (context->encodings,
1825 &context->codec_priv, &context->codec_priv_size,
1826 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
1827 GST_WARNING_OBJECT (demux, "Decoding codec private data failed");
1828 ret = GST_FLOW_ERROR;
1832 if (context->type == 0 || context->codec_id == NULL || (ret != GST_FLOW_OK
1833 && ret != GST_FLOW_UNEXPECTED)) {
1834 if (ret == GST_FLOW_OK || ret == GST_FLOW_UNEXPECTED)
1835 GST_WARNING_OBJECT (ebml, "Unknown stream/codec in track entry header");
1837 demux->num_streams--;
1838 g_ptr_array_remove_index (demux->src, demux->num_streams);
1839 g_assert (demux->src->len == demux->num_streams);
1841 gst_matroska_track_free (context);
1847 /* now create the GStreamer connectivity */
1848 switch (context->type) {
1849 case GST_MATROSKA_TRACK_TYPE_VIDEO:{
1850 GstMatroskaTrackVideoContext *videocontext =
1851 (GstMatroskaTrackVideoContext *) context;
1853 padname = g_strdup_printf ("video_%02d", demux->num_v_streams++);
1854 templ = gst_element_class_get_pad_template (klass, "video_%02d");
1855 caps = gst_matroska_demux_video_caps (videocontext,
1856 context->codec_id, (guint8 *) context->codec_priv,
1857 context->codec_priv_size, &codec, &riff_fourcc);
1860 list = gst_tag_list_new ();
1861 gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
1862 GST_TAG_VIDEO_CODEC, codec, NULL);
1868 case GST_MATROSKA_TRACK_TYPE_AUDIO:{
1869 GstMatroskaTrackAudioContext *audiocontext =
1870 (GstMatroskaTrackAudioContext *) context;
1872 padname = g_strdup_printf ("audio_%02d", demux->num_a_streams++);
1873 templ = gst_element_class_get_pad_template (klass, "audio_%02d");
1874 caps = gst_matroska_demux_audio_caps (audiocontext,
1875 context->codec_id, context->codec_priv, context->codec_priv_size,
1876 &codec, &riff_audio_fmt);
1879 list = gst_tag_list_new ();
1880 gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
1881 GST_TAG_AUDIO_CODEC, codec, NULL);
1887 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:{
1888 GstMatroskaTrackSubtitleContext *subtitlecontext =
1889 (GstMatroskaTrackSubtitleContext *) context;
1891 padname = g_strdup_printf ("subtitle_%02d", demux->num_t_streams++);
1892 templ = gst_element_class_get_pad_template (klass, "subtitle_%02d");
1893 caps = gst_matroska_demux_subtitle_caps (subtitlecontext,
1894 context->codec_id, context->codec_priv, context->codec_priv_size);
1898 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1899 case GST_MATROSKA_TRACK_TYPE_LOGO:
1900 case GST_MATROSKA_TRACK_TYPE_BUTTONS:
1901 case GST_MATROSKA_TRACK_TYPE_CONTROL:
1903 /* we should already have quit by now */
1904 g_assert_not_reached ();
1907 if ((context->language == NULL || *context->language == '\0') &&
1908 (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO ||
1909 context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
1910 GST_LOG ("stream %d: language=eng (assuming default)", context->index);
1911 context->language = g_strdup ("eng");
1914 if (context->language) {
1918 list = gst_tag_list_new ();
1920 /* Matroska contains ISO 639-2B codes, we want ISO 639-1 */
1921 lang = gst_tag_get_language_code (context->language);
1922 gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
1923 GST_TAG_LANGUAGE_CODE, (lang) ? lang : context->language, NULL);
1927 GST_WARNING_OBJECT (demux, "could not determine caps for stream with "
1928 "codec_id='%s'", context->codec_id);
1929 switch (context->type) {
1930 case GST_MATROSKA_TRACK_TYPE_VIDEO:
1931 caps = gst_caps_new_simple ("video/x-unknown", NULL);
1933 case GST_MATROSKA_TRACK_TYPE_AUDIO:
1934 caps = gst_caps_new_simple ("audio/x-unknown", NULL);
1936 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
1937 caps = gst_caps_new_simple ("application/x-subtitle-unknown", NULL);
1939 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1941 caps = gst_caps_new_simple ("application/x-matroska-unknown", NULL);
1944 gst_caps_set_simple (caps, "codec-id", G_TYPE_STRING, context->codec_id,
1947 /* add any unrecognised riff fourcc / audio format, but after codec-id */
1948 if (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO && riff_audio_fmt != 0)
1949 gst_caps_set_simple (caps, "format", G_TYPE_INT, riff_audio_fmt, NULL);
1950 else if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO && riff_fourcc != 0)
1951 gst_caps_set_simple (caps, "fourcc", GST_TYPE_FOURCC, riff_fourcc, NULL);
1954 /* the pad in here */
1955 context->pad = gst_pad_new_from_template (templ, padname);
1956 context->caps = caps;
1958 gst_pad_set_event_function (context->pad,
1959 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_event));
1960 gst_pad_set_query_type_function (context->pad,
1961 GST_DEBUG_FUNCPTR (gst_matroska_demux_get_src_query_types));
1962 gst_pad_set_query_function (context->pad,
1963 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_query));
1965 GST_INFO_OBJECT (demux, "Adding pad '%s' with caps %" GST_PTR_FORMAT,
1968 context->pending_tags = list;
1970 gst_pad_set_element_private (context->pad, context);
1972 gst_pad_use_fixed_caps (context->pad);
1973 gst_pad_set_caps (context->pad, context->caps);
1974 gst_pad_set_active (context->pad, TRUE);
1975 gst_element_add_pad (GST_ELEMENT (demux), context->pad);
1983 static const GstQueryType *
1984 gst_matroska_demux_get_src_query_types (GstPad * pad)
1986 static const GstQueryType query_types[] = {
1997 gst_matroska_demux_query (GstMatroskaDemux * demux, GstPad * pad,
2000 gboolean res = FALSE;
2001 GstMatroskaTrackContext *context = NULL;
2004 context = gst_pad_get_element_private (pad);
2007 switch (GST_QUERY_TYPE (query)) {
2008 case GST_QUERY_POSITION:
2012 gst_query_parse_position (query, &format, NULL);
2014 if (format == GST_FORMAT_TIME) {
2015 GST_OBJECT_LOCK (demux);
2017 gst_query_set_position (query, GST_FORMAT_TIME, context->pos);
2019 gst_query_set_position (query, GST_FORMAT_TIME,
2020 demux->segment.last_stop);
2021 GST_OBJECT_UNLOCK (demux);
2022 } else if (format == GST_FORMAT_DEFAULT && context
2023 && context->default_duration) {
2024 GST_OBJECT_LOCK (demux);
2025 gst_query_set_position (query, GST_FORMAT_DEFAULT,
2026 context->pos / context->default_duration);
2027 GST_OBJECT_UNLOCK (demux);
2029 GST_DEBUG_OBJECT (demux,
2030 "only position query in TIME and DEFAULT format is supported");
2036 case GST_QUERY_DURATION:
2040 gst_query_parse_duration (query, &format, NULL);
2042 if (format == GST_FORMAT_TIME) {
2043 GST_OBJECT_LOCK (demux);
2044 gst_query_set_duration (query, GST_FORMAT_TIME,
2045 demux->segment.duration);
2046 GST_OBJECT_UNLOCK (demux);
2047 } else if (format == GST_FORMAT_DEFAULT && context
2048 && context->default_duration) {
2049 GST_OBJECT_LOCK (demux);
2050 gst_query_set_duration (query, GST_FORMAT_DEFAULT,
2051 demux->segment.duration / context->default_duration);
2052 GST_OBJECT_UNLOCK (demux);
2054 GST_DEBUG_OBJECT (demux,
2055 "only duration query in TIME and DEFAULT format is supported");
2062 case GST_QUERY_SEEKING:
2066 gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
2067 if (fmt == GST_FORMAT_TIME) {
2070 if (demux->streaming) {
2071 /* assuming we'll be able to get an index ... */
2072 seekable = demux->seekable;
2074 seekable = ! !demux->index;
2077 gst_query_set_seeking (query, GST_FORMAT_TIME, seekable,
2078 0, demux->segment.duration);
2084 res = gst_pad_query_default (pad, query);
2092 gst_matroska_demux_element_query (GstElement * element, GstQuery * query)
2094 return gst_matroska_demux_query (GST_MATROSKA_DEMUX (element), NULL, query);
2098 gst_matroska_demux_handle_src_query (GstPad * pad, GstQuery * query)
2101 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (gst_pad_get_parent (pad));
2103 ret = gst_matroska_demux_query (demux, pad, query);
2105 gst_object_unref (demux);
2111 gst_matroska_index_seek_find (GstMatroskaIndex * i1, GstClockTime * time,
2114 if (i1->time < *time)
2116 else if (i1->time > *time)
2122 static GstMatroskaIndex *
2123 gst_matroskademux_do_index_seek (GstMatroskaDemux * demux,
2124 GstMatroskaTrackContext * track, gint64 seek_pos, GArray ** _index,
2125 gint * _entry_index)
2127 GstMatroskaIndex *entry = NULL;
2130 if (!demux->index || !demux->index->len)
2133 /* find entry just before or at the requested position */
2134 if (track && track->index_table)
2135 index = track->index_table;
2137 index = demux->index;
2140 gst_util_array_binary_search (index->data, index->len,
2141 sizeof (GstMatroskaIndex),
2142 (GCompareDataFunc) gst_matroska_index_seek_find, GST_SEARCH_MODE_BEFORE,
2146 entry = &g_array_index (index, GstMatroskaIndex, 0);
2151 *_entry_index = entry - (GstMatroskaIndex *) index->data;
2156 /* takes ownership of taglist */
2158 gst_matroska_demux_found_global_tag (GstMatroskaDemux * demux,
2159 GstTagList * taglist)
2161 if (demux->global_tags) {
2162 /* nothing sent yet, add to cache */
2163 gst_tag_list_insert (demux->global_tags, taglist, GST_TAG_MERGE_APPEND);
2164 gst_tag_list_free (taglist);
2166 /* hm, already sent, no need to cache and wait anymore */
2167 GST_DEBUG_OBJECT (demux, "Sending late global tags %" GST_PTR_FORMAT,
2169 gst_element_found_tags (GST_ELEMENT (demux), taglist);
2173 /* returns FALSE if there are no pads to deliver event to,
2174 * otherwise TRUE (whatever the outcome of event sending),
2175 * takes ownership of the passed event! */
2177 gst_matroska_demux_send_event (GstMatroskaDemux * demux, GstEvent * event)
2179 gboolean is_newsegment;
2180 gboolean ret = FALSE;
2183 g_return_val_if_fail (event != NULL, FALSE);
2185 GST_DEBUG_OBJECT (demux, "Sending event of type %s to all source pads",
2186 GST_EVENT_TYPE_NAME (event));
2188 is_newsegment = (GST_EVENT_TYPE (event) == GST_EVENT_NEWSEGMENT);
2190 g_assert (demux->src->len == demux->num_streams);
2191 for (i = 0; i < demux->src->len; i++) {
2192 GstMatroskaTrackContext *stream;
2194 stream = g_ptr_array_index (demux->src, i);
2195 gst_event_ref (event);
2196 gst_pad_push_event (stream->pad, event);
2199 /* FIXME: send global tags before stream tags */
2200 if (G_UNLIKELY (is_newsegment && stream->pending_tags != NULL)) {
2201 GST_DEBUG_OBJECT (demux, "Sending pending_tags %p for pad %s:%s : %"
2202 GST_PTR_FORMAT, stream->pending_tags,
2203 GST_DEBUG_PAD_NAME (stream->pad), stream->pending_tags);
2204 gst_element_found_tags_for_pad (GST_ELEMENT (demux), stream->pad,
2205 stream->pending_tags);
2206 stream->pending_tags = NULL;
2210 if (G_UNLIKELY (is_newsegment && demux->global_tags != NULL)) {
2211 gst_tag_list_add (demux->global_tags, GST_TAG_MERGE_REPLACE,
2212 GST_TAG_CONTAINER_FORMAT, "Matroska", NULL);
2213 GST_DEBUG_OBJECT (demux, "Sending global_tags %p : %" GST_PTR_FORMAT,
2214 demux->global_tags, demux->global_tags);
2215 gst_element_found_tags (GST_ELEMENT (demux), demux->global_tags);
2216 demux->global_tags = NULL;
2219 gst_event_unref (event);
2224 gst_matroska_demux_element_send_event (GstElement * element, GstEvent * event)
2226 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
2229 g_return_val_if_fail (event != NULL, FALSE);
2231 if (GST_EVENT_TYPE (event) == GST_EVENT_SEEK) {
2232 res = gst_matroska_demux_handle_seek_event (demux, NULL, event);
2234 GST_WARNING_OBJECT (demux, "Unhandled event of type %s",
2235 GST_EVENT_TYPE_NAME (event));
2238 gst_event_unref (event);
2242 /* determine track to seek in */
2243 static GstMatroskaTrackContext *
2244 gst_matroska_demux_get_seek_track (GstMatroskaDemux * demux,
2245 GstMatroskaTrackContext * track)
2249 if (track && track->type == GST_MATROSKA_TRACK_TYPE_VIDEO)
2252 for (i = 0; i < demux->src->len; i++) {
2253 GstMatroskaTrackContext *stream;
2255 stream = g_ptr_array_index (demux->src, i);
2256 if (stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO && stream->index_table)
2264 gst_matroska_demux_reset_streams (GstMatroskaDemux * demux, GstClockTime time,
2269 GST_DEBUG_OBJECT (demux, "resetting stream state");
2271 g_assert (demux->src->len == demux->num_streams);
2272 for (i = 0; i < demux->src->len; i++) {
2273 GstMatroskaTrackContext *context = g_ptr_array_index (demux->src, i);
2274 context->pos = time;
2275 context->set_discont = TRUE;
2276 context->eos = FALSE;
2277 context->from_time = GST_CLOCK_TIME_NONE;
2279 context->last_flow = GST_FLOW_OK;
2280 if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
2281 GstMatroskaTrackVideoContext *videocontext =
2282 (GstMatroskaTrackVideoContext *) context;
2283 /* demux object lock held by caller */
2284 videocontext->earliest_time = GST_CLOCK_TIME_NONE;
2290 gst_matroska_demux_move_to_entry (GstMatroskaDemux * demux,
2291 GstMatroskaIndex * entry, gboolean reset)
2295 GST_OBJECT_LOCK (demux);
2297 /* seek (relative to matroska segment) */
2298 /* position might be invalid; will error when streaming resumes ... */
2299 demux->offset = entry->pos + demux->ebml_segment_start;
2301 GST_DEBUG_OBJECT (demux, "Seeked to offset %" G_GUINT64_FORMAT ", block %d, "
2302 "time %" GST_TIME_FORMAT, entry->pos + demux->ebml_segment_start,
2303 entry->block, GST_TIME_ARGS (entry->time));
2305 /* update the time */
2306 gst_matroska_demux_reset_streams (demux, entry->time, TRUE);
2307 demux->segment.last_stop = entry->time;
2308 demux->seek_block = entry->block;
2309 demux->seek_first = TRUE;
2310 demux->last_stop_end = GST_CLOCK_TIME_NONE;
2312 for (i = 0; i < demux->src->len; i++) {
2313 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->src, i);
2316 stream->to_offset = G_MAXINT64;
2318 if (stream->from_offset != -1)
2319 stream->to_offset = stream->from_offset;
2321 stream->from_offset = -1;
2324 GST_OBJECT_UNLOCK (demux);
2329 /* searches for a cluster start from @pos,
2330 * return GST_FLOW_OK and cluster position in @pos if found */
2331 static GstFlowReturn
2332 gst_matroska_demux_search_cluster (GstMatroskaDemux * demux, gint64 * pos)
2334 gint64 newpos = *pos;
2336 GstFlowReturn ret = GST_FLOW_OK;
2337 const guint chunk = 64 * 1024;
2338 GstBuffer *buf = NULL;
2343 orig_offset = demux->offset;
2345 /* read in at newpos and scan for ebml cluster id */
2347 GstByteReader reader;
2350 ret = gst_pad_pull_range (demux->sinkpad, newpos, chunk, &buf);
2351 if (ret != GST_FLOW_OK)
2353 GST_DEBUG_OBJECT (demux, "read buffer size %d at offset %" G_GINT64_FORMAT,
2354 GST_BUFFER_SIZE (buf), newpos);
2355 gst_byte_reader_init_from_buffer (&reader, buf);
2358 cluster_pos = gst_byte_reader_masked_scan_uint32 (&reader, 0xffffffff,
2359 GST_MATROSKA_ID_CLUSTER, cluster_pos,
2360 GST_BUFFER_SIZE (buf) - cluster_pos);
2361 if (cluster_pos >= 0) {
2362 newpos += cluster_pos;
2363 GST_DEBUG_OBJECT (demux,
2364 "found cluster ebml id at offset %" G_GINT64_FORMAT, newpos);
2365 /* extra checks whether we really sync'ed to a cluster:
2366 * - either it is the first and only cluster
2367 * - either there is a cluster after this one
2368 * - either cluster length is undefined
2370 /* ok if first cluster (there may not a subsequent one) */
2371 if (newpos == demux->first_cluster_offset) {
2372 GST_DEBUG_OBJECT (demux, "cluster is first cluster -> OK");
2375 demux->offset = newpos;
2377 gst_matroska_demux_peek_id_length_pull (demux, &id, &length, &needed);
2378 if (ret != GST_FLOW_OK)
2380 g_assert (id == GST_MATROSKA_ID_CLUSTER);
2381 GST_DEBUG_OBJECT (demux, "cluster size %" G_GUINT64_FORMAT ", prefix %d",
2383 /* ok if undefined length or first cluster */
2384 if (length == G_MAXUINT64) {
2385 GST_DEBUG_OBJECT (demux, "cluster has undefined length -> OK");
2389 demux->offset += length + needed;
2391 gst_matroska_demux_peek_id_length_pull (demux, &id, &length, &needed);
2392 if (ret != GST_FLOW_OK)
2394 GST_DEBUG_OBJECT (demux, "next element is %scluster",
2395 id == GST_MATROSKA_ID_CLUSTER ? "" : "not ");
2396 if (id == GST_MATROSKA_ID_CLUSTER)
2398 /* not ok, resume */
2401 /* partial cluster id may have been in tail of buffer */
2402 newpos += MAX (GST_BUFFER_SIZE (buf), 4) - 3;
2403 gst_buffer_unref (buf);
2409 gst_buffer_unref (buf);
2413 demux->offset = orig_offset;
2418 /* bisect and scan through file for cluster starting before @time,
2419 * returns fake index entry with corresponding info on cluster */
2420 static GstMatroskaIndex *
2421 gst_matroska_demux_search_pos (GstMatroskaDemux * demux, GstClockTime time)
2423 GstMatroskaIndex *entry = NULL;
2424 GstMatroskaDemuxState current_state;
2425 GstClockTime otime, prev_cluster_time, current_cluster_time, cluster_time;
2426 gint64 opos, newpos, startpos = 0, current_offset;
2427 gint64 prev_cluster_offset = -1, current_cluster_offset, cluster_offset;
2428 const guint chunk = 64 * 1024;
2429 GstBuffer *buf = NULL;
2435 /* (under)estimate new position, resync using cluster ebml id,
2436 * and scan forward to appropriate cluster
2437 * (and re-estimate if need to go backward) */
2439 prev_cluster_time = GST_CLOCK_TIME_NONE;
2441 /* store some current state */
2442 current_state = demux->state;
2443 g_return_val_if_fail (current_state == GST_MATROSKA_DEMUX_STATE_DATA, NULL);
2445 current_cluster_offset = demux->cluster_offset;
2446 current_cluster_time = demux->cluster_time;
2447 current_offset = demux->offset;
2449 demux->state = GST_MATROSKA_DEMUX_STATE_SCANNING;
2451 /* estimate using start and current position */
2452 opos = demux->offset - demux->ebml_segment_start;
2453 otime = demux->segment.last_stop;
2456 GST_LOG_OBJECT (demux,
2457 "opos: %" G_GUINT64_FORMAT ", otime: %" GST_TIME_FORMAT, opos,
2458 GST_TIME_ARGS (otime));
2459 newpos = gst_util_uint64_scale (opos, time, otime) - chunk;
2462 /* favour undershoot */
2463 newpos = newpos * 90 / 100;
2464 newpos += demux->ebml_segment_start;
2466 GST_DEBUG_OBJECT (demux,
2467 "estimated offset for %" GST_TIME_FORMAT ": %" G_GINT64_FORMAT,
2468 GST_TIME_ARGS (time), newpos);
2470 /* and at least start scanning before previous scan start to avoid looping */
2471 startpos = startpos * 90 / 100;
2472 if (startpos && startpos < newpos)
2475 /* read in at newpos and scan for ebml cluster id */
2479 ret = gst_matroska_demux_search_cluster (demux, &newpos);
2480 if (ret == GST_FLOW_UNEXPECTED) {
2481 /* heuristic HACK */
2482 newpos = startpos * 80 / 100;
2483 GST_DEBUG_OBJECT (demux, "EOS; "
2484 "new estimated offset for %" GST_TIME_FORMAT ": %" G_GINT64_FORMAT,
2485 GST_TIME_ARGS (time), newpos);
2488 } else if (ret != GST_FLOW_OK) {
2495 /* then start scanning and parsing for cluster time,
2496 * re-estimate if overshoot, otherwise next cluster and so on */
2497 demux->offset = newpos;
2498 demux->cluster_time = cluster_time = GST_CLOCK_TIME_NONE;
2500 guint64 cluster_size = 0;
2502 /* peek and parse some elements */
2503 ret = gst_matroska_demux_peek_id_length_pull (demux, &id, &length, &needed);
2504 if (ret != GST_FLOW_OK)
2506 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
2507 "size %" G_GUINT64_FORMAT ", needed %d", demux->offset, id,
2509 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
2510 if (ret != GST_FLOW_OK)
2513 if (id == GST_MATROSKA_ID_CLUSTER) {
2514 cluster_time = GST_CLOCK_TIME_NONE;
2515 if (length == G_MAXUINT64)
2518 cluster_size = length + needed;
2520 if (demux->cluster_time != GST_CLOCK_TIME_NONE &&
2521 cluster_time == GST_CLOCK_TIME_NONE) {
2522 cluster_time = demux->cluster_time * demux->time_scale;
2523 cluster_offset = demux->cluster_offset;
2524 GST_DEBUG_OBJECT (demux, "found cluster at offset %" G_GINT64_FORMAT
2525 " with time %" GST_TIME_FORMAT, cluster_offset,
2526 GST_TIME_ARGS (cluster_time));
2527 if (cluster_time > time) {
2528 GST_DEBUG_OBJECT (demux, "overshot target");
2529 /* cluster overshoots */
2530 if (cluster_offset == demux->first_cluster_offset) {
2531 /* but no prev one */
2532 GST_DEBUG_OBJECT (demux, "but using first cluster anyway");
2533 prev_cluster_time = cluster_time;
2534 prev_cluster_offset = cluster_offset;
2537 if (prev_cluster_time != GST_CLOCK_TIME_NONE) {
2538 /* prev cluster did not overshoot, so prev cluster is target */
2541 /* re-estimate using this new position info */
2542 opos = cluster_offset;
2543 otime = cluster_time;
2547 /* cluster undershoots, goto next one */
2548 prev_cluster_time = cluster_time;
2549 prev_cluster_offset = cluster_offset;
2550 /* skip cluster if length is defined,
2551 * otherwise will be skippingly parsed into */
2553 GST_DEBUG_OBJECT (demux, "skipping to next cluster");
2554 demux->offset = cluster_offset + cluster_size;
2555 demux->cluster_time = GST_CLOCK_TIME_NONE;
2557 GST_DEBUG_OBJECT (demux, "parsing/skipping cluster elements");
2564 if (ret == GST_FLOW_UNEXPECTED) {
2565 if (prev_cluster_time != GST_CLOCK_TIME_NONE)
2571 entry = g_new0 (GstMatroskaIndex, 1);
2572 entry->time = prev_cluster_time;
2573 entry->pos = prev_cluster_offset - demux->ebml_segment_start;
2574 GST_DEBUG_OBJECT (demux, "simulated index entry; time %" GST_TIME_FORMAT
2575 ", pos %" G_GUINT64_FORMAT, GST_TIME_ARGS (entry->time), entry->pos);
2579 gst_buffer_unref (buf);
2581 /* restore some state */
2582 demux->cluster_offset = current_cluster_offset;
2583 demux->cluster_time = current_cluster_time;
2584 demux->offset = current_offset;
2585 demux->state = current_state;
2591 gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
2592 GstPad * pad, GstEvent * event)
2594 GstMatroskaIndex *entry = NULL;
2595 GstMatroskaIndex scan_entry;
2597 GstSeekType cur_type, stop_type;
2599 gboolean flush, keyunit;
2602 GstMatroskaTrackContext *track = NULL;
2603 GstSegment seeksegment = { 0, };
2607 track = gst_pad_get_element_private (pad);
2609 track = gst_matroska_demux_get_seek_track (demux, track);
2611 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
2614 /* we can only seek on time */
2615 if (format != GST_FORMAT_TIME) {
2616 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
2620 /* copy segment, we need this because we still need the old
2621 * segment when we close the current segment. */
2622 memcpy (&seeksegment, &demux->segment, sizeof (GstSegment));
2625 GST_DEBUG_OBJECT (demux, "configuring seek");
2626 gst_segment_set_seek (&seeksegment, rate, format, flags,
2627 cur_type, cur, stop_type, stop, &update);
2630 GST_DEBUG_OBJECT (demux, "New segment %" GST_SEGMENT_FORMAT, &seeksegment);
2632 /* check sanity before we start flushing and all that */
2633 GST_OBJECT_LOCK (demux);
2634 if ((entry = gst_matroskademux_do_index_seek (demux, track,
2635 seeksegment.last_stop, &demux->seek_index, &demux->seek_entry)) ==
2637 /* pull mode without index can scan later on */
2638 if (demux->index || demux->streaming) {
2639 GST_DEBUG_OBJECT (demux, "No matching seek entry in index");
2640 GST_OBJECT_UNLOCK (demux);
2644 GST_DEBUG_OBJECT (demux, "Seek position looks sane");
2645 GST_OBJECT_UNLOCK (demux);
2647 if (demux->streaming) {
2648 /* need to seek to cluster start to pick up cluster time */
2649 /* upstream takes care of flushing and all that
2650 * ... and newsegment event handling takes care of the rest */
2651 return perform_seek_to_offset (demux,
2652 entry->pos + demux->ebml_segment_start);
2655 flush = ! !(flags & GST_SEEK_FLAG_FLUSH);
2656 keyunit = ! !(flags & GST_SEEK_FLAG_KEY_UNIT);
2659 GST_DEBUG_OBJECT (demux, "Starting flush");
2660 gst_pad_push_event (demux->sinkpad, gst_event_new_flush_start ());
2661 gst_matroska_demux_send_event (demux, gst_event_new_flush_start ());
2663 GST_DEBUG_OBJECT (demux, "Non-flushing seek, pausing task");
2664 gst_pad_pause_task (demux->sinkpad);
2667 /* now grab the stream lock so that streaming cannot continue, for
2668 * non flushing seeks when the element is in PAUSED this could block
2670 GST_DEBUG_OBJECT (demux, "Waiting for streaming to stop");
2671 GST_PAD_STREAM_LOCK (demux->sinkpad);
2673 /* pull mode without index can do some scanning */
2674 if (!demux->streaming && !demux->index) {
2675 /* need to stop flushing upstream as we need it next */
2677 gst_pad_push_event (demux->sinkpad, gst_event_new_flush_stop ());
2678 entry = gst_matroska_demux_search_pos (demux, seeksegment.last_stop);
2679 /* keep local copy */
2681 scan_entry = *entry;
2683 entry = &scan_entry;
2685 GST_DEBUG_OBJECT (demux, "Scan failed to find matching position");
2687 gst_matroska_demux_send_event (demux, gst_event_new_flush_stop ());
2693 GST_DEBUG_OBJECT (demux, "seek to key unit, adjusting segment start to %"
2694 GST_TIME_FORMAT, GST_TIME_ARGS (entry->time));
2695 seeksegment.start = entry->time;
2696 seeksegment.last_stop = entry->time;
2697 seeksegment.time = entry->time;
2701 GST_DEBUG_OBJECT (demux, "Stopping flush");
2702 gst_pad_push_event (demux->sinkpad, gst_event_new_flush_stop ());
2703 gst_matroska_demux_send_event (demux, gst_event_new_flush_stop ());
2704 } else if (demux->segment_running) {
2705 GST_DEBUG_OBJECT (demux, "Closing currently running segment");
2707 GST_OBJECT_LOCK (demux);
2708 if (demux->close_segment)
2709 gst_event_unref (demux->close_segment);
2711 demux->close_segment = gst_event_new_new_segment (TRUE,
2712 demux->segment.rate, GST_FORMAT_TIME, demux->segment.start,
2713 demux->segment.last_stop, demux->segment.time);
2714 GST_OBJECT_UNLOCK (demux);
2717 GST_OBJECT_LOCK (demux);
2718 /* now update the real segment info */
2719 GST_DEBUG_OBJECT (demux, "Committing new seek segment");
2720 memcpy (&demux->segment, &seeksegment, sizeof (GstSegment));
2721 GST_OBJECT_UNLOCK (demux);
2723 /* update some (segment) state */
2724 if (!gst_matroska_demux_move_to_entry (demux, entry, TRUE))
2727 /* notify start of new segment */
2728 if (demux->segment.flags & GST_SEEK_FLAG_SEGMENT) {
2731 msg = gst_message_new_segment_start (GST_OBJECT (demux),
2732 GST_FORMAT_TIME, demux->segment.start);
2733 gst_element_post_message (GST_ELEMENT (demux), msg);
2736 GST_OBJECT_LOCK (demux);
2737 if (demux->new_segment)
2738 gst_event_unref (demux->new_segment);
2739 demux->new_segment = gst_event_new_new_segment_full (FALSE,
2740 demux->segment.rate, demux->segment.applied_rate, demux->segment.format,
2741 demux->segment.start, demux->segment.stop, demux->segment.time);
2742 GST_OBJECT_UNLOCK (demux);
2744 /* restart our task since it might have been stopped when we did the
2746 demux->segment_running = TRUE;
2747 gst_pad_start_task (demux->sinkpad, (GstTaskFunction) gst_matroska_demux_loop,
2750 /* streaming can continue now */
2751 GST_PAD_STREAM_UNLOCK (demux->sinkpad);
2757 GST_PAD_STREAM_UNLOCK (demux->sinkpad);
2758 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Got a seek error"));
2764 * Handle whether we can perform the seek event or if we have to let the chain
2765 * function handle seeks to build the seek indexes first.
2768 gst_matroska_demux_handle_seek_push (GstMatroskaDemux * demux, GstPad * pad,
2772 GstSeekType cur_type, stop_type;
2777 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
2782 /* we can only seek on time */
2783 if (format != GST_FORMAT_TIME) {
2784 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
2788 if (stop_type != GST_SEEK_TYPE_NONE && stop != GST_CLOCK_TIME_NONE) {
2789 GST_DEBUG_OBJECT (demux, "Seek end-time not supported in streaming mode");
2793 if (!(flags & GST_SEEK_FLAG_FLUSH)) {
2794 GST_DEBUG_OBJECT (demux,
2795 "Non-flushing seek not supported in streaming mode");
2799 if (flags & GST_SEEK_FLAG_SEGMENT) {
2800 GST_DEBUG_OBJECT (demux, "Segment seek not supported in streaming mode");
2804 /* check for having parsed index already */
2805 if (!demux->index_parsed) {
2806 gboolean building_index;
2809 if (!demux->index_offset) {
2810 GST_DEBUG_OBJECT (demux, "no index (location); no seek in push mode");
2814 GST_OBJECT_LOCK (demux);
2815 /* handle the seek event in the chain function */
2816 demux->state = GST_MATROSKA_DEMUX_STATE_SEEK;
2817 /* no more seek can be issued until state reset to _DATA */
2819 /* copy the event */
2820 if (demux->seek_event)
2821 gst_event_unref (demux->seek_event);
2822 demux->seek_event = gst_event_ref (event);
2824 /* set the building_index flag so that only one thread can setup the
2825 * structures for index seeking. */
2826 building_index = demux->building_index;
2827 if (!building_index) {
2828 demux->building_index = TRUE;
2829 offset = demux->index_offset;
2831 GST_OBJECT_UNLOCK (demux);
2833 if (!building_index) {
2834 /* seek to the first subindex or legacy index */
2835 GST_INFO_OBJECT (demux, "Seeking to Cues at %" G_GUINT64_FORMAT, offset);
2836 return perform_seek_to_offset (demux, offset);
2839 /* well, we are handling it already */
2843 /* delegate to tweaked regular seek */
2844 return gst_matroska_demux_handle_seek_event (demux, pad, event);
2848 gst_matroska_demux_handle_src_event (GstPad * pad, GstEvent * event)
2850 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (gst_pad_get_parent (pad));
2851 gboolean res = TRUE;
2853 switch (GST_EVENT_TYPE (event)) {
2854 case GST_EVENT_SEEK:
2855 /* no seeking until we are (safely) ready */
2856 if (demux->state != GST_MATROSKA_DEMUX_STATE_DATA) {
2857 GST_DEBUG_OBJECT (demux, "not ready for seeking yet");
2860 if (!demux->streaming)
2861 res = gst_matroska_demux_handle_seek_event (demux, pad, event);
2863 res = gst_matroska_demux_handle_seek_push (demux, pad, event);
2864 gst_event_unref (event);
2869 GstMatroskaTrackContext *context = gst_pad_get_element_private (pad);
2870 if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
2871 GstMatroskaTrackVideoContext *videocontext =
2872 (GstMatroskaTrackVideoContext *) context;
2874 GstClockTimeDiff diff;
2875 GstClockTime timestamp;
2877 gst_event_parse_qos (event, &proportion, &diff, ×tamp);
2879 GST_OBJECT_LOCK (demux);
2880 videocontext->earliest_time = timestamp + diff;
2881 GST_OBJECT_UNLOCK (demux);
2884 gst_event_unref (event);
2888 /* events we don't need to handle */
2889 case GST_EVENT_NAVIGATION:
2890 gst_event_unref (event);
2894 case GST_EVENT_LATENCY:
2896 res = gst_pad_push_event (demux->sinkpad, event);
2900 gst_object_unref (demux);
2905 static GstFlowReturn
2906 gst_matroska_demux_seek_to_previous_keyframe (GstMatroskaDemux * demux)
2908 GstFlowReturn ret = GST_FLOW_UNEXPECTED;
2909 gboolean done = TRUE;
2912 g_return_val_if_fail (demux->seek_index, GST_FLOW_UNEXPECTED);
2913 g_return_val_if_fail (demux->seek_entry < demux->seek_index->len,
2914 GST_FLOW_UNEXPECTED);
2916 GST_DEBUG_OBJECT (demux, "locating previous keyframe");
2918 if (!demux->seek_entry) {
2919 GST_DEBUG_OBJECT (demux, "no earlier index entry");
2923 for (i = 0; i < demux->src->len; i++) {
2924 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->src, i);
2926 GST_DEBUG_OBJECT (demux, "segment start %" GST_TIME_FORMAT
2927 ", stream %d at %" GST_TIME_FORMAT,
2928 GST_TIME_ARGS (demux->segment.start), stream->index,
2929 GST_TIME_ARGS (stream->from_time));
2930 if (GST_CLOCK_TIME_IS_VALID (stream->from_time)) {
2931 if (stream->from_time > demux->segment.start) {
2932 GST_DEBUG_OBJECT (demux, "stream %d not finished yet", stream->index);
2936 /* nothing pushed for this stream;
2937 * likely seek entry did not start at keyframe, so all was skipped.
2938 * So we need an earlier entry */
2944 GstMatroskaIndex *entry;
2946 entry = &g_array_index (demux->seek_index, GstMatroskaIndex,
2947 --demux->seek_entry);
2948 if (!gst_matroska_demux_move_to_entry (demux, entry, FALSE))
2958 /* skip unknown or alike element */
2959 static GstFlowReturn
2960 gst_matroska_demux_parse_skip (GstMatroskaDemux * demux, GstEbmlRead * ebml,
2961 const gchar * parent_name, guint id)
2963 if (id == GST_EBML_ID_VOID) {
2964 GST_DEBUG_OBJECT (demux, "Skipping EBML Void element");
2965 } else if (id == GST_EBML_ID_CRC32) {
2966 GST_DEBUG_OBJECT (demux, "Skipping EBML CRC32 element");
2968 GST_WARNING_OBJECT (demux,
2969 "Unknown %s subelement 0x%x - ignoring", parent_name, id);
2972 return gst_ebml_read_skip (ebml);
2975 static GstFlowReturn
2976 gst_matroska_demux_parse_header (GstMatroskaDemux * demux, GstEbmlRead * ebml)
2983 /* this function is the first to be called */
2989 ret = gst_ebml_peek_id (ebml, &id);
2990 if (ret != GST_FLOW_OK)
2993 GST_DEBUG_OBJECT (demux, "id: %08x", id);
2995 if (id != GST_EBML_ID_HEADER) {
2996 GST_ERROR_OBJECT (demux, "Failed to read header");
3000 ret = gst_ebml_read_master (ebml, &id);
3001 if (ret != GST_FLOW_OK)
3004 while (gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3005 ret = gst_ebml_peek_id (ebml, &id);
3006 if (ret != GST_FLOW_OK)
3010 /* is our read version uptodate? */
3011 case GST_EBML_ID_EBMLREADVERSION:{
3014 ret = gst_ebml_read_uint (ebml, &id, &num);
3015 if (ret != GST_FLOW_OK)
3017 if (num != GST_EBML_VERSION) {
3018 GST_ERROR_OBJECT (ebml, "Unsupported EBML version %" G_GUINT64_FORMAT,
3020 return GST_FLOW_ERROR;
3023 GST_DEBUG_OBJECT (ebml, "EbmlReadVersion: %" G_GUINT64_FORMAT, num);
3027 /* we only handle 8 byte lengths at max */
3028 case GST_EBML_ID_EBMLMAXSIZELENGTH:{
3031 ret = gst_ebml_read_uint (ebml, &id, &num);
3032 if (ret != GST_FLOW_OK)
3034 if (num > sizeof (guint64)) {
3035 GST_ERROR_OBJECT (ebml,
3036 "Unsupported EBML maximum size %" G_GUINT64_FORMAT, num);
3037 return GST_FLOW_ERROR;
3039 GST_DEBUG_OBJECT (ebml, "EbmlMaxSizeLength: %" G_GUINT64_FORMAT, num);
3043 /* we handle 4 byte IDs at max */
3044 case GST_EBML_ID_EBMLMAXIDLENGTH:{
3047 ret = gst_ebml_read_uint (ebml, &id, &num);
3048 if (ret != GST_FLOW_OK)
3050 if (num > sizeof (guint32)) {
3051 GST_ERROR_OBJECT (ebml,
3052 "Unsupported EBML maximum ID %" G_GUINT64_FORMAT, num);
3053 return GST_FLOW_ERROR;
3055 GST_DEBUG_OBJECT (ebml, "EbmlMaxIdLength: %" G_GUINT64_FORMAT, num);
3059 case GST_EBML_ID_DOCTYPE:{
3062 ret = gst_ebml_read_ascii (ebml, &id, &text);
3063 if (ret != GST_FLOW_OK)
3066 GST_DEBUG_OBJECT (ebml, "EbmlDocType: %s", GST_STR_NULL (text));
3074 case GST_EBML_ID_DOCTYPEREADVERSION:{
3077 ret = gst_ebml_read_uint (ebml, &id, &num);
3078 if (ret != GST_FLOW_OK)
3081 GST_DEBUG_OBJECT (ebml, "EbmlReadVersion: %" G_GUINT64_FORMAT, num);
3086 ret = gst_matroska_demux_parse_skip (demux, ebml, "EBML header", id);
3087 if (ret != GST_FLOW_OK)
3091 /* we ignore these two, as they don't tell us anything we care about */
3092 case GST_EBML_ID_EBMLVERSION:
3093 case GST_EBML_ID_DOCTYPEVERSION:
3094 ret = gst_ebml_read_skip (ebml);
3095 if (ret != GST_FLOW_OK)
3102 ret = GST_FLOW_ERROR;
3104 if (g_str_equal (doctype, GST_MATROSKA_DOCTYPE_MATROSKA) ||
3105 g_str_equal (doctype, GST_MATROSKA_DOCTYPE_WEBM)) {
3107 GST_INFO_OBJECT (demux, "Input is %s version %d", doctype, version);
3110 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
3111 ("Demuxer version (2) is too old to read %s version %d",
3115 GST_ELEMENT_ERROR (demux, STREAM, WRONG_TYPE, (NULL),
3116 ("Input is not a matroska stream (doctype=%s)", doctype));
3120 GST_ELEMENT_ERROR (demux, STREAM, WRONG_TYPE, (NULL),
3121 ("Input is not a matroska stream"));
3127 static GstFlowReturn
3128 gst_matroska_demux_parse_tracks (GstMatroskaDemux * demux, GstEbmlRead * ebml)
3130 GstFlowReturn ret = GST_FLOW_OK;
3133 DEBUG_ELEMENT_START (demux, ebml, "Tracks");
3135 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3136 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
3140 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3141 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3145 /* one track within the "all-tracks" header */
3146 case GST_MATROSKA_ID_TRACKENTRY:
3147 ret = gst_matroska_demux_add_stream (demux, ebml);
3151 ret = gst_matroska_demux_parse_skip (demux, ebml, "Track", id);
3155 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
3157 demux->tracks_parsed = TRUE;
3162 static GstFlowReturn
3163 gst_matroska_demux_parse_index_cuetrack (GstMatroskaDemux * demux,
3164 GstEbmlRead * ebml, guint * nentries)
3168 GstMatroskaIndex idx;
3170 idx.pos = (guint64) - 1;
3172 idx.time = GST_CLOCK_TIME_NONE;
3175 DEBUG_ELEMENT_START (demux, ebml, "CueTrackPositions");
3177 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3178 DEBUG_ELEMENT_STOP (demux, ebml, "CueTrackPositions", ret);
3182 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3183 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3188 case GST_MATROSKA_ID_CUETRACK:
3192 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
3197 GST_WARNING_OBJECT (demux, "Invalid CueTrack 0");
3201 GST_DEBUG_OBJECT (demux, "CueTrack: %" G_GUINT64_FORMAT, num);
3206 /* position in file */
3207 case GST_MATROSKA_ID_CUECLUSTERPOSITION:
3211 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
3214 if (num > G_MAXINT64) {
3215 GST_WARNING_OBJECT (demux, "CueClusterPosition %" G_GUINT64_FORMAT
3224 /* number of block in the cluster */
3225 case GST_MATROSKA_ID_CUEBLOCKNUMBER:
3229 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
3233 GST_WARNING_OBJECT (demux, "Invalid CueBlockNumber 0");
3237 GST_DEBUG_OBJECT (demux, "CueBlockNumber: %" G_GUINT64_FORMAT, num);
3240 /* mild sanity check, disregard strange cases ... */
3241 if (idx.block > G_MAXUINT16) {
3242 GST_DEBUG_OBJECT (demux, "... looks suspicious, ignoring");
3249 ret = gst_matroska_demux_parse_skip (demux, ebml, "CueTrackPositions",
3253 case GST_MATROSKA_ID_CUECODECSTATE:
3254 case GST_MATROSKA_ID_CUEREFERENCE:
3255 ret = gst_ebml_read_skip (ebml);
3260 DEBUG_ELEMENT_STOP (demux, ebml, "CueTrackPositions", ret);
3262 if ((ret == GST_FLOW_OK || ret == GST_FLOW_UNEXPECTED)
3263 && idx.pos != (guint64) - 1 && idx.track > 0) {
3264 g_array_append_val (demux->index, idx);
3266 } else if (ret == GST_FLOW_OK || ret == GST_FLOW_UNEXPECTED) {
3267 GST_DEBUG_OBJECT (demux, "CueTrackPositions without valid content");
3273 static GstFlowReturn
3274 gst_matroska_demux_parse_index_pointentry (GstMatroskaDemux * demux,
3279 GstClockTime time = GST_CLOCK_TIME_NONE;
3282 DEBUG_ELEMENT_START (demux, ebml, "CuePoint");
3284 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3285 DEBUG_ELEMENT_STOP (demux, ebml, "CuePoint", ret);
3289 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3290 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3294 /* one single index entry ('point') */
3295 case GST_MATROSKA_ID_CUETIME:
3297 if ((ret = gst_ebml_read_uint (ebml, &id, &time)) != GST_FLOW_OK)
3300 GST_DEBUG_OBJECT (demux, "CueTime: %" G_GUINT64_FORMAT, time);
3301 time = time * demux->time_scale;
3305 /* position in the file + track to which it belongs */
3306 case GST_MATROSKA_ID_CUETRACKPOSITIONS:
3309 gst_matroska_demux_parse_index_cuetrack (demux, ebml,
3310 &nentries)) != GST_FLOW_OK)
3316 ret = gst_matroska_demux_parse_skip (demux, ebml, "CuePoint", id);
3321 DEBUG_ELEMENT_STOP (demux, ebml, "CuePoint", ret);
3324 if (time == GST_CLOCK_TIME_NONE) {
3325 GST_WARNING_OBJECT (demux, "CuePoint without valid time");
3326 g_array_remove_range (demux->index, demux->index->len - nentries,
3331 for (i = demux->index->len - nentries; i < demux->index->len; i++) {
3332 GstMatroskaIndex *idx =
3333 &g_array_index (demux->index, GstMatroskaIndex, i);
3336 GST_DEBUG_OBJECT (demux, "Index entry: pos=%" G_GUINT64_FORMAT
3337 ", time=%" GST_TIME_FORMAT ", track=%u, block=%u", idx->pos,
3338 GST_TIME_ARGS (idx->time), (guint) idx->track, (guint) idx->block);
3342 GST_DEBUG_OBJECT (demux, "Empty CuePoint");
3349 gst_matroska_index_compare (GstMatroskaIndex * i1, GstMatroskaIndex * i2)
3351 if (i1->time < i2->time)
3353 else if (i1->time > i2->time)
3355 else if (i1->block < i2->block)
3357 else if (i1->block > i2->block)
3363 static GstFlowReturn
3364 gst_matroska_demux_parse_index (GstMatroskaDemux * demux, GstEbmlRead * ebml)
3367 GstFlowReturn ret = GST_FLOW_OK;
3371 g_array_free (demux->index, TRUE);
3373 g_array_sized_new (FALSE, FALSE, sizeof (GstMatroskaIndex), 128);
3375 DEBUG_ELEMENT_START (demux, ebml, "Cues");
3377 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3378 DEBUG_ELEMENT_STOP (demux, ebml, "Cues", ret);
3382 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3383 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3387 /* one single index entry ('point') */
3388 case GST_MATROSKA_ID_POINTENTRY:
3389 ret = gst_matroska_demux_parse_index_pointentry (demux, ebml);
3393 ret = gst_matroska_demux_parse_skip (demux, ebml, "Cues", id);
3397 DEBUG_ELEMENT_STOP (demux, ebml, "Cues", ret);
3399 /* Sort index by time, smallest time first, for easier searching */
3400 g_array_sort (demux->index, (GCompareFunc) gst_matroska_index_compare);
3402 /* Now sort the track specific index entries into their own arrays */
3403 for (i = 0; i < demux->index->len; i++) {
3404 GstMatroskaIndex *idx = &g_array_index (demux->index, GstMatroskaIndex, i);
3406 GstMatroskaTrackContext *ctx;
3408 if (demux->element_index) {
3411 if (idx->track != 0 &&
3413 gst_matroska_demux_stream_from_num (demux, idx->track)) != -1) {
3414 ctx = g_ptr_array_index (demux->src, track_num);
3416 if (ctx->index_writer_id == -1)
3417 gst_index_get_writer_id (demux->element_index, GST_OBJECT (ctx->pad),
3418 &ctx->index_writer_id);
3419 writer_id = ctx->index_writer_id;
3421 if (demux->element_index_writer_id == -1)
3422 gst_index_get_writer_id (demux->element_index, GST_OBJECT (demux),
3423 &demux->element_index_writer_id);
3424 writer_id = demux->element_index_writer_id;
3427 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
3428 G_GUINT64_FORMAT " for writer id %d", GST_TIME_ARGS (idx->time),
3429 idx->pos, writer_id);
3430 gst_index_add_association (demux->element_index, writer_id,
3431 GST_ASSOCIATION_FLAG_KEY_UNIT, GST_FORMAT_TIME, idx->time,
3432 GST_FORMAT_BYTES, idx->pos + demux->ebml_segment_start, NULL);
3435 if (idx->track == 0)
3438 track_num = gst_matroska_demux_stream_from_num (demux, idx->track);
3439 if (track_num == -1)
3442 ctx = g_ptr_array_index (demux->src, track_num);
3444 if (ctx->index_table == NULL)
3446 g_array_sized_new (FALSE, FALSE, sizeof (GstMatroskaIndex), 128);
3448 g_array_append_vals (ctx->index_table, idx, 1);
3451 demux->index_parsed = TRUE;
3453 /* sanity check; empty index normalizes to no index */
3454 if (demux->index->len == 0) {
3455 g_array_free (demux->index, TRUE);
3456 demux->index = NULL;
3462 static GstFlowReturn
3463 gst_matroska_demux_parse_info (GstMatroskaDemux * demux, GstEbmlRead * ebml)
3465 GstFlowReturn ret = GST_FLOW_OK;
3468 DEBUG_ELEMENT_START (demux, ebml, "SegmentInfo");
3470 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3471 DEBUG_ELEMENT_STOP (demux, ebml, "SegmentInfo", ret);
3475 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3476 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3480 /* cluster timecode */
3481 case GST_MATROSKA_ID_TIMECODESCALE:{
3484 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
3488 GST_DEBUG_OBJECT (demux, "TimeCodeScale: %" G_GUINT64_FORMAT, num);
3489 demux->time_scale = num;
3493 case GST_MATROSKA_ID_DURATION:{
3497 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
3501 GST_WARNING_OBJECT (demux, "Invalid duration %lf", num);
3505 GST_DEBUG_OBJECT (demux, "Duration: %lf", num);
3507 dur = gst_gdouble_to_guint64 (num *
3508 gst_guint64_to_gdouble (demux->time_scale));
3509 if (GST_CLOCK_TIME_IS_VALID (dur) && dur <= G_MAXINT64)
3510 gst_segment_set_duration (&demux->segment, GST_FORMAT_TIME, dur);
3514 case GST_MATROSKA_ID_WRITINGAPP:{
3517 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
3520 GST_DEBUG_OBJECT (demux, "WritingApp: %s", GST_STR_NULL (text));
3521 demux->writing_app = text;
3525 case GST_MATROSKA_ID_MUXINGAPP:{
3528 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
3531 GST_DEBUG_OBJECT (demux, "MuxingApp: %s", GST_STR_NULL (text));
3532 demux->muxing_app = text;
3536 case GST_MATROSKA_ID_DATEUTC:{
3539 if ((ret = gst_ebml_read_date (ebml, &id, &time)) != GST_FLOW_OK)
3542 GST_DEBUG_OBJECT (demux, "DateUTC: %" G_GINT64_FORMAT, time);
3543 demux->created = time;
3547 case GST_MATROSKA_ID_TITLE:{
3549 GstTagList *taglist;
3551 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
3554 GST_DEBUG_OBJECT (demux, "Title: %s", GST_STR_NULL (text));
3555 taglist = gst_tag_list_new ();
3556 gst_tag_list_add (taglist, GST_TAG_MERGE_APPEND, GST_TAG_TITLE, text,
3558 gst_matroska_demux_found_global_tag (demux, taglist);
3564 ret = gst_matroska_demux_parse_skip (demux, ebml, "SegmentInfo", id);
3568 case GST_MATROSKA_ID_SEGMENTUID:
3569 case GST_MATROSKA_ID_SEGMENTFILENAME:
3570 case GST_MATROSKA_ID_PREVUID:
3571 case GST_MATROSKA_ID_PREVFILENAME:
3572 case GST_MATROSKA_ID_NEXTUID:
3573 case GST_MATROSKA_ID_NEXTFILENAME:
3574 case GST_MATROSKA_ID_SEGMENTFAMILY:
3575 case GST_MATROSKA_ID_CHAPTERTRANSLATE:
3576 ret = gst_ebml_read_skip (ebml);
3581 DEBUG_ELEMENT_STOP (demux, ebml, "SegmentInfo", ret);
3583 demux->segmentinfo_parsed = TRUE;
3588 static GstFlowReturn
3589 gst_matroska_demux_parse_metadata_id_simple_tag (GstMatroskaDemux * demux,
3590 GstEbmlRead * ebml, GstTagList ** p_taglist)
3592 /* FIXME: check if there are more useful mappings */
3595 const gchar *matroska_tagname;
3596 const gchar *gstreamer_tagname;
3600 GST_MATROSKA_TAG_ID_TITLE, GST_TAG_TITLE}, {
3601 GST_MATROSKA_TAG_ID_AUTHOR, GST_TAG_ARTIST}, {
3602 GST_MATROSKA_TAG_ID_ALBUM, GST_TAG_ALBUM}, {
3603 GST_MATROSKA_TAG_ID_COMMENTS, GST_TAG_COMMENT}, {
3604 GST_MATROSKA_TAG_ID_BITSPS, GST_TAG_BITRATE}, {
3605 GST_MATROSKA_TAG_ID_BPS, GST_TAG_BITRATE}, {
3606 GST_MATROSKA_TAG_ID_ENCODER, GST_TAG_ENCODER}, {
3607 GST_MATROSKA_TAG_ID_DATE, GST_TAG_DATE}, {
3608 GST_MATROSKA_TAG_ID_ISRC, GST_TAG_ISRC}, {
3609 GST_MATROSKA_TAG_ID_COPYRIGHT, GST_TAG_COPYRIGHT}, {
3610 GST_MATROSKA_TAG_ID_BPM, GST_TAG_BEATS_PER_MINUTE}, {
3611 GST_MATROSKA_TAG_ID_TERMS_OF_USE, GST_TAG_LICENSE}, {
3612 GST_MATROSKA_TAG_ID_COMPOSER, GST_TAG_COMPOSER}, {
3613 GST_MATROSKA_TAG_ID_LEAD_PERFORMER, GST_TAG_PERFORMER}, {
3614 GST_MATROSKA_TAG_ID_GENRE, GST_TAG_GENRE}
3618 gchar *value = NULL;
3621 DEBUG_ELEMENT_START (demux, ebml, "SimpleTag");
3623 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3624 DEBUG_ELEMENT_STOP (demux, ebml, "SimpleTag", ret);
3628 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3629 /* read all sub-entries */
3631 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3635 case GST_MATROSKA_ID_TAGNAME:
3638 ret = gst_ebml_read_ascii (ebml, &id, &tag);
3639 GST_DEBUG_OBJECT (demux, "TagName: %s", GST_STR_NULL (tag));
3642 case GST_MATROSKA_ID_TAGSTRING:
3645 ret = gst_ebml_read_utf8 (ebml, &id, &value);
3646 GST_DEBUG_OBJECT (demux, "TagString: %s", GST_STR_NULL (value));
3650 ret = gst_matroska_demux_parse_skip (demux, ebml, "SimpleTag", id);
3654 case GST_MATROSKA_ID_TAGLANGUAGE:
3655 case GST_MATROSKA_ID_TAGDEFAULT:
3656 case GST_MATROSKA_ID_TAGBINARY:
3657 ret = gst_ebml_read_skip (ebml);
3662 DEBUG_ELEMENT_STOP (demux, ebml, "SimpleTag", ret);
3667 for (i = 0; i < G_N_ELEMENTS (tag_conv); i++) {
3668 const gchar *tagname_gst = tag_conv[i].gstreamer_tagname;
3670 const gchar *tagname_mkv = tag_conv[i].matroska_tagname;
3672 if (strcmp (tagname_mkv, tag) == 0) {
3673 GValue dest = { 0, };
3674 GType dest_type = gst_tag_get_type (tagname_gst);
3676 /* Ensure that any date string is complete */
3677 if (dest_type == GST_TYPE_DATE) {
3678 guint year = 1901, month = 1, day = 1;
3680 /* Dates can be yyyy-MM-dd, yyyy-MM or yyyy, but we need
3682 if (sscanf (value, "%04u-%02u-%02u", &year, &month, &day) != 0) {
3684 value = g_strdup_printf ("%04u-%02u-%02u", year, month, day);
3688 g_value_init (&dest, dest_type);
3689 if (gst_value_deserialize (&dest, value)) {
3690 gst_tag_list_add_values (*p_taglist, GST_TAG_MERGE_APPEND,
3691 tagname_gst, &dest, NULL);
3693 GST_WARNING_OBJECT (demux, "Can't transform tag '%s' with "
3694 "value '%s' to target type '%s'", tag, value,
3695 g_type_name (dest_type));
3697 g_value_unset (&dest);
3709 static GstFlowReturn
3710 gst_matroska_demux_parse_metadata_id_tag (GstMatroskaDemux * demux,
3711 GstEbmlRead * ebml, GstTagList ** p_taglist)
3716 DEBUG_ELEMENT_START (demux, ebml, "Tag");
3718 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3719 DEBUG_ELEMENT_STOP (demux, ebml, "Tag", ret);
3723 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3724 /* read all sub-entries */
3726 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3730 case GST_MATROSKA_ID_SIMPLETAG:
3731 ret = gst_matroska_demux_parse_metadata_id_simple_tag (demux, ebml,
3736 ret = gst_matroska_demux_parse_skip (demux, ebml, "Tag", id);
3741 DEBUG_ELEMENT_STOP (demux, ebml, "Tag", ret);
3746 static GstFlowReturn
3747 gst_matroska_demux_parse_metadata (GstMatroskaDemux * demux, GstEbmlRead * ebml)
3749 GstTagList *taglist;
3750 GstFlowReturn ret = GST_FLOW_OK;
3755 curpos = gst_ebml_read_get_pos (ebml);
3757 /* Make sure we don't parse a tags element twice and
3758 * post it's tags twice */
3759 curpos = gst_ebml_read_get_pos (ebml);
3760 for (l = demux->tags_parsed; l; l = l->next) {
3761 guint64 *pos = l->data;
3763 if (*pos == curpos) {
3764 GST_DEBUG_OBJECT (demux, "Skipping already parsed Tags at offset %"
3765 G_GUINT64_FORMAT, curpos);
3770 demux->tags_parsed =
3771 g_list_prepend (demux->tags_parsed, g_slice_new (guint64));
3772 *((guint64 *) demux->tags_parsed->data) = curpos;
3775 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3776 DEBUG_ELEMENT_STOP (demux, ebml, "Tags", ret);
3780 taglist = gst_tag_list_new ();
3782 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3783 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3787 case GST_MATROSKA_ID_TAG:
3788 ret = gst_matroska_demux_parse_metadata_id_tag (demux, ebml, &taglist);
3792 ret = gst_matroska_demux_parse_skip (demux, ebml, "Tags", id);
3794 /* FIXME: Use to limit the tags to specific pads */
3795 case GST_MATROSKA_ID_TARGETS:
3796 ret = gst_ebml_read_skip (ebml);
3801 DEBUG_ELEMENT_STOP (demux, ebml, "Tags", ret);
3803 gst_matroska_demux_found_global_tag (demux, taglist);
3808 static GstFlowReturn
3809 gst_matroska_demux_parse_attached_file (GstMatroskaDemux * demux,
3810 GstEbmlRead * ebml, GstTagList * taglist)
3814 gchar *description = NULL;
3815 gchar *filename = NULL;
3816 gchar *mimetype = NULL;
3817 guint8 *data = NULL;
3818 guint64 datalen = 0;
3820 DEBUG_ELEMENT_START (demux, ebml, "AttachedFile");
3822 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3823 DEBUG_ELEMENT_STOP (demux, ebml, "AttachedFile", ret);
3827 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3828 /* read all sub-entries */
3830 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3834 case GST_MATROSKA_ID_FILEDESCRIPTION:
3836 GST_WARNING_OBJECT (demux, "FileDescription can only appear once");
3840 ret = gst_ebml_read_utf8 (ebml, &id, &description);
3841 GST_DEBUG_OBJECT (demux, "FileDescription: %s",
3842 GST_STR_NULL (description));
3844 case GST_MATROSKA_ID_FILENAME:
3846 GST_WARNING_OBJECT (demux, "FileName can only appear once");
3850 ret = gst_ebml_read_utf8 (ebml, &id, &filename);
3852 GST_DEBUG_OBJECT (demux, "FileName: %s", GST_STR_NULL (filename));
3854 case GST_MATROSKA_ID_FILEMIMETYPE:
3856 GST_WARNING_OBJECT (demux, "FileMimeType can only appear once");
3860 ret = gst_ebml_read_ascii (ebml, &id, &mimetype);
3861 GST_DEBUG_OBJECT (demux, "FileMimeType: %s", GST_STR_NULL (mimetype));
3863 case GST_MATROSKA_ID_FILEDATA:
3865 GST_WARNING_OBJECT (demux, "FileData can only appear once");
3869 ret = gst_ebml_read_binary (ebml, &id, &data, &datalen);
3870 GST_DEBUG_OBJECT (demux, "FileData of size %" G_GUINT64_FORMAT,
3875 ret = gst_matroska_demux_parse_skip (demux, ebml, "AttachedFile", id);
3877 case GST_MATROSKA_ID_FILEUID:
3878 ret = gst_ebml_read_skip (ebml);
3883 DEBUG_ELEMENT_STOP (demux, ebml, "AttachedFile", ret);
3885 if (filename && mimetype && data && datalen > 0) {
3886 GstTagImageType image_type = GST_TAG_IMAGE_TYPE_NONE;
3887 GstBuffer *tagbuffer = NULL;
3889 gchar *filename_lc = g_utf8_strdown (filename, -1);
3891 GST_DEBUG_OBJECT (demux, "Creating tag for attachment with filename '%s', "
3892 "mimetype '%s', description '%s', size %" G_GUINT64_FORMAT, filename,
3893 mimetype, GST_STR_NULL (description), datalen);
3895 /* TODO: better heuristics for different image types */
3896 if (strstr (filename_lc, "cover")) {
3897 if (strstr (filename_lc, "back"))
3898 image_type = GST_TAG_IMAGE_TYPE_BACK_COVER;
3900 image_type = GST_TAG_IMAGE_TYPE_FRONT_COVER;
3901 } else if (g_str_has_prefix (mimetype, "image/") ||
3902 g_str_has_suffix (filename_lc, "png") ||
3903 g_str_has_suffix (filename_lc, "jpg") ||
3904 g_str_has_suffix (filename_lc, "jpeg") ||
3905 g_str_has_suffix (filename_lc, "gif") ||
3906 g_str_has_suffix (filename_lc, "bmp")) {
3907 image_type = GST_TAG_IMAGE_TYPE_UNDEFINED;
3909 g_free (filename_lc);
3911 /* First try to create an image tag buffer from this */
3912 if (image_type != GST_TAG_IMAGE_TYPE_NONE) {
3914 gst_tag_image_data_to_image_buffer (data, datalen, image_type);
3917 image_type = GST_TAG_IMAGE_TYPE_NONE;
3920 /* if this failed create an attachment buffer */
3922 tagbuffer = gst_buffer_new_and_alloc (datalen);
3924 memcpy (GST_BUFFER_DATA (tagbuffer), data, datalen);
3925 GST_BUFFER_SIZE (tagbuffer) = datalen;
3927 caps = gst_type_find_helper_for_buffer (NULL, tagbuffer, NULL);
3929 caps = gst_caps_new_simple (mimetype, NULL);
3930 gst_buffer_set_caps (tagbuffer, caps);
3931 gst_caps_unref (caps);
3934 /* Set filename and description on the caps */
3935 caps = GST_BUFFER_CAPS (tagbuffer);
3936 gst_caps_set_simple (caps, "filename", G_TYPE_STRING, filename, NULL);
3938 gst_caps_set_simple (caps, "description", G_TYPE_STRING, description,
3941 GST_DEBUG_OBJECT (demux,
3942 "Created attachment buffer with caps: %" GST_PTR_FORMAT, caps);
3944 /* and append to the tag list */
3945 if (image_type != GST_TAG_IMAGE_TYPE_NONE)
3946 gst_tag_list_add (taglist, GST_TAG_MERGE_APPEND, GST_TAG_IMAGE, tagbuffer,
3949 gst_tag_list_add (taglist, GST_TAG_MERGE_APPEND, GST_TAG_ATTACHMENT,
3956 g_free (description);
3961 static GstFlowReturn
3962 gst_matroska_demux_parse_attachments (GstMatroskaDemux * demux,
3966 GstFlowReturn ret = GST_FLOW_OK;
3967 GstTagList *taglist;
3969 DEBUG_ELEMENT_START (demux, ebml, "Attachments");
3971 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3972 DEBUG_ELEMENT_STOP (demux, ebml, "Attachments", ret);
3976 taglist = gst_tag_list_new ();
3978 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3979 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3983 case GST_MATROSKA_ID_ATTACHEDFILE:
3984 ret = gst_matroska_demux_parse_attached_file (demux, ebml, taglist);
3988 ret = gst_matroska_demux_parse_skip (demux, ebml, "Attachments", id);
3992 DEBUG_ELEMENT_STOP (demux, ebml, "Attachments", ret);
3994 if (gst_structure_n_fields (GST_STRUCTURE (taglist)) > 0) {
3995 GST_DEBUG_OBJECT (demux, "Storing attachment tags");
3996 gst_matroska_demux_found_global_tag (demux, taglist);
3998 GST_DEBUG_OBJECT (demux, "No valid attachments found");
3999 gst_tag_list_free (taglist);
4002 demux->attachments_parsed = TRUE;
4007 static GstFlowReturn
4008 gst_matroska_demux_parse_chapters (GstMatroskaDemux * demux, GstEbmlRead * ebml)
4011 GstFlowReturn ret = GST_FLOW_OK;
4013 GST_WARNING_OBJECT (demux, "Parsing of chapters not implemented yet");
4015 /* TODO: implement parsing of chapters */
4017 DEBUG_ELEMENT_START (demux, ebml, "Chapters");
4019 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
4020 DEBUG_ELEMENT_STOP (demux, ebml, "Chapters", ret);
4024 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
4025 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
4030 ret = gst_ebml_read_skip (ebml);
4035 DEBUG_ELEMENT_STOP (demux, ebml, "Chapters", ret);
4040 * Read signed/unsigned "EBML" numbers.
4041 * Return: number of bytes processed.
4045 gst_matroska_ebmlnum_uint (guint8 * data, guint size, guint64 * num)
4047 gint len_mask = 0x80, read = 1, n = 1, num_ffs = 0;
4055 while (read <= 8 && !(total & len_mask)) {
4062 if ((total &= (len_mask - 1)) == len_mask - 1)
4067 if (data[n] == 0xff)
4069 total = (total << 8) | data[n];
4073 if (read == num_ffs && total != 0)
4082 gst_matroska_ebmlnum_sint (guint8 * data, guint size, gint64 * num)
4087 /* read as unsigned number first */
4088 if ((res = gst_matroska_ebmlnum_uint (data, size, &unum)) < 0)
4092 if (unum == G_MAXUINT64)
4095 *num = unum - ((1 << ((7 * res) - 1)) - 1);
4101 * Mostly used for subtitles. We add void filler data for each
4102 * lagging stream to make sure we don't deadlock.
4106 gst_matroska_demux_sync_streams (GstMatroskaDemux * demux)
4110 GST_LOG_OBJECT (demux, "Sync to %" GST_TIME_FORMAT,
4111 GST_TIME_ARGS (demux->segment.last_stop));
4113 g_assert (demux->num_streams == demux->src->len);
4114 for (stream_nr = 0; stream_nr < demux->src->len; stream_nr++) {
4115 GstMatroskaTrackContext *context;
4117 context = g_ptr_array_index (demux->src, stream_nr);
4119 GST_LOG_OBJECT (demux,
4120 "Checking for resync on stream %d (%" GST_TIME_FORMAT ")", stream_nr,
4121 GST_TIME_ARGS (context->pos));
4123 if (G_LIKELY (context->type != GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
4124 GST_LOG_OBJECT (demux, "Skipping sync on non-subtitle stream");
4128 /* does it lag? 0.5 seconds is a random threshold...
4129 * lag need only be considered if we have advanced into requested segment */
4130 if (GST_CLOCK_TIME_IS_VALID (context->pos) &&
4131 GST_CLOCK_TIME_IS_VALID (demux->segment.last_stop) &&
4132 demux->segment.last_stop > demux->segment.start &&
4133 context->pos + (GST_SECOND / 2) < demux->segment.last_stop) {
4136 new_start = demux->segment.last_stop - (GST_SECOND / 2);
4137 if (GST_CLOCK_TIME_IS_VALID (demux->segment.stop))
4138 new_start = MIN (new_start, demux->segment.stop);
4139 GST_DEBUG_OBJECT (demux,
4140 "Synchronizing stream %d with others by advancing time " "from %"
4141 GST_TIME_FORMAT " to %" GST_TIME_FORMAT, stream_nr,
4142 GST_TIME_ARGS (context->pos), GST_TIME_ARGS (new_start));
4144 context->pos = new_start;
4146 /* advance stream time */
4147 gst_pad_push_event (context->pad,
4148 gst_event_new_new_segment (TRUE, demux->segment.rate,
4149 demux->segment.format, new_start,
4150 demux->segment.stop, new_start));
4155 static GstFlowReturn
4156 gst_matroska_demux_push_hdr_buf (GstMatroskaDemux * demux,
4157 GstMatroskaTrackContext * stream, guint8 * data, guint len)
4159 GstFlowReturn ret, cret;
4160 GstBuffer *header_buf = NULL;
4162 ret = gst_pad_alloc_buffer_and_set_caps (stream->pad,
4163 GST_BUFFER_OFFSET_NONE, len, stream->caps, &header_buf);
4165 /* we combine but don't use the combined value to check if we have a buffer
4166 * or not. The combined value is what we return. */
4167 cret = gst_matroska_demux_combine_flows (demux, stream, ret);
4168 if (ret != GST_FLOW_OK)
4171 memcpy (GST_BUFFER_DATA (header_buf), data, len);
4173 if (stream->set_discont) {
4174 GST_BUFFER_FLAG_SET (header_buf, GST_BUFFER_FLAG_DISCONT);
4175 stream->set_discont = FALSE;
4178 ret = gst_pad_push (stream->pad, header_buf);
4181 cret = gst_matroska_demux_combine_flows (demux, stream, ret);
4188 GST_DEBUG_OBJECT (demux, "could not alloc buffer: %s, combined %s",
4189 gst_flow_get_name (ret), gst_flow_get_name (cret));
4194 static GstFlowReturn
4195 gst_matroska_demux_push_flac_codec_priv_data (GstMatroskaDemux * demux,
4196 GstMatroskaTrackContext * stream)
4202 GST_LOG_OBJECT (demux, "priv data size = %u", stream->codec_priv_size);
4204 pdata = (guint8 *) stream->codec_priv;
4206 /* need at least 'fLaC' marker + STREAMINFO metadata block */
4207 if (stream->codec_priv_size < ((4) + (4 + 34))) {
4208 GST_WARNING_OBJECT (demux, "not enough codec priv data for flac headers");
4209 return GST_FLOW_ERROR;
4212 if (memcmp (pdata, "fLaC", 4) != 0) {
4213 GST_WARNING_OBJECT (demux, "no flac marker at start of stream headers");
4214 return GST_FLOW_ERROR;
4217 ret = gst_matroska_demux_push_hdr_buf (demux, stream, pdata, 4);
4218 if (ret != GST_FLOW_OK)
4221 off = 4; /* skip fLaC marker */
4222 while (off < stream->codec_priv_size) {
4223 len = GST_READ_UINT8 (pdata + off + 1) << 16;
4224 len |= GST_READ_UINT8 (pdata + off + 2) << 8;
4225 len |= GST_READ_UINT8 (pdata + off + 3);
4227 GST_DEBUG_OBJECT (demux, "header packet: len=%u bytes, flags=0x%02x",
4228 len, (guint) pdata[off]);
4230 ret = gst_matroska_demux_push_hdr_buf (demux, stream, pdata + off, len + 4);
4231 if (ret != GST_FLOW_OK)
4239 static GstFlowReturn
4240 gst_matroska_demux_push_speex_codec_priv_data (GstMatroskaDemux * demux,
4241 GstMatroskaTrackContext * stream)
4246 GST_LOG_OBJECT (demux, "priv data size = %u", stream->codec_priv_size);
4248 pdata = (guint8 *) stream->codec_priv;
4250 /* need at least 'fLaC' marker + STREAMINFO metadata block */
4251 if (stream->codec_priv_size < 80) {
4252 GST_WARNING_OBJECT (demux, "not enough codec priv data for speex headers");
4253 return GST_FLOW_ERROR;
4256 if (memcmp (pdata, "Speex ", 8) != 0) {
4257 GST_WARNING_OBJECT (demux, "no Speex marker at start of stream headers");
4258 return GST_FLOW_ERROR;
4261 ret = gst_matroska_demux_push_hdr_buf (demux, stream, pdata, 80);
4262 if (ret != GST_FLOW_OK)
4265 if (stream->codec_priv_size == 80)
4268 return gst_matroska_demux_push_hdr_buf (demux, stream, pdata + 80,
4269 stream->codec_priv_size - 80);
4272 static GstFlowReturn
4273 gst_matroska_demux_push_xiph_codec_priv_data (GstMatroskaDemux * demux,
4274 GstMatroskaTrackContext * stream)
4277 guint8 *p = (guint8 *) stream->codec_priv;
4278 gint i, offset, num_packets;
4279 guint *length, last;
4281 if (stream->codec_priv == NULL || stream->codec_priv_size == 0) {
4282 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4283 ("Missing codec private data for xiph headers, broken file"));
4284 return GST_FLOW_ERROR;
4287 /* start of the stream and vorbis audio or theora video, need to
4288 * send the codec_priv data as first three packets */
4289 num_packets = p[0] + 1;
4290 GST_DEBUG_OBJECT (demux, "%u stream headers, total length=%u bytes",
4291 (guint) num_packets, stream->codec_priv_size);
4293 length = g_alloca (num_packets * sizeof (guint));
4297 /* first packets, read length values */
4298 for (i = 0; i < num_packets - 1; i++) {
4300 while (offset < stream->codec_priv_size) {
4301 length[i] += p[offset];
4302 if (p[offset++] != 0xff)
4307 if (offset + last > stream->codec_priv_size)
4308 return GST_FLOW_ERROR;
4310 /* last packet is the remaining size */
4311 length[i] = stream->codec_priv_size - offset - last;
4313 for (i = 0; i < num_packets; i++) {
4314 GST_DEBUG_OBJECT (demux, "buffer %d: length=%u bytes", i,
4316 if (offset + length[i] > stream->codec_priv_size)
4317 return GST_FLOW_ERROR;
4320 gst_matroska_demux_push_hdr_buf (demux, stream, p + offset, length[i]);
4321 if (ret != GST_FLOW_OK)
4324 offset += length[i];
4330 gst_matroska_demux_push_dvd_clut_change_event (GstMatroskaDemux * demux,
4331 GstMatroskaTrackContext * stream)
4335 g_assert (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB));
4337 if (!stream->codec_priv)
4340 /* ideally, VobSub private data should be parsed and stored more convenient
4341 * elsewhere, but for now, only interested in a small part */
4343 /* make sure we have terminating 0 */
4344 buf = g_strndup ((gchar *) stream->codec_priv, stream->codec_priv_size);
4346 /* just locate and parse palette part */
4347 start = strstr (buf, "palette:");
4352 guint8 r, g, b, y, u, v;
4355 while (g_ascii_isspace (*start))
4357 for (i = 0; i < 16; i++) {
4358 if (sscanf (start, "%06x", &col) != 1)
4361 while ((*start == ',') || g_ascii_isspace (*start))
4363 /* sigh, need to convert this from vobsub pseudo-RGB to YUV */
4364 r = (col >> 16) & 0xff;
4365 g = (col >> 8) & 0xff;
4367 y = CLAMP ((0.1494 * r + 0.6061 * g + 0.2445 * b) * 219 / 255 + 16, 0,
4369 u = CLAMP (0.6066 * r - 0.4322 * g - 0.1744 * b + 128, 0, 255);
4370 v = CLAMP (-0.08435 * r - 0.3422 * g + 0.4266 * b + 128, 0, 255);
4371 clut[i] = (y << 16) | (u << 8) | v;
4374 /* got them all without problems; build and send event */
4378 s = gst_structure_new ("application/x-gst-dvd", "event", G_TYPE_STRING,
4379 "dvd-spu-clut-change", "clut00", G_TYPE_INT, clut[0], "clut01",
4380 G_TYPE_INT, clut[1], "clut02", G_TYPE_INT, clut[2], "clut03",
4381 G_TYPE_INT, clut[3], "clut04", G_TYPE_INT, clut[4], "clut05",
4382 G_TYPE_INT, clut[5], "clut06", G_TYPE_INT, clut[6], "clut07",
4383 G_TYPE_INT, clut[7], "clut08", G_TYPE_INT, clut[8], "clut09",
4384 G_TYPE_INT, clut[9], "clut10", G_TYPE_INT, clut[10], "clut11",
4385 G_TYPE_INT, clut[11], "clut12", G_TYPE_INT, clut[12], "clut13",
4386 G_TYPE_INT, clut[13], "clut14", G_TYPE_INT, clut[14], "clut15",
4387 G_TYPE_INT, clut[15], NULL);
4389 gst_pad_push_event (stream->pad,
4390 gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM, s));
4396 static GstFlowReturn
4397 gst_matroska_demux_add_mpeg_seq_header (GstElement * element,
4398 GstMatroskaTrackContext * stream, GstBuffer ** buf)
4400 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
4402 guint seq_header_len;
4405 if (stream->codec_state) {
4406 seq_header = stream->codec_state;
4407 seq_header_len = stream->codec_state_size;
4408 } else if (stream->codec_priv) {
4409 seq_header = stream->codec_priv;
4410 seq_header_len = stream->codec_priv_size;
4415 /* Sequence header only needed for keyframes */
4416 if (GST_BUFFER_FLAG_IS_SET (*buf, GST_BUFFER_FLAG_DELTA_UNIT))
4419 if (GST_BUFFER_SIZE (*buf) < 4)
4422 header = GST_READ_UINT32_BE (GST_BUFFER_DATA (*buf));
4423 /* Sequence start code, if not found prepend */
4424 if (header != 0x000001b3) {
4426 GstFlowReturn ret, cret;
4428 ret = gst_pad_alloc_buffer_and_set_caps (stream->pad,
4429 GST_BUFFER_OFFSET_NONE, GST_BUFFER_SIZE (*buf) + seq_header_len,
4430 stream->caps, &newbuf);
4431 cret = gst_matroska_demux_combine_flows (demux, stream, ret);
4432 if (ret != GST_FLOW_OK) {
4433 GST_WARNING_OBJECT (demux, "Reallocating buffer for sequence header "
4434 "failed: %s, combined flow return: %s", gst_flow_get_name (ret),
4435 gst_flow_get_name (cret));
4439 GST_DEBUG_OBJECT (demux, "Prepending MPEG sequence header");
4440 gst_buffer_copy_metadata (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
4441 GST_BUFFER_COPY_FLAGS);
4442 g_memmove (GST_BUFFER_DATA (newbuf), seq_header, seq_header_len);
4443 g_memmove (GST_BUFFER_DATA (newbuf) + seq_header_len,
4444 GST_BUFFER_DATA (*buf), GST_BUFFER_SIZE (*buf));
4445 gst_buffer_unref (*buf);
4452 static GstFlowReturn
4453 gst_matroska_demux_add_wvpk_header (GstElement * element,
4454 GstMatroskaTrackContext * stream, GstBuffer ** buf)
4456 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
4457 GstMatroskaTrackAudioContext *audiocontext =
4458 (GstMatroskaTrackAudioContext *) stream;
4459 GstBuffer *newbuf = NULL;
4462 GstFlowReturn ret, cret = GST_FLOW_OK;
4470 wvh.version = GST_READ_UINT16_LE (stream->codec_priv);
4473 wvh.total_samples = -1;
4474 wvh.block_index = audiocontext->wvpk_block_index;
4476 if (audiocontext->channels <= 2) {
4477 guint32 block_samples;
4479 block_samples = GST_READ_UINT32_LE (GST_BUFFER_DATA (*buf));
4480 /* we need to reconstruct the header of the wavpack block */
4482 /* -20 because ck_size is the size of the wavpack block -8
4483 * and lace_size is the size of the wavpack block + 12
4484 * (the three guint32 of the header that already are in the buffer) */
4485 wvh.ck_size = GST_BUFFER_SIZE (*buf) + sizeof (Wavpack4Header) - 20;
4487 /* block_samples, flags and crc are already in the buffer */
4488 newlen = GST_BUFFER_SIZE (*buf) + sizeof (Wavpack4Header) - 12;
4490 gst_pad_alloc_buffer_and_set_caps (stream->pad, GST_BUFFER_OFFSET_NONE,
4491 newlen, stream->caps, &newbuf);
4492 cret = gst_matroska_demux_combine_flows (demux, stream, ret);
4493 if (ret != GST_FLOW_OK) {
4494 GST_DEBUG_OBJECT (demux, "pad_alloc failed %s, combined %s",
4495 gst_flow_get_name (ret), gst_flow_get_name (cret));
4499 data = GST_BUFFER_DATA (newbuf);
4504 GST_WRITE_UINT32_LE (data + 4, wvh.ck_size);
4505 GST_WRITE_UINT16_LE (data + 8, wvh.version);
4506 GST_WRITE_UINT8 (data + 10, wvh.track_no);
4507 GST_WRITE_UINT8 (data + 11, wvh.index_no);
4508 GST_WRITE_UINT32_LE (data + 12, wvh.total_samples);
4509 GST_WRITE_UINT32_LE (data + 16, wvh.block_index);
4510 g_memmove (data + 20, GST_BUFFER_DATA (*buf), GST_BUFFER_SIZE (*buf));
4511 gst_buffer_copy_metadata (newbuf, *buf,
4512 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS);
4513 gst_buffer_unref (*buf);
4515 audiocontext->wvpk_block_index += block_samples;
4520 guint32 block_samples, flags, crc, blocksize;
4522 data = GST_BUFFER_DATA (*buf);
4523 size = GST_BUFFER_SIZE (*buf);
4526 GST_ERROR_OBJECT (demux, "Too small wavpack buffer");
4527 return GST_FLOW_ERROR;
4530 block_samples = GST_READ_UINT32_LE (data);
4535 flags = GST_READ_UINT32_LE (data);
4538 crc = GST_READ_UINT32_LE (data);
4541 blocksize = GST_READ_UINT32_LE (data);
4545 if (blocksize == 0 || size < blocksize)
4548 if (newbuf == NULL) {
4549 newbuf = gst_buffer_new_and_alloc (sizeof (Wavpack4Header) + blocksize);
4550 gst_buffer_set_caps (newbuf, stream->caps);
4552 gst_buffer_copy_metadata (newbuf, *buf,
4553 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS);
4556 outdata = GST_BUFFER_DATA (newbuf);
4558 GST_BUFFER_SIZE (newbuf) += sizeof (Wavpack4Header) + blocksize;
4559 GST_BUFFER_DATA (newbuf) =
4560 g_realloc (GST_BUFFER_DATA (newbuf), GST_BUFFER_SIZE (newbuf));
4561 GST_BUFFER_MALLOCDATA (newbuf) = GST_BUFFER_DATA (newbuf);
4562 outdata = GST_BUFFER_DATA (newbuf);
4565 outdata[outpos] = 'w';
4566 outdata[outpos + 1] = 'v';
4567 outdata[outpos + 2] = 'p';
4568 outdata[outpos + 3] = 'k';
4571 GST_WRITE_UINT32_LE (outdata + outpos,
4572 blocksize + sizeof (Wavpack4Header) - 8);
4573 GST_WRITE_UINT16_LE (outdata + outpos + 4, wvh.version);
4574 GST_WRITE_UINT8 (outdata + outpos + 6, wvh.track_no);
4575 GST_WRITE_UINT8 (outdata + outpos + 7, wvh.index_no);
4576 GST_WRITE_UINT32_LE (outdata + outpos + 8, wvh.total_samples);
4577 GST_WRITE_UINT32_LE (outdata + outpos + 12, wvh.block_index);
4578 GST_WRITE_UINT32_LE (outdata + outpos + 16, block_samples);
4579 GST_WRITE_UINT32_LE (outdata + outpos + 20, flags);
4580 GST_WRITE_UINT32_LE (outdata + outpos + 24, crc);
4583 g_memmove (outdata + outpos, data, blocksize);
4584 outpos += blocksize;
4588 gst_buffer_unref (*buf);
4590 audiocontext->wvpk_block_index += block_samples;
4596 static GstFlowReturn
4597 gst_matroska_demux_check_subtitle_buffer (GstElement * element,
4598 GstMatroskaTrackContext * stream, GstBuffer ** buf)
4600 GstMatroskaTrackSubtitleContext *sub_stream;
4601 const gchar *encoding, *data;
4607 sub_stream = (GstMatroskaTrackSubtitleContext *) stream;
4609 data = (const gchar *) GST_BUFFER_DATA (*buf);
4610 size = GST_BUFFER_SIZE (*buf);
4612 if (!sub_stream->invalid_utf8) {
4613 if (g_utf8_validate (data, size, NULL)) {
4616 GST_WARNING_OBJECT (element, "subtitle stream %d is not valid UTF-8, this "
4617 "is broken according to the matroska specification", stream->num);
4618 sub_stream->invalid_utf8 = TRUE;
4621 /* file with broken non-UTF8 subtitle, do the best we can do to fix it */
4622 encoding = g_getenv ("GST_SUBTITLE_ENCODING");
4623 if (encoding == NULL || *encoding == '\0') {
4624 /* if local encoding is UTF-8 and no encoding specified
4625 * via the environment variable, assume ISO-8859-15 */
4626 if (g_get_charset (&encoding)) {
4627 encoding = "ISO-8859-15";
4631 utf8 = g_convert_with_fallback (data, size, "UTF-8", encoding, (char *) "*",
4635 GST_LOG_OBJECT (element, "could not convert string from '%s' to UTF-8: %s",
4636 encoding, err->message);
4640 /* invalid input encoding, fall back to ISO-8859-15 (always succeeds) */
4641 encoding = "ISO-8859-15";
4642 utf8 = g_convert_with_fallback (data, size, "UTF-8", encoding, (char *) "*",
4646 GST_LOG_OBJECT (element, "converted subtitle text from %s to UTF-8 %s",
4647 encoding, (err) ? "(using ISO-8859-15 as fallback)" : "");
4650 utf8 = g_strdup ("invalid subtitle");
4652 newbuf = gst_buffer_new ();
4653 GST_BUFFER_MALLOCDATA (newbuf) = (guint8 *) utf8;
4654 GST_BUFFER_DATA (newbuf) = (guint8 *) utf8;
4655 GST_BUFFER_SIZE (newbuf) = strlen (utf8);
4656 gst_buffer_copy_metadata (newbuf, *buf,
4657 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS);
4658 gst_buffer_unref (*buf);
4664 static GstFlowReturn
4665 gst_matroska_demux_check_aac (GstElement * element,
4666 GstMatroskaTrackContext * stream, GstBuffer ** buf)
4671 data = GST_BUFFER_DATA (*buf);
4672 size = GST_BUFFER_SIZE (*buf);
4674 if (size > 2 && data[0] == 0xff && (data[1] >> 4 == 0x0f)) {
4678 /* tss, ADTS data, remove codec_data
4679 * still assume it is at least parsed */
4680 new_caps = gst_caps_copy (stream->caps);
4681 s = gst_caps_get_structure (new_caps, 0);
4683 gst_structure_remove_field (s, "codec_data");
4684 gst_caps_replace (&stream->caps, new_caps);
4685 gst_pad_set_caps (stream->pad, new_caps);
4686 gst_buffer_set_caps (*buf, new_caps);
4687 GST_DEBUG_OBJECT (element, "ADTS AAC audio data; removing codec-data, "
4688 "new caps: %" GST_PTR_FORMAT, new_caps);
4689 gst_caps_unref (new_caps);
4692 /* disable subsequent checking */
4693 stream->postprocess_frame = NULL;
4698 static GstFlowReturn
4699 gst_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux,
4700 GstEbmlRead * ebml, guint64 cluster_time, guint64 cluster_offset,
4701 gboolean is_simpleblock)
4703 GstMatroskaTrackContext *stream = NULL;
4704 GstFlowReturn ret = GST_FLOW_OK;
4705 gboolean readblock = FALSE;
4707 guint64 block_duration = 0;
4708 GstBuffer *buf = NULL;
4709 gint stream_num = -1, n, laces = 0;
4711 gint *lace_size = NULL;
4714 gint64 referenceblock = 0;
4717 offset = gst_ebml_read_get_offset (ebml);
4719 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
4720 if (!is_simpleblock) {
4721 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK) {
4725 id = GST_MATROSKA_ID_SIMPLEBLOCK;
4729 /* one block inside the group. Note, block parsing is one
4730 * of the harder things, so this code is a bit complicated.
4731 * See http://www.matroska.org/ for documentation. */
4732 case GST_MATROSKA_ID_SIMPLEBLOCK:
4733 case GST_MATROSKA_ID_BLOCK:
4739 gst_buffer_unref (buf);
4742 if ((ret = gst_ebml_read_buffer (ebml, &id, &buf)) != GST_FLOW_OK)
4745 data = GST_BUFFER_DATA (buf);
4746 size = GST_BUFFER_SIZE (buf);
4748 /* first byte(s): blocknum */
4749 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
4754 /* fetch stream from num */
4755 stream_num = gst_matroska_demux_stream_from_num (demux, num);
4756 if (G_UNLIKELY (size < 3)) {
4757 GST_WARNING_OBJECT (demux, "Invalid size %u", size);
4758 /* non-fatal, try next block(group) */
4761 } else if (G_UNLIKELY (stream_num < 0 ||
4762 stream_num >= demux->num_streams)) {
4763 /* let's not give up on a stray invalid track number */
4764 GST_WARNING_OBJECT (demux,
4765 "Invalid stream %d for track number %" G_GUINT64_FORMAT
4766 "; ignoring block", stream_num, num);
4770 stream = g_ptr_array_index (demux->src, stream_num);
4772 /* time (relative to cluster time) */
4773 time = ((gint16) GST_READ_UINT16_BE (data));
4776 flags = GST_READ_UINT8 (data);
4780 GST_LOG_OBJECT (demux, "time %" G_GUINT64_FORMAT ", flags %d", time,
4783 switch ((flags & 0x06) >> 1) {
4784 case 0x0: /* no lacing */
4786 lace_size = g_new (gint, 1);
4787 lace_size[0] = size;
4790 case 0x1: /* xiph lacing */
4791 case 0x2: /* fixed-size lacing */
4792 case 0x3: /* EBML lacing */
4794 goto invalid_lacing;
4795 laces = GST_READ_UINT8 (data) + 1;
4798 lace_size = g_new0 (gint, laces);
4800 switch ((flags & 0x06) >> 1) {
4801 case 0x1: /* xiph lacing */ {
4802 guint temp, total = 0;
4804 for (n = 0; ret == GST_FLOW_OK && n < laces - 1; n++) {
4807 goto invalid_lacing;
4808 temp = GST_READ_UINT8 (data);
4809 lace_size[n] += temp;
4815 total += lace_size[n];
4817 lace_size[n] = size - total;
4821 case 0x2: /* fixed-size lacing */
4822 for (n = 0; n < laces; n++)
4823 lace_size[n] = size / laces;
4826 case 0x3: /* EBML lacing */ {
4829 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
4833 total = lace_size[0] = num;
4834 for (n = 1; ret == GST_FLOW_OK && n < laces - 1; n++) {
4838 if ((r = gst_matroska_ebmlnum_sint (data, size, &snum)) < 0)
4842 lace_size[n] = lace_size[n - 1] + snum;
4843 total += lace_size[n];
4846 lace_size[n] = size - total;
4853 if (stream->send_xiph_headers) {
4854 ret = gst_matroska_demux_push_xiph_codec_priv_data (demux, stream);
4855 stream->send_xiph_headers = FALSE;
4858 if (stream->send_flac_headers) {
4859 ret = gst_matroska_demux_push_flac_codec_priv_data (demux, stream);
4860 stream->send_flac_headers = FALSE;
4863 if (stream->send_speex_headers) {
4864 ret = gst_matroska_demux_push_speex_codec_priv_data (demux, stream);
4865 stream->send_speex_headers = FALSE;
4868 if (stream->send_dvd_event) {
4869 gst_matroska_demux_push_dvd_clut_change_event (demux, stream);
4870 /* FIXME: should we send this event again after (flushing) seek ? */
4871 stream->send_dvd_event = FALSE;
4874 if (ret != GST_FLOW_OK)
4881 case GST_MATROSKA_ID_BLOCKDURATION:{
4882 ret = gst_ebml_read_uint (ebml, &id, &block_duration);
4883 GST_DEBUG_OBJECT (demux, "BlockDuration: %" G_GUINT64_FORMAT,
4888 case GST_MATROSKA_ID_REFERENCEBLOCK:{
4889 ret = gst_ebml_read_sint (ebml, &id, &referenceblock);
4890 GST_DEBUG_OBJECT (demux, "ReferenceBlock: %" G_GINT64_FORMAT,
4895 case GST_MATROSKA_ID_CODECSTATE:{
4897 guint64 data_len = 0;
4900 gst_ebml_read_binary (ebml, &id, &data,
4901 &data_len)) != GST_FLOW_OK)
4904 if (G_UNLIKELY (stream == NULL)) {
4905 GST_WARNING_OBJECT (demux,
4906 "Unexpected CodecState subelement - ignoring");
4910 g_free (stream->codec_state);
4911 stream->codec_state = data;
4912 stream->codec_state_size = data_len;
4914 /* Decode if necessary */
4915 if (stream->encodings && stream->encodings->len > 0
4916 && stream->codec_state && stream->codec_state_size > 0) {
4917 if (!gst_matroska_decode_data (stream->encodings,
4918 &stream->codec_state, &stream->codec_state_size,
4919 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
4920 GST_WARNING_OBJECT (demux, "Decoding codec state failed");
4924 GST_DEBUG_OBJECT (demux, "CodecState of %u bytes",
4925 stream->codec_state_size);
4930 ret = gst_matroska_demux_parse_skip (demux, ebml, "BlockGroup", id);
4933 case GST_MATROSKA_ID_BLOCKVIRTUAL:
4934 case GST_MATROSKA_ID_BLOCKADDITIONS:
4935 case GST_MATROSKA_ID_REFERENCEPRIORITY:
4936 case GST_MATROSKA_ID_REFERENCEVIRTUAL:
4937 case GST_MATROSKA_ID_SLICES:
4938 GST_DEBUG_OBJECT (demux,
4939 "Skipping BlockGroup subelement 0x%x - ignoring", id);
4940 ret = gst_ebml_read_skip (ebml);
4948 /* reading a number or so could have failed */
4949 if (ret != GST_FLOW_OK)
4952 if (ret == GST_FLOW_OK && readblock) {
4953 guint64 duration = 0;
4954 gint64 lace_time = 0;
4955 gboolean delta_unit;
4957 stream = g_ptr_array_index (demux->src, stream_num);
4959 if (cluster_time != GST_CLOCK_TIME_NONE) {
4960 /* FIXME: What to do with negative timestamps? Give timestamp 0 or -1?
4961 * Drop unless the lace contains timestamp 0? */
4962 if (time < 0 && (-time) > cluster_time) {
4965 if (stream->timecodescale == 1.0)
4966 lace_time = (cluster_time + time) * demux->time_scale;
4969 gst_util_guint64_to_gdouble ((cluster_time + time) *
4970 demux->time_scale) * stream->timecodescale;
4973 lace_time = GST_CLOCK_TIME_NONE;
4976 /* need to refresh segment info ASAP */
4977 if (GST_CLOCK_TIME_IS_VALID (lace_time) && demux->need_newsegment) {
4978 GST_DEBUG_OBJECT (demux,
4979 "generating segment starting at %" GST_TIME_FORMAT,
4980 GST_TIME_ARGS (lace_time));
4981 /* pretend we seeked here */
4982 gst_segment_set_seek (&demux->segment, demux->segment.rate,
4983 GST_FORMAT_TIME, 0, GST_SEEK_TYPE_SET, lace_time,
4984 GST_SEEK_TYPE_SET, GST_CLOCK_TIME_NONE, NULL);
4985 /* now convey our segment notion downstream */
4986 gst_matroska_demux_send_event (demux, gst_event_new_new_segment (FALSE,
4987 demux->segment.rate, demux->segment.format, demux->segment.start,
4988 demux->segment.stop, demux->segment.start));
4989 demux->need_newsegment = FALSE;
4992 if (block_duration) {
4993 if (stream->timecodescale == 1.0)
4994 duration = gst_util_uint64_scale (block_duration, demux->time_scale, 1);
4997 gst_util_gdouble_to_guint64 (gst_util_guint64_to_gdouble
4998 (gst_util_uint64_scale (block_duration, demux->time_scale,
4999 1)) * stream->timecodescale);
5000 } else if (stream->default_duration) {
5001 duration = stream->default_duration * laces;
5003 /* else duration is diff between timecode of this and next block */
5005 /* For SimpleBlock, look at the keyframe bit in flags. Otherwise,
5006 a ReferenceBlock implies that this is not a keyframe. In either
5007 case, it only makes sense for video streams. */
5008 delta_unit = stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
5009 ((is_simpleblock && !(flags & 0x80)) || referenceblock);
5011 if (delta_unit && stream->set_discont) {
5012 /* When doing seeks or such, we need to restart on key frames or
5013 * decoders might choke. */
5014 GST_DEBUG_OBJECT (demux, "skipping delta unit");
5018 for (n = 0; n < laces; n++) {
5021 if (G_UNLIKELY (lace_size[n] > size)) {
5022 GST_WARNING_OBJECT (demux, "Invalid lace size");
5026 /* QoS for video track with an index. the assumption is that
5027 index entries point to keyframes, but if that is not true we
5028 will instad skip until the next keyframe. */
5029 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
5030 stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
5031 stream->index_table && demux->segment.rate > 0.0) {
5032 GstMatroskaTrackVideoContext *videocontext =
5033 (GstMatroskaTrackVideoContext *) stream;
5034 GstClockTime earliest_time;
5035 GstClockTime earliest_stream_time;
5037 GST_OBJECT_LOCK (demux);
5038 earliest_time = videocontext->earliest_time;
5039 GST_OBJECT_UNLOCK (demux);
5040 earliest_stream_time = gst_segment_to_position (&demux->segment,
5041 GST_FORMAT_TIME, earliest_time);
5043 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
5044 GST_CLOCK_TIME_IS_VALID (earliest_stream_time) &&
5045 lace_time <= earliest_stream_time) {
5046 /* find index entry (keyframe) <= earliest_stream_time */
5047 GstMatroskaIndex *entry =
5048 gst_util_array_binary_search (stream->index_table->data,
5049 stream->index_table->len, sizeof (GstMatroskaIndex),
5050 (GCompareDataFunc) gst_matroska_index_seek_find,
5051 GST_SEARCH_MODE_BEFORE, &earliest_stream_time, NULL);
5053 /* if that entry (keyframe) is after the current the current
5054 buffer, we can skip pushing (and thus decoding) all
5055 buffers until that keyframe. */
5056 if (entry && GST_CLOCK_TIME_IS_VALID (entry->time) &&
5057 entry->time > lace_time) {
5058 GST_LOG_OBJECT (demux, "Skipping lace before late keyframe");
5059 stream->set_discont = TRUE;
5065 sub = gst_buffer_create_sub (buf,
5066 GST_BUFFER_SIZE (buf) - size, lace_size[n]);
5067 GST_DEBUG_OBJECT (demux, "created subbuffer %p", sub);
5070 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
5072 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
5074 if (stream->encodings != NULL && stream->encodings->len > 0)
5075 sub = gst_matroska_decode_buffer (stream, sub);
5078 GST_WARNING_OBJECT (demux, "Decoding buffer failed");
5082 GST_BUFFER_TIMESTAMP (sub) = lace_time;
5084 if (GST_CLOCK_TIME_IS_VALID (lace_time)) {
5085 GstClockTime last_stop_end;
5087 /* Check if this stream is after segment stop */
5088 if (GST_CLOCK_TIME_IS_VALID (demux->segment.stop) &&
5089 lace_time >= demux->segment.stop) {
5090 GST_DEBUG_OBJECT (demux,
5091 "Stream %d after segment stop %" GST_TIME_FORMAT, stream->index,
5092 GST_TIME_ARGS (demux->segment.stop));
5093 gst_buffer_unref (sub);
5096 if (offset >= stream->to_offset) {
5097 GST_DEBUG_OBJECT (demux, "Stream %d after playback section",
5099 gst_buffer_unref (sub);
5103 /* handle gaps, e.g. non-zero start-time, or an cue index entry
5104 * that landed us with timestamps not quite intended */
5105 if (GST_CLOCK_TIME_IS_VALID (demux->segment.last_stop) &&
5106 demux->segment.rate > 0.0) {
5107 GstClockTimeDiff diff;
5109 /* only send newsegments with increasing start times,
5110 * otherwise if these go back and forth downstream (sinks) increase
5111 * accumulated time and running_time */
5112 diff = GST_CLOCK_DIFF (demux->segment.last_stop, lace_time);
5113 if (diff > 2 * GST_SECOND && lace_time > demux->segment.start &&
5114 (!GST_CLOCK_TIME_IS_VALID (demux->segment.stop) ||
5115 lace_time < demux->segment.stop)) {
5116 GST_DEBUG_OBJECT (demux,
5117 "Gap of %" G_GINT64_FORMAT " ns detected in"
5118 "stream %d (%" GST_TIME_FORMAT " -> %" GST_TIME_FORMAT "). "
5119 "Sending updated NEWSEGMENT events", diff,
5120 stream->index, GST_TIME_ARGS (stream->pos),
5121 GST_TIME_ARGS (lace_time));
5122 /* send newsegment events such that the gap is not accounted in
5123 * accum time, hence running_time */
5124 /* close ahead of gap */
5125 gst_matroska_demux_send_event (demux,
5126 gst_event_new_new_segment (TRUE, demux->segment.rate,
5127 demux->segment.format, demux->segment.last_stop,
5128 demux->segment.last_stop, demux->segment.last_stop));
5130 gst_matroska_demux_send_event (demux,
5131 gst_event_new_new_segment (FALSE, demux->segment.rate,
5132 demux->segment.format, lace_time, demux->segment.stop,
5134 /* align segment view with downstream,
5135 * prevents double-counting accum when closing segment */
5136 gst_segment_set_newsegment (&demux->segment, FALSE,
5137 demux->segment.rate, demux->segment.format, lace_time,
5138 demux->segment.stop, lace_time);
5139 demux->segment.last_stop = lace_time;
5143 if (!GST_CLOCK_TIME_IS_VALID (demux->segment.last_stop)
5144 || demux->segment.last_stop < lace_time) {
5145 demux->segment.last_stop = lace_time;
5148 last_stop_end = lace_time;
5150 GST_BUFFER_DURATION (sub) = duration / laces;
5151 last_stop_end += GST_BUFFER_DURATION (sub);
5154 if (!GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) ||
5155 demux->last_stop_end < last_stop_end)
5156 demux->last_stop_end = last_stop_end;
5158 if (demux->segment.duration == -1 ||
5159 demux->segment.duration < lace_time) {
5160 gst_segment_set_duration (&demux->segment, GST_FORMAT_TIME,
5162 gst_element_post_message (GST_ELEMENT_CAST (demux),
5163 gst_message_new_duration (GST_OBJECT_CAST (demux),
5164 GST_FORMAT_TIME, GST_CLOCK_TIME_NONE));
5168 stream->pos = lace_time;
5170 gst_matroska_demux_sync_streams (demux);
5172 if (stream->set_discont) {
5173 GST_DEBUG_OBJECT (demux, "marking DISCONT");
5174 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DISCONT);
5175 stream->set_discont = FALSE;
5178 /* reverse playback book-keeping */
5179 if (!GST_CLOCK_TIME_IS_VALID (stream->from_time))
5180 stream->from_time = lace_time;
5181 if (stream->from_offset == -1)
5182 stream->from_offset = offset;
5184 GST_DEBUG_OBJECT (demux,
5185 "Pushing lace %d, data of size %d for stream %d, time=%"
5186 GST_TIME_FORMAT " and duration=%" GST_TIME_FORMAT, n,
5187 GST_BUFFER_SIZE (sub), stream_num,
5188 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (sub)),
5189 GST_TIME_ARGS (GST_BUFFER_DURATION (sub)));
5191 if (demux->element_index) {
5192 if (stream->index_writer_id == -1)
5193 gst_index_get_writer_id (demux->element_index,
5194 GST_OBJECT (stream->pad), &stream->index_writer_id);
5196 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
5197 G_GUINT64_FORMAT " for writer id %d",
5198 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (sub)), cluster_offset,
5199 stream->index_writer_id);
5200 gst_index_add_association (demux->element_index,
5201 stream->index_writer_id, GST_BUFFER_FLAG_IS_SET (sub,
5202 GST_BUFFER_FLAG_DELTA_UNIT) ? 0 : GST_ASSOCIATION_FLAG_KEY_UNIT,
5203 GST_FORMAT_TIME, GST_BUFFER_TIMESTAMP (sub), GST_FORMAT_BYTES,
5204 cluster_offset, NULL);
5207 gst_buffer_set_caps (sub, GST_PAD_CAPS (stream->pad));
5209 /* Postprocess the buffers depending on the codec used */
5210 if (stream->postprocess_frame) {
5211 GST_LOG_OBJECT (demux, "running post process");
5212 ret = stream->postprocess_frame (GST_ELEMENT (demux), stream, &sub);
5215 ret = gst_pad_push (stream->pad, sub);
5216 if (demux->segment.rate < 0) {
5217 if (lace_time > demux->segment.stop && ret == GST_FLOW_UNEXPECTED) {
5218 /* In reverse playback we can get a GST_FLOW_UNEXPECTED when
5219 * we are at the end of the segment, so we just need to jump
5220 * back to the previous section. */
5221 GST_DEBUG_OBJECT (demux, "downstream has reached end of segment");
5226 ret = gst_matroska_demux_combine_flows (demux, stream, ret);
5229 size -= lace_size[n];
5230 if (lace_time != GST_CLOCK_TIME_NONE && duration)
5231 lace_time += duration / laces;
5233 lace_time = GST_CLOCK_TIME_NONE;
5239 gst_buffer_unref (buf);
5250 ret = gst_matroska_demux_combine_flows (demux, stream, ret);
5255 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Invalid lacing size"));
5256 /* non-fatal, try next block(group) */
5262 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Data error"));
5263 /* non-fatal, try next block(group) */
5269 /* return FALSE if block(group) should be skipped (due to a seek) */
5270 static inline gboolean
5271 gst_matroska_demux_seek_block (GstMatroskaDemux * demux)
5273 if (G_UNLIKELY (demux->seek_block)) {
5274 if (!(--demux->seek_block)) {
5277 GST_LOG_OBJECT (demux, "should skip block due to seek");
5285 static GstFlowReturn
5286 gst_matroska_demux_parse_contents_seekentry (GstMatroskaDemux * demux,
5290 guint64 seek_pos = (guint64) - 1;
5291 guint32 seek_id = 0;
5294 DEBUG_ELEMENT_START (demux, ebml, "Seek");
5296 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
5297 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
5301 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
5302 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
5306 case GST_MATROSKA_ID_SEEKID:
5310 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
5313 GST_DEBUG_OBJECT (demux, "SeekID: %" G_GUINT64_FORMAT, t);
5318 case GST_MATROSKA_ID_SEEKPOSITION:
5322 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
5325 if (t > G_MAXINT64) {
5326 GST_WARNING_OBJECT (demux,
5327 "Too large SeekPosition %" G_GUINT64_FORMAT, t);
5331 GST_DEBUG_OBJECT (demux, "SeekPosition: %" G_GUINT64_FORMAT, t);
5337 ret = gst_matroska_demux_parse_skip (demux, ebml, "SeekHead", id);
5342 if (ret != GST_FLOW_OK && ret != GST_FLOW_UNEXPECTED)
5345 if (!seek_id || seek_pos == (guint64) - 1) {
5346 GST_WARNING_OBJECT (demux, "Incomplete seekhead entry (0x%x/%"
5347 G_GUINT64_FORMAT ")", seek_id, seek_pos);
5352 case GST_MATROSKA_ID_SEEKHEAD:
5355 case GST_MATROSKA_ID_CUES:
5356 case GST_MATROSKA_ID_TAGS:
5357 case GST_MATROSKA_ID_TRACKS:
5358 case GST_MATROSKA_ID_SEGMENTINFO:
5359 case GST_MATROSKA_ID_ATTACHMENTS:
5360 case GST_MATROSKA_ID_CHAPTERS:
5362 guint64 before_pos, length;
5366 length = gst_matroska_demux_get_length (demux);
5367 before_pos = demux->offset;
5369 if (length == (guint64) - 1) {
5370 GST_DEBUG_OBJECT (demux, "no upstream length, skipping SeakHead entry");
5374 /* check for validity */
5375 if (seek_pos + demux->ebml_segment_start + 12 >= length) {
5376 GST_WARNING_OBJECT (demux,
5377 "SeekHead reference lies outside file!" " (%"
5378 G_GUINT64_FORMAT "+%" G_GUINT64_FORMAT "+12 >= %"
5379 G_GUINT64_FORMAT ")", seek_pos, demux->ebml_segment_start, length);
5383 /* only pick up index location when streaming */
5384 if (demux->streaming) {
5385 if (seek_id == GST_MATROSKA_ID_CUES) {
5386 demux->index_offset = seek_pos + demux->ebml_segment_start;
5387 GST_DEBUG_OBJECT (demux, "Cues located at offset %" G_GUINT64_FORMAT,
5388 demux->index_offset);
5394 demux->offset = seek_pos + demux->ebml_segment_start;
5397 if ((ret = gst_matroska_demux_peek_id_length_pull (demux, &id, &length,
5398 &needed)) != GST_FLOW_OK)
5401 if (id != seek_id) {
5402 GST_WARNING_OBJECT (demux,
5403 "We looked for ID=0x%x but got ID=0x%x (pos=%" G_GUINT64_FORMAT ")",
5404 seek_id, id, seek_pos + demux->ebml_segment_start);
5407 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
5412 demux->offset = before_pos;
5417 GST_DEBUG_OBJECT (demux, "Ignoring Seek entry for ID=0x%x", seek_id);
5420 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
5425 static GstFlowReturn
5426 gst_matroska_demux_parse_contents (GstMatroskaDemux * demux, GstEbmlRead * ebml)
5428 GstFlowReturn ret = GST_FLOW_OK;
5431 DEBUG_ELEMENT_START (demux, ebml, "SeekHead");
5433 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
5434 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
5438 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
5439 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
5443 case GST_MATROSKA_ID_SEEKENTRY:
5445 ret = gst_matroska_demux_parse_contents_seekentry (demux, ebml);
5446 /* Ignore EOS and errors here */
5447 if (ret != GST_FLOW_OK) {
5448 GST_DEBUG_OBJECT (demux, "Ignoring %s", gst_flow_get_name (ret));
5455 ret = gst_matroska_demux_parse_skip (demux, ebml, "SeekHead", id);
5460 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
5465 #define GST_FLOW_OVERFLOW GST_FLOW_CUSTOM_ERROR
5467 static inline GstFlowReturn
5468 gst_matroska_demux_check_read_size (GstMatroskaDemux * demux, guint64 bytes)
5470 if (G_UNLIKELY (bytes > 10 * 1024 * 1024)) {
5471 /* only a few blocks are expected/allowed to be large,
5472 * and will be recursed into, whereas others will be read and must fit */
5473 if (demux->streaming) {
5474 /* fatal in streaming case, as we can't step over easily */
5475 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
5476 ("reading large block of size %" G_GUINT64_FORMAT " not supported; "
5477 "file might be corrupt.", bytes));
5478 return GST_FLOW_ERROR;
5480 /* indicate higher level to quietly give up */
5481 GST_DEBUG_OBJECT (demux,
5482 "too large block of size %" G_GUINT64_FORMAT, bytes);
5483 return GST_FLOW_ERROR;
5490 /* returns TRUE if we truely are in error state, and should give up */
5491 static inline gboolean
5492 gst_matroska_demux_check_parse_error (GstMatroskaDemux * demux)
5494 if (!demux->streaming && demux->next_cluster_offset > 0) {
5495 /* just repositioning to where next cluster should be and try from there */
5496 GST_WARNING_OBJECT (demux, "parse error, trying next cluster expected at %"
5497 G_GUINT64_FORMAT, demux->next_cluster_offset);
5498 demux->offset = demux->next_cluster_offset;
5499 demux->next_cluster_offset = 0;
5504 /* sigh, one last attempt above and beyond call of duty ...;
5505 * search for cluster mark following current pos */
5506 pos = demux->offset;
5507 GST_WARNING_OBJECT (demux, "parse error, looking for next cluster");
5508 if (gst_matroska_demux_search_cluster (demux, &pos) != GST_FLOW_OK) {
5509 /* did not work, give up */
5512 GST_DEBUG_OBJECT (demux, "... found at %" G_GUINT64_FORMAT, pos);
5513 /* try that position */
5514 demux->offset = pos;
5520 static inline GstFlowReturn
5521 gst_matroska_demux_flush (GstMatroskaDemux * demux, guint flush)
5523 GST_LOG_OBJECT (demux, "skipping %d bytes", flush);
5524 demux->offset += flush;
5525 if (demux->streaming) {
5528 /* hard to skip large blocks when streaming */
5529 ret = gst_matroska_demux_check_read_size (demux, flush);
5530 if (ret != GST_FLOW_OK)
5532 if (flush <= gst_adapter_available (demux->adapter))
5533 gst_adapter_flush (demux->adapter, flush);
5535 return GST_FLOW_UNEXPECTED;
5540 /* initializes @ebml with @bytes from input stream at current offset.
5541 * Returns UNEXPECTED if insufficient available,
5542 * ERROR if too much was attempted to read. */
5543 static inline GstFlowReturn
5544 gst_matroska_demux_take (GstMatroskaDemux * demux, guint64 bytes,
5547 GstBuffer *buffer = NULL;
5548 GstFlowReturn ret = GST_FLOW_OK;
5550 GST_LOG_OBJECT (demux, "taking %" G_GUINT64_FORMAT " bytes for parsing",
5552 ret = gst_matroska_demux_check_read_size (demux, bytes);
5553 if (G_UNLIKELY (ret != GST_FLOW_OK)) {
5554 if (!demux->streaming) {
5555 /* in pull mode, we can skip */
5556 if ((ret = gst_matroska_demux_flush (demux, bytes)) == GST_FLOW_OK)
5557 ret = GST_FLOW_OVERFLOW;
5559 /* otherwise fatal */
5560 ret = GST_FLOW_ERROR;
5564 if (demux->streaming) {
5565 if (gst_adapter_available (demux->adapter) >= bytes)
5566 buffer = gst_adapter_take_buffer (demux->adapter, bytes);
5568 ret = GST_FLOW_UNEXPECTED;
5570 ret = gst_matroska_demux_peek_bytes (demux, demux->offset, bytes, &buffer,
5572 if (G_LIKELY (buffer)) {
5573 gst_ebml_read_init (ebml, GST_ELEMENT_CAST (demux), buffer, demux->offset);
5574 demux->offset += bytes;
5581 gst_matroska_demux_check_seekability (GstMatroskaDemux * demux)
5584 gboolean seekable = FALSE;
5585 gint64 start = -1, stop = -1;
5587 query = gst_query_new_seeking (GST_FORMAT_BYTES);
5588 if (!gst_pad_peer_query (demux->sinkpad, query)) {
5589 GST_DEBUG_OBJECT (demux, "seeking query failed");
5593 gst_query_parse_seeking (query, NULL, &seekable, &start, &stop);
5595 /* try harder to query upstream size if we didn't get it the first time */
5596 if (seekable && stop == -1) {
5597 GstFormat fmt = GST_FORMAT_BYTES;
5599 GST_DEBUG_OBJECT (demux, "doing duration query to fix up unset stop");
5600 gst_pad_query_peer_duration (demux->sinkpad, &fmt, &stop);
5603 /* if upstream doesn't know the size, it's likely that it's not seekable in
5604 * practice even if it technically may be seekable */
5605 if (seekable && (start != 0 || stop <= start)) {
5606 GST_DEBUG_OBJECT (demux, "seekable but unknown start/stop -> disable");
5611 GST_INFO_OBJECT (demux, "seekable: %d (%" G_GUINT64_FORMAT " - %"
5612 G_GUINT64_FORMAT ")", seekable, start, stop);
5613 demux->seekable = seekable;
5615 gst_query_unref (query);
5618 static GstFlowReturn
5619 gst_matroska_demux_find_tracks (GstMatroskaDemux * demux)
5625 GstFlowReturn ret = GST_FLOW_OK;
5627 GST_WARNING_OBJECT (demux,
5628 "Found Cluster element before Tracks, searching Tracks");
5631 before_pos = demux->offset;
5633 /* Search Tracks element */
5635 ret = gst_matroska_demux_peek_id_length_pull (demux, &id, &length, &needed);
5636 if (ret != GST_FLOW_OK)
5639 if (id != GST_MATROSKA_ID_TRACKS) {
5640 /* we may be skipping large cluster here, so forego size check etc */
5641 /* ... but we can't skip undefined size; force error */
5642 if (length == G_MAXUINT64) {
5643 ret = gst_matroska_demux_check_read_size (demux, length);
5646 demux->offset += needed;
5647 demux->offset += length;
5652 /* will lead to track parsing ... */
5653 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
5658 demux->offset = before_pos;
5663 #define GST_READ_CHECK(stmt) \
5665 if (G_UNLIKELY ((ret = (stmt)) != GST_FLOW_OK)) { \
5666 if (ret == GST_FLOW_OVERFLOW) { \
5667 ret = GST_FLOW_OK; \
5673 static GstFlowReturn
5674 gst_matroska_demux_parse_id (GstMatroskaDemux * demux, guint32 id,
5675 guint64 length, guint needed)
5677 GstEbmlRead ebml = { 0, };
5678 GstFlowReturn ret = GST_FLOW_OK;
5681 GST_LOG_OBJECT (demux, "Parsing Element id 0x%x, "
5682 "size %" G_GUINT64_FORMAT ", prefix %d", id, length, needed);
5684 /* if we plan to read and parse this element, we need prefix (id + length)
5685 * and the contents */
5686 /* mind about overflow wrap-around when dealing with undefined size */
5688 if (G_LIKELY (length != G_MAXUINT64))
5691 switch (demux->state) {
5692 case GST_MATROSKA_DEMUX_STATE_START:
5694 case GST_EBML_ID_HEADER:
5695 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5696 ret = gst_matroska_demux_parse_header (demux, &ebml);
5697 if (ret != GST_FLOW_OK)
5699 demux->state = GST_MATROSKA_DEMUX_STATE_SEGMENT;
5700 gst_matroska_demux_check_seekability (demux);
5703 goto invalid_header;
5707 case GST_MATROSKA_DEMUX_STATE_SEGMENT:
5709 case GST_MATROSKA_ID_SEGMENT:
5710 /* eat segment prefix */
5711 GST_READ_CHECK (gst_matroska_demux_flush (demux, needed));
5712 GST_DEBUG_OBJECT (demux,
5713 "Found Segment start at offset %" G_GUINT64_FORMAT,
5715 /* seeks are from the beginning of the segment,
5716 * after the segment ID/length */
5717 demux->ebml_segment_start = demux->offset;
5718 demux->state = GST_MATROSKA_DEMUX_STATE_HEADER;
5721 GST_WARNING_OBJECT (demux,
5722 "Expected a Segment ID (0x%x), but received 0x%x!",
5723 GST_MATROSKA_ID_SEGMENT, id);
5724 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
5728 case GST_MATROSKA_DEMUX_STATE_SCANNING:
5729 if (id != GST_MATROSKA_ID_CLUSTER &&
5730 id != GST_MATROSKA_ID_CLUSTERTIMECODE)
5733 case GST_MATROSKA_DEMUX_STATE_HEADER:
5734 case GST_MATROSKA_DEMUX_STATE_DATA:
5735 case GST_MATROSKA_DEMUX_STATE_SEEK:
5737 case GST_MATROSKA_ID_SEGMENTINFO:
5738 if (!demux->segmentinfo_parsed) {
5739 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5740 ret = gst_matroska_demux_parse_info (demux, &ebml);
5742 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
5745 case GST_MATROSKA_ID_TRACKS:
5746 if (!demux->tracks_parsed) {
5747 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5748 ret = gst_matroska_demux_parse_tracks (demux, &ebml);
5750 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
5753 case GST_MATROSKA_ID_CLUSTER:
5754 if (G_UNLIKELY (!demux->tracks_parsed)) {
5755 if (demux->streaming) {
5756 GST_DEBUG_OBJECT (demux, "Cluster before Track");
5757 goto not_streamable;
5759 ret = gst_matroska_demux_find_tracks (demux);
5760 if (!demux->tracks_parsed)
5764 if (G_UNLIKELY (demux->state == GST_MATROSKA_DEMUX_STATE_HEADER)) {
5765 demux->state = GST_MATROSKA_DEMUX_STATE_DATA;
5766 demux->first_cluster_offset = demux->offset;
5767 GST_DEBUG_OBJECT (demux, "signaling no more pads");
5768 gst_element_no_more_pads (GST_ELEMENT (demux));
5769 /* send initial newsegment */
5770 gst_matroska_demux_send_event (demux,
5771 gst_event_new_new_segment (FALSE, 1.0,
5773 (demux->segment.duration >
5774 0) ? demux->segment.duration : -1, 0));
5776 demux->cluster_time = GST_CLOCK_TIME_NONE;
5777 demux->cluster_offset = demux->offset;
5778 if (G_UNLIKELY (!demux->seek_first && demux->seek_block)) {
5779 GST_DEBUG_OBJECT (demux, "seek target block %" G_GUINT64_FORMAT
5780 " not found in Cluster, trying next Cluster's first block instead",
5782 demux->seek_block = 0;
5784 demux->seek_first = FALSE;
5785 /* record next cluster for recovery */
5786 if (read != G_MAXUINT64)
5787 demux->next_cluster_offset = demux->cluster_offset + read;
5788 /* eat cluster prefix */
5789 gst_matroska_demux_flush (demux, needed);
5791 case GST_MATROSKA_ID_CLUSTERTIMECODE:
5795 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5796 if ((ret = gst_ebml_read_uint (&ebml, &id, &num)) != GST_FLOW_OK)
5798 GST_DEBUG_OBJECT (demux, "ClusterTimeCode: %" G_GUINT64_FORMAT, num);
5799 demux->cluster_time = num;
5800 if (demux->element_index) {
5801 if (demux->element_index_writer_id == -1)
5802 gst_index_get_writer_id (demux->element_index,
5803 GST_OBJECT (demux), &demux->element_index_writer_id);
5804 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
5805 G_GUINT64_FORMAT " for writer id %d",
5806 GST_TIME_ARGS (demux->cluster_time), demux->cluster_offset,
5807 demux->element_index_writer_id);
5808 gst_index_add_association (demux->element_index,
5809 demux->element_index_writer_id, GST_ASSOCIATION_FLAG_KEY_UNIT,
5810 GST_FORMAT_TIME, demux->cluster_time,
5811 GST_FORMAT_BYTES, demux->cluster_offset, NULL);
5815 case GST_MATROSKA_ID_BLOCKGROUP:
5816 if (!gst_matroska_demux_seek_block (demux))
5818 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5819 DEBUG_ELEMENT_START (demux, &ebml, "BlockGroup");
5820 if ((ret = gst_ebml_read_master (&ebml, &id)) == GST_FLOW_OK) {
5821 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
5822 &ebml, demux->cluster_time, demux->cluster_offset, FALSE);
5824 DEBUG_ELEMENT_STOP (demux, &ebml, "BlockGroup", ret);
5826 case GST_MATROSKA_ID_SIMPLEBLOCK:
5827 if (!gst_matroska_demux_seek_block (demux))
5829 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5830 DEBUG_ELEMENT_START (demux, &ebml, "SimpleBlock");
5831 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
5832 &ebml, demux->cluster_time, demux->cluster_offset, TRUE);
5833 DEBUG_ELEMENT_STOP (demux, &ebml, "SimpleBlock", ret);
5835 case GST_MATROSKA_ID_ATTACHMENTS:
5836 if (!demux->attachments_parsed) {
5837 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5838 ret = gst_matroska_demux_parse_attachments (demux, &ebml);
5840 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
5843 case GST_MATROSKA_ID_TAGS:
5844 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5845 ret = gst_matroska_demux_parse_metadata (demux, &ebml);
5847 case GST_MATROSKA_ID_CHAPTERS:
5848 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5849 ret = gst_matroska_demux_parse_chapters (demux, &ebml);
5851 case GST_MATROSKA_ID_SEEKHEAD:
5852 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5853 ret = gst_matroska_demux_parse_contents (demux, &ebml);
5855 case GST_MATROSKA_ID_CUES:
5856 if (demux->index_parsed) {
5857 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
5860 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5861 ret = gst_matroska_demux_parse_index (demux, &ebml);
5862 /* only push based; delayed index building */
5863 if (ret == GST_FLOW_OK
5864 && demux->state == GST_MATROSKA_DEMUX_STATE_SEEK) {
5867 GST_OBJECT_LOCK (demux);
5868 event = demux->seek_event;
5869 demux->seek_event = NULL;
5870 GST_OBJECT_UNLOCK (demux);
5873 /* unlikely to fail, since we managed to seek to this point */
5874 if (!gst_matroska_demux_handle_seek_event (demux, NULL, event))
5876 /* resume data handling, main thread clear to seek again */
5877 GST_OBJECT_LOCK (demux);
5878 demux->state = GST_MATROSKA_DEMUX_STATE_DATA;
5879 GST_OBJECT_UNLOCK (demux);
5882 case GST_MATROSKA_ID_POSITION:
5883 case GST_MATROSKA_ID_PREVSIZE:
5884 case GST_MATROSKA_ID_ENCRYPTEDBLOCK:
5885 case GST_MATROSKA_ID_SILENTTRACKS:
5886 GST_DEBUG_OBJECT (demux,
5887 "Skipping Cluster subelement 0x%x - ignoring", id);
5891 GST_DEBUG_OBJECT (demux, "skipping Element 0x%x", id);
5892 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
5898 if (ret == GST_FLOW_PARSE)
5902 gst_ebml_read_clear (&ebml);
5908 /* simply exit, maybe not enough data yet */
5909 /* no ebml to clear if read error */
5914 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
5915 ("Failed to parse Element 0x%x", id));
5916 ret = GST_FLOW_ERROR;
5921 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
5922 ("File layout does not permit streaming"));
5923 ret = GST_FLOW_ERROR;
5928 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
5929 ("No Tracks element found"));
5930 ret = GST_FLOW_ERROR;
5935 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Invalid header"));
5936 ret = GST_FLOW_ERROR;
5941 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Failed to seek"));
5942 ret = GST_FLOW_ERROR;
5948 gst_matroska_demux_loop (GstPad * pad)
5950 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (pad));
5956 /* If we have to close a segment, send a new segment to do this now */
5957 if (G_LIKELY (demux->state == GST_MATROSKA_DEMUX_STATE_DATA)) {
5958 if (G_UNLIKELY (demux->close_segment)) {
5959 gst_matroska_demux_send_event (demux, demux->close_segment);
5960 demux->close_segment = NULL;
5962 if (G_UNLIKELY (demux->new_segment)) {
5963 gst_matroska_demux_send_event (demux, demux->new_segment);
5964 demux->new_segment = NULL;
5968 ret = gst_matroska_demux_peek_id_length_pull (demux, &id, &length, &needed);
5969 if (ret == GST_FLOW_UNEXPECTED)
5971 if (ret != GST_FLOW_OK) {
5972 if (gst_matroska_demux_check_parse_error (demux))
5978 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
5979 "size %" G_GUINT64_FORMAT ", needed %d", demux->offset, id,
5982 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
5983 if (ret == GST_FLOW_UNEXPECTED)
5985 if (ret != GST_FLOW_OK)
5988 /* check if we're at the end of a configured segment */
5989 if (G_LIKELY (demux->src->len)) {
5992 g_assert (demux->num_streams == demux->src->len);
5993 for (i = 0; i < demux->src->len; i++) {
5994 GstMatroskaTrackContext *context = g_ptr_array_index (demux->src, i);
5995 GST_DEBUG_OBJECT (context->pad, "pos %" GST_TIME_FORMAT,
5996 GST_TIME_ARGS (context->pos));
5997 if (context->eos == FALSE)
6001 GST_INFO_OBJECT (demux, "All streams are EOS");
6002 ret = GST_FLOW_UNEXPECTED;
6007 if (G_UNLIKELY (demux->offset == gst_matroska_demux_get_length (demux))) {
6008 GST_LOG_OBJECT (demux, "Reached end of stream");
6009 ret = GST_FLOW_UNEXPECTED;
6018 if (demux->segment.rate < 0.0) {
6019 ret = gst_matroska_demux_seek_to_previous_keyframe (demux);
6020 if (ret == GST_FLOW_OK)
6027 const gchar *reason = gst_flow_get_name (ret);
6028 gboolean push_eos = FALSE;
6030 GST_LOG_OBJECT (demux, "pausing task, reason %s", reason);
6031 demux->segment_running = FALSE;
6032 gst_pad_pause_task (demux->sinkpad);
6034 if (ret == GST_FLOW_UNEXPECTED) {
6035 /* perform EOS logic */
6037 /* Close the segment, i.e. update segment stop with the duration
6038 * if no stop was set */
6039 if (GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) &&
6040 !GST_CLOCK_TIME_IS_VALID (demux->segment.stop)) {
6042 gst_event_new_new_segment_full (TRUE, demux->segment.rate,
6043 demux->segment.applied_rate, demux->segment.format,
6044 demux->segment.start,
6045 MAX (demux->last_stop_end, demux->segment.start),
6046 demux->segment.time);
6047 gst_matroska_demux_send_event (demux, event);
6050 if (demux->segment.flags & GST_SEEK_FLAG_SEGMENT) {
6053 /* for segment playback we need to post when (in stream time)
6054 * we stopped, this is either stop (when set) or the duration. */
6055 if ((stop = demux->segment.stop) == -1)
6056 stop = demux->last_stop_end;
6058 GST_LOG_OBJECT (demux, "Sending segment done, at end of segment");
6059 gst_element_post_message (GST_ELEMENT (demux),
6060 gst_message_new_segment_done (GST_OBJECT (demux), GST_FORMAT_TIME,
6065 } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_UNEXPECTED) {
6066 /* for fatal errors we post an error message */
6067 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
6068 ("stream stopped, reason %s", reason));
6072 /* send EOS, and prevent hanging if no streams yet */
6073 GST_LOG_OBJECT (demux, "Sending EOS, at end of stream");
6074 if (!gst_matroska_demux_send_event (demux, gst_event_new_eos ()) &&
6075 (ret == GST_FLOW_UNEXPECTED)) {
6076 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
6077 (NULL), ("got eos but no streams (yet)"));
6085 * Create and push a flushing seek event upstream
6088 perform_seek_to_offset (GstMatroskaDemux * demux, guint64 offset)
6093 GST_DEBUG_OBJECT (demux, "Seeking to %" G_GUINT64_FORMAT, offset);
6096 gst_event_new_seek (1.0, GST_FORMAT_BYTES,
6097 GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, GST_SEEK_TYPE_SET, offset,
6098 GST_SEEK_TYPE_NONE, -1);
6100 res = gst_pad_push_event (demux->sinkpad, event);
6102 /* newsegment event will update offset */
6106 static const guint8 *
6107 gst_matroska_demux_peek_adapter (GstMatroskaDemux * demux, guint peek)
6109 return gst_adapter_peek (demux->adapter, peek);
6112 static GstFlowReturn
6113 gst_matroska_demux_peek_id_length_push (GstMatroskaDemux * demux, guint32 * _id,
6114 guint64 * _length, guint * _needed)
6116 return gst_ebml_peek_id_length (_id, _length, _needed,
6117 (GstPeekData) gst_matroska_demux_peek_adapter, (gpointer) demux,
6118 GST_ELEMENT_CAST (demux), demux->offset);
6121 static GstFlowReturn
6122 gst_matroska_demux_chain (GstPad * pad, GstBuffer * buffer)
6124 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (pad));
6126 GstFlowReturn ret = GST_FLOW_OK;
6131 if (G_UNLIKELY (GST_BUFFER_IS_DISCONT (buffer))) {
6132 GST_DEBUG_OBJECT (demux, "got DISCONT");
6133 gst_adapter_clear (demux->adapter);
6134 GST_OBJECT_LOCK (demux);
6135 gst_matroska_demux_reset_streams (demux, GST_CLOCK_TIME_NONE, FALSE);
6136 GST_OBJECT_UNLOCK (demux);
6139 gst_adapter_push (demux->adapter, buffer);
6143 available = gst_adapter_available (demux->adapter);
6145 ret = gst_matroska_demux_peek_id_length_push (demux, &id, &length, &needed);
6146 if (G_UNLIKELY (ret != GST_FLOW_OK && ret != GST_FLOW_UNEXPECTED))
6149 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
6150 "size %" G_GUINT64_FORMAT ", needed %d, available %d", demux->offset, id,
6151 length, needed, available);
6153 if (needed > available)
6156 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
6157 if (ret == GST_FLOW_UNEXPECTED) {
6158 /* need more data */
6160 } else if (ret != GST_FLOW_OK) {
6167 gst_matroska_demux_handle_sink_event (GstPad * pad, GstEvent * event)
6169 gboolean res = TRUE;
6170 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (pad));
6172 GST_DEBUG_OBJECT (demux,
6173 "have event type %s: %p on sink pad", GST_EVENT_TYPE_NAME (event), event);
6175 switch (GST_EVENT_TYPE (event)) {
6176 case GST_EVENT_NEWSEGMENT:
6179 gdouble rate, arate;
6180 gint64 start, stop, time = 0;
6184 /* some debug output */
6185 gst_segment_init (&segment, GST_FORMAT_UNDEFINED);
6186 gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format,
6187 &start, &stop, &time);
6188 gst_segment_set_newsegment_full (&segment, update, rate, arate, format,
6190 GST_DEBUG_OBJECT (demux,
6191 "received format %d newsegment %" GST_SEGMENT_FORMAT, format,
6194 if (demux->state < GST_MATROSKA_DEMUX_STATE_DATA) {
6195 GST_DEBUG_OBJECT (demux, "still starting");
6199 /* we only expect a BYTE segment, e.g. following a seek */
6200 if (format != GST_FORMAT_BYTES) {
6201 GST_DEBUG_OBJECT (demux, "unsupported segment format, ignoring");
6205 GST_DEBUG_OBJECT (demux, "clearing segment state");
6206 /* clear current segment leftover */
6207 gst_adapter_clear (demux->adapter);
6208 /* and some streaming setup */
6209 demux->offset = start;
6210 /* do not know where we are;
6211 * need to come across a cluster and generate newsegment */
6212 demux->segment.last_stop = GST_CLOCK_TIME_NONE;
6213 demux->cluster_time = GST_CLOCK_TIME_NONE;
6214 demux->cluster_offset = 0;
6215 demux->need_newsegment = TRUE;
6216 /* but keep some of the upstream segment */
6217 demux->segment.rate = rate;
6219 /* chain will send initial newsegment after pads have been added,
6220 * or otherwise come up with one */
6221 GST_DEBUG_OBJECT (demux, "eating event");
6222 gst_event_unref (event);
6228 if (demux->state != GST_MATROSKA_DEMUX_STATE_DATA) {
6229 gst_event_unref (event);
6230 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
6231 (NULL), ("got eos and didn't receive a complete header object"));
6232 } else if (demux->num_streams == 0) {
6233 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
6234 (NULL), ("got eos but no streams (yet)"));
6236 gst_matroska_demux_send_event (demux, event);
6240 case GST_EVENT_FLUSH_STOP:
6242 gst_adapter_clear (demux->adapter);
6243 GST_OBJECT_LOCK (demux);
6244 gst_matroska_demux_reset_streams (demux, GST_CLOCK_TIME_NONE, TRUE);
6245 GST_OBJECT_UNLOCK (demux);
6246 demux->segment.last_stop = GST_CLOCK_TIME_NONE;
6247 demux->cluster_time = GST_CLOCK_TIME_NONE;
6248 demux->cluster_offset = 0;
6252 res = gst_pad_event_default (pad, event);
6260 gst_matroska_demux_sink_activate (GstPad * sinkpad)
6262 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (sinkpad));
6264 if (gst_pad_check_pull_range (sinkpad)) {
6265 GST_DEBUG ("going to pull mode");
6266 demux->streaming = FALSE;
6267 return gst_pad_activate_pull (sinkpad, TRUE);
6269 GST_DEBUG ("going to push (streaming) mode");
6270 demux->streaming = TRUE;
6271 return gst_pad_activate_push (sinkpad, TRUE);
6278 gst_matroska_demux_sink_activate_pull (GstPad * sinkpad, gboolean active)
6280 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (sinkpad));
6283 /* if we have a scheduler we can start the task */
6284 demux->segment_running = TRUE;
6285 gst_pad_start_task (sinkpad, (GstTaskFunction) gst_matroska_demux_loop,
6288 demux->segment_running = FALSE;
6289 gst_pad_stop_task (sinkpad);
6296 gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext *
6297 videocontext, const gchar * codec_id, guint8 * data, guint size,
6298 gchar ** codec_name, guint32 * riff_fourcc)
6300 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) videocontext;
6301 GstCaps *caps = NULL;
6303 g_assert (videocontext != NULL);
6304 g_assert (codec_name != NULL);
6306 context->send_xiph_headers = FALSE;
6307 context->send_flac_headers = FALSE;
6308 context->send_speex_headers = FALSE;
6313 /* TODO: check if we have all codec types from matroska-ids.h
6314 * check if we have to do more special things with codec_private
6317 * GST_MATROSKA_CODEC_ID_VIDEO_QUICKTIME
6318 * GST_MATROSKA_CODEC_ID_VIDEO_SNOW
6321 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VFW_FOURCC)) {
6322 gst_riff_strf_vids *vids = NULL;
6325 GstBuffer *buf = NULL;
6327 vids = (gst_riff_strf_vids *) data;
6329 /* assure size is big enough */
6331 GST_WARNING ("Too small BITMAPINFOHEADER (%d bytes)", size);
6334 if (size < sizeof (gst_riff_strf_vids)) {
6335 vids = g_new (gst_riff_strf_vids, 1);
6336 memcpy (vids, data, size);
6339 /* little-endian -> byte-order */
6340 vids->size = GUINT32_FROM_LE (vids->size);
6341 vids->width = GUINT32_FROM_LE (vids->width);
6342 vids->height = GUINT32_FROM_LE (vids->height);
6343 vids->planes = GUINT16_FROM_LE (vids->planes);
6344 vids->bit_cnt = GUINT16_FROM_LE (vids->bit_cnt);
6345 vids->compression = GUINT32_FROM_LE (vids->compression);
6346 vids->image_size = GUINT32_FROM_LE (vids->image_size);
6347 vids->xpels_meter = GUINT32_FROM_LE (vids->xpels_meter);
6348 vids->ypels_meter = GUINT32_FROM_LE (vids->ypels_meter);
6349 vids->num_colors = GUINT32_FROM_LE (vids->num_colors);
6350 vids->imp_colors = GUINT32_FROM_LE (vids->imp_colors);
6352 if (size > sizeof (gst_riff_strf_vids)) { /* some extra_data */
6353 buf = gst_buffer_new_and_alloc (size - sizeof (gst_riff_strf_vids));
6354 memcpy (GST_BUFFER_DATA (buf),
6355 (guint8 *) vids + sizeof (gst_riff_strf_vids),
6356 GST_BUFFER_SIZE (buf));
6360 *riff_fourcc = vids->compression;
6362 caps = gst_riff_create_video_caps (vids->compression, NULL, vids,
6363 buf, NULL, codec_name);
6366 GST_WARNING ("Unhandled RIFF fourcc %" GST_FOURCC_FORMAT,
6367 GST_FOURCC_ARGS (vids->compression));
6371 gst_buffer_unref (buf);
6373 if (vids != (gst_riff_strf_vids *) data)
6376 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_UNCOMPRESSED)) {
6379 switch (videocontext->fourcc) {
6380 case GST_MAKE_FOURCC ('I', '4', '2', '0'):
6381 *codec_name = g_strdup ("Raw planar YUV 4:2:0");
6382 fourcc = videocontext->fourcc;
6384 case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
6385 *codec_name = g_strdup ("Raw packed YUV 4:2:2");
6386 fourcc = videocontext->fourcc;
6388 case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
6389 *codec_name = g_strdup ("Raw packed YUV 4:2:0");
6390 fourcc = videocontext->fourcc;
6392 case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
6393 *codec_name = g_strdup ("Raw packed YUV 4:2:2");
6394 fourcc = videocontext->fourcc;
6396 case GST_MAKE_FOURCC ('A', 'Y', 'U', 'V'):
6397 *codec_name = g_strdup ("Raw packed YUV 4:4:4 with alpha channel");
6398 fourcc = videocontext->fourcc;
6402 GST_DEBUG ("Unknown fourcc %" GST_FOURCC_FORMAT,
6403 GST_FOURCC_ARGS (videocontext->fourcc));
6407 caps = gst_caps_new_simple ("video/x-raw-yuv",
6408 "format", GST_TYPE_FOURCC, fourcc, NULL);
6409 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_SP)) {
6410 caps = gst_caps_new_simple ("video/x-divx",
6411 "divxversion", G_TYPE_INT, 4, NULL);
6412 *codec_name = g_strdup ("MPEG-4 simple profile");
6413 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP) ||
6414 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AP)) {
6416 caps = gst_caps_new_full (gst_structure_new ("video/x-divx",
6417 "divxversion", G_TYPE_INT, 5, NULL),
6418 gst_structure_new ("video/x-xvid", NULL),
6419 gst_structure_new ("video/mpeg",
6420 "mpegversion", G_TYPE_INT, 4,
6421 "systemstream", G_TYPE_BOOLEAN, FALSE, NULL), NULL);
6423 caps = gst_caps_new_simple ("video/mpeg",
6424 "mpegversion", G_TYPE_INT, 4,
6425 "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
6427 GstBuffer *priv = gst_buffer_new_and_alloc (size);
6429 memcpy (GST_BUFFER_DATA (priv), data, size);
6430 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
6431 gst_buffer_unref (priv);
6433 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP))
6434 *codec_name = g_strdup ("MPEG-4 advanced simple profile");
6436 *codec_name = g_strdup ("MPEG-4 advanced profile");
6437 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MSMPEG4V3)) {
6439 caps = gst_caps_new_full (gst_structure_new ("video/x-divx",
6440 "divxversion", G_TYPE_INT, 3, NULL),
6441 gst_structure_new ("video/x-msmpeg",
6442 "msmpegversion", G_TYPE_INT, 43, NULL), NULL);
6444 caps = gst_caps_new_simple ("video/x-msmpeg",
6445 "msmpegversion", G_TYPE_INT, 43, NULL);
6446 *codec_name = g_strdup ("Microsoft MPEG-4 v.3");
6447 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1) ||
6448 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG2)) {
6451 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1))
6456 caps = gst_caps_new_simple ("video/mpeg",
6457 "systemstream", G_TYPE_BOOLEAN, FALSE,
6458 "mpegversion", G_TYPE_INT, mpegversion, NULL);
6459 *codec_name = g_strdup_printf ("MPEG-%d video", mpegversion);
6460 context->postprocess_frame = gst_matroska_demux_add_mpeg_seq_header;
6461 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MJPEG)) {
6462 caps = gst_caps_new_simple ("image/jpeg", NULL);
6463 *codec_name = g_strdup ("Motion-JPEG");
6464 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AVC)) {
6465 caps = gst_caps_new_simple ("video/x-h264", NULL);
6467 GstBuffer *priv = gst_buffer_new_and_alloc (size);
6469 /* First byte is the version, second is the profile indication, and third
6470 * is the 5 contraint_set_flags and 3 reserved bits. Fourth byte is the
6471 * level indication. */
6472 gst_codec_utils_h264_caps_set_level_and_profile (caps, data + 1,
6475 memcpy (GST_BUFFER_DATA (priv), data, size);
6476 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
6477 gst_buffer_unref (priv);
6480 *codec_name = g_strdup ("H264");
6481 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1)) ||
6482 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2)) ||
6483 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3)) ||
6484 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))) {
6485 gint rmversion = -1;
6487 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1))
6489 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2))
6491 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3))
6493 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))
6496 caps = gst_caps_new_simple ("video/x-pn-realvideo",
6497 "rmversion", G_TYPE_INT, rmversion, NULL);
6498 GST_DEBUG ("data:%p, size:0x%x", data, size);
6499 /* We need to extract the extradata ! */
6500 if (data && (size >= 0x22)) {
6505 subformat = GST_READ_UINT32_BE (data + 0x1a);
6506 rformat = GST_READ_UINT32_BE (data + 0x1e);
6508 priv = gst_buffer_new_and_alloc (size - 0x1a);
6510 memcpy (GST_BUFFER_DATA (priv), data + 0x1a, size - 0x1a);
6511 gst_caps_set_simple (caps,
6512 "codec_data", GST_TYPE_BUFFER, priv,
6513 "format", G_TYPE_INT, rformat,
6514 "subformat", G_TYPE_INT, subformat, NULL);
6515 gst_buffer_unref (priv);
6518 *codec_name = g_strdup_printf ("RealVideo %d.0", rmversion);
6519 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_THEORA)) {
6520 caps = gst_caps_new_simple ("video/x-theora", NULL);
6521 context->send_xiph_headers = TRUE;
6522 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_DIRAC)) {
6523 caps = gst_caps_new_simple ("video/x-dirac", NULL);
6524 *codec_name = g_strdup_printf ("Dirac");
6525 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8)) {
6526 caps = gst_caps_new_simple ("video/x-vp8", NULL);
6527 *codec_name = g_strdup_printf ("On2 VP8");
6529 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
6535 GstStructure *structure;
6537 for (i = 0; i < gst_caps_get_size (caps); i++) {
6538 structure = gst_caps_get_structure (caps, i);
6540 /* FIXME: use the real unit here! */
6541 GST_DEBUG ("video size %dx%d, target display size %dx%d (any unit)",
6542 videocontext->pixel_width,
6543 videocontext->pixel_height,
6544 videocontext->display_width, videocontext->display_height);
6546 /* pixel width and height are the w and h of the video in pixels */
6547 if (videocontext->pixel_width > 0 && videocontext->pixel_height > 0) {
6548 gint w = videocontext->pixel_width;
6550 gint h = videocontext->pixel_height;
6552 gst_structure_set (structure,
6553 "width", G_TYPE_INT, w, "height", G_TYPE_INT, h, NULL);
6556 if (videocontext->display_width > 0 && videocontext->display_height > 0) {
6559 /* calculate the pixel aspect ratio using the display and pixel w/h */
6560 n = videocontext->display_width * videocontext->pixel_height;
6561 d = videocontext->display_height * videocontext->pixel_width;
6562 GST_DEBUG ("setting PAR to %d/%d", n, d);
6563 gst_structure_set (structure, "pixel-aspect-ratio",
6565 videocontext->display_width * videocontext->pixel_height,
6566 videocontext->display_height * videocontext->pixel_width, NULL);
6569 if (videocontext->default_fps > 0.0) {
6570 GValue fps_double = { 0, };
6571 GValue fps_fraction = { 0, };
6573 g_value_init (&fps_double, G_TYPE_DOUBLE);
6574 g_value_init (&fps_fraction, GST_TYPE_FRACTION);
6575 g_value_set_double (&fps_double, videocontext->default_fps);
6576 g_value_transform (&fps_double, &fps_fraction);
6578 GST_DEBUG ("using default fps %f", videocontext->default_fps);
6580 gst_structure_set_value (structure, "framerate", &fps_fraction);
6581 g_value_unset (&fps_double);
6582 g_value_unset (&fps_fraction);
6583 } else if (context->default_duration > 0) {
6584 GValue fps_double = { 0, };
6585 GValue fps_fraction = { 0, };
6587 g_value_init (&fps_double, G_TYPE_DOUBLE);
6588 g_value_init (&fps_fraction, GST_TYPE_FRACTION);
6589 g_value_set_double (&fps_double, (gdouble) GST_SECOND /
6590 gst_guint64_to_gdouble (context->default_duration));
6591 g_value_transform (&fps_double, &fps_fraction);
6593 GST_DEBUG ("using default duration %" G_GUINT64_FORMAT,
6594 context->default_duration);
6596 gst_structure_set_value (structure, "framerate", &fps_fraction);
6597 g_value_unset (&fps_double);
6598 g_value_unset (&fps_fraction);
6600 /* sort of a hack to get most codecs to support,
6601 * even if the default_duration is missing */
6602 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
6606 if (videocontext->parent.flags & GST_MATROSKA_VIDEOTRACK_INTERLACED)
6607 gst_structure_set (structure, "interlaced", G_TYPE_BOOLEAN, TRUE, NULL);
6610 gst_caps_do_simplify (caps);
6617 * Some AAC specific code... *sigh*
6618 * FIXME: maybe we should use '15' and code the sample rate explicitly
6619 * if the sample rate doesn't match the predefined rates exactly? (tpm)
6623 aac_rate_idx (gint rate)
6627 else if (75132 <= rate)
6629 else if (55426 <= rate)
6631 else if (46009 <= rate)
6633 else if (37566 <= rate)
6635 else if (27713 <= rate)
6637 else if (23004 <= rate)
6639 else if (18783 <= rate)
6641 else if (13856 <= rate)
6643 else if (11502 <= rate)
6645 else if (9391 <= rate)
6652 aac_profile_idx (const gchar * codec_id)
6656 if (strlen (codec_id) <= 12)
6658 else if (!strncmp (&codec_id[12], "MAIN", 4))
6660 else if (!strncmp (&codec_id[12], "LC", 2))
6662 else if (!strncmp (&codec_id[12], "SSR", 3))
6670 #define AAC_SYNC_EXTENSION_TYPE 0x02b7
6673 gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext *
6674 audiocontext, const gchar * codec_id, guint8 * data, guint size,
6675 gchar ** codec_name, guint16 * riff_audio_fmt)
6677 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) audiocontext;
6678 GstCaps *caps = NULL;
6680 g_assert (audiocontext != NULL);
6681 g_assert (codec_name != NULL);
6684 *riff_audio_fmt = 0;
6686 context->send_xiph_headers = FALSE;
6687 context->send_flac_headers = FALSE;
6688 context->send_speex_headers = FALSE;
6690 /* TODO: check if we have all codec types from matroska-ids.h
6691 * check if we have to do more special things with codec_private
6692 * check if we need bitdepth in different places too
6693 * implement channel position magic
6695 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID9
6696 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID10
6697 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDMC
6698 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDM2
6701 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1) ||
6702 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2) ||
6703 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L3)) {
6706 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1))
6708 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2))
6713 caps = gst_caps_new_simple ("audio/mpeg",
6714 "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, layer, NULL);
6715 *codec_name = g_strdup_printf ("MPEG-1 layer %d", layer);
6716 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE) ||
6717 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_LE)) {
6720 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE))
6721 endianness = G_BIG_ENDIAN;
6723 endianness = G_LITTLE_ENDIAN;
6725 caps = gst_caps_new_simple ("audio/x-raw-int",
6726 "width", G_TYPE_INT, audiocontext->bitdepth,
6727 "depth", G_TYPE_INT, audiocontext->bitdepth,
6728 "signed", G_TYPE_BOOLEAN, audiocontext->bitdepth != 8,
6729 "endianness", G_TYPE_INT, endianness, NULL);
6731 *codec_name = g_strdup_printf ("Raw %d-bit PCM audio",
6732 audiocontext->bitdepth);
6733 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_FLOAT)) {
6734 caps = gst_caps_new_simple ("audio/x-raw-float",
6735 "endianness", G_TYPE_INT, G_LITTLE_ENDIAN,
6736 "width", G_TYPE_INT, audiocontext->bitdepth, NULL);
6737 *codec_name = g_strdup_printf ("Raw %d-bit floating-point audio",
6738 audiocontext->bitdepth);
6739 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AC3,
6740 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AC3))) {
6741 caps = gst_caps_new_simple ("audio/x-ac3",
6742 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
6743 *codec_name = g_strdup ("AC-3 audio");
6744 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_EAC3,
6745 strlen (GST_MATROSKA_CODEC_ID_AUDIO_EAC3))) {
6746 caps = gst_caps_new_simple ("audio/x-eac3",
6747 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
6748 *codec_name = g_strdup ("E-AC-3 audio");
6749 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_DTS)) {
6750 caps = gst_caps_new_simple ("audio/x-dts", NULL);
6751 *codec_name = g_strdup ("DTS audio");
6752 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_VORBIS)) {
6753 caps = gst_caps_new_simple ("audio/x-vorbis", NULL);
6754 context->send_xiph_headers = TRUE;
6755 /* vorbis decoder does tags */
6756 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_FLAC)) {
6757 caps = gst_caps_new_simple ("audio/x-flac", NULL);
6758 context->send_flac_headers = TRUE;
6759 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_SPEEX)) {
6760 caps = gst_caps_new_simple ("audio/x-speex", NULL);
6761 context->send_speex_headers = TRUE;
6762 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_ACM)) {
6763 gst_riff_strf_auds auds;
6766 GstBuffer *codec_data = gst_buffer_new ();
6768 /* little-endian -> byte-order */
6769 auds.format = GST_READ_UINT16_LE (data);
6770 auds.channels = GST_READ_UINT16_LE (data + 2);
6771 auds.rate = GST_READ_UINT32_LE (data + 4);
6772 auds.av_bps = GST_READ_UINT32_LE (data + 8);
6773 auds.blockalign = GST_READ_UINT16_LE (data + 12);
6774 auds.size = GST_READ_UINT16_LE (data + 16);
6776 /* 18 is the waveformatex size */
6777 gst_buffer_set_data (codec_data, data + 18, auds.size);
6780 *riff_audio_fmt = auds.format;
6782 caps = gst_riff_create_audio_caps (auds.format, NULL, &auds, NULL,
6783 codec_data, codec_name);
6784 gst_buffer_unref (codec_data);
6787 GST_WARNING ("Unhandled RIFF audio format 0x%02x", auds.format);
6790 } else if (g_str_has_prefix (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC)) {
6791 GstBuffer *priv = NULL;
6793 gint rate_idx, profile;
6794 guint8 *data = NULL;
6796 /* unspecified AAC profile with opaque private codec data */
6797 if (strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC) == 0) {
6798 if (context->codec_priv_size >= 2) {
6799 guint obj_type, freq_index, explicit_freq_bytes = 0;
6801 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
6803 freq_index = (GST_READ_UINT16_BE (context->codec_priv) & 0x780) >> 7;
6804 obj_type = (GST_READ_UINT16_BE (context->codec_priv) & 0xF800) >> 11;
6805 if (freq_index == 15)
6806 explicit_freq_bytes = 3;
6807 GST_DEBUG ("obj_type = %u, freq_index = %u", obj_type, freq_index);
6808 priv = gst_buffer_new_and_alloc (context->codec_priv_size);
6809 memcpy (GST_BUFFER_DATA (priv), context->codec_priv,
6810 context->codec_priv_size);
6811 /* assume SBR if samplerate <= 24kHz */
6812 if (obj_type == 5 || (freq_index >= 6 && freq_index != 15) ||
6813 (context->codec_priv_size == (5 + explicit_freq_bytes))) {
6814 audiocontext->samplerate *= 2;
6817 GST_WARNING ("Opaque A_AAC codec ID, but no codec private data");
6818 /* this is pretty broken;
6819 * maybe we need to make up some default private,
6820 * or maybe ADTS data got dumped in.
6821 * Let's set up some private data now, and check actual data later */
6822 /* just try this and see what happens ... */
6823 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
6824 context->postprocess_frame = gst_matroska_demux_check_aac;
6828 /* make up decoder-specific data if it is not supplied */
6830 priv = gst_buffer_new_and_alloc (5);
6831 data = GST_BUFFER_DATA (priv);
6832 rate_idx = aac_rate_idx (audiocontext->samplerate);
6833 profile = aac_profile_idx (codec_id);
6835 data[0] = ((profile + 1) << 3) | ((rate_idx & 0xE) >> 1);
6836 data[1] = ((rate_idx & 0x1) << 7) | (audiocontext->channels << 3);
6837 GST_BUFFER_SIZE (priv) = 2;
6839 if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2,
6840 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2))) {
6842 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4,
6843 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4))) {
6846 if (g_strrstr (codec_id, "SBR")) {
6847 /* HE-AAC (aka SBR AAC) */
6848 audiocontext->samplerate *= 2;
6849 rate_idx = aac_rate_idx (audiocontext->samplerate);
6850 data[2] = AAC_SYNC_EXTENSION_TYPE >> 3;
6851 data[3] = ((AAC_SYNC_EXTENSION_TYPE & 0x07) << 5) | 5;
6852 data[4] = (1 << 7) | (rate_idx << 3);
6853 GST_BUFFER_SIZE (priv) = 5;
6856 gst_buffer_unref (priv);
6858 GST_ERROR ("Unknown AAC profile and no codec private data");
6863 caps = gst_caps_new_simple ("audio/mpeg",
6864 "mpegversion", G_TYPE_INT, mpegversion,
6865 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
6866 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
6867 *codec_name = g_strdup_printf ("MPEG-%d AAC audio", mpegversion);
6869 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TTA)) {
6870 caps = gst_caps_new_simple ("audio/x-tta",
6871 "width", G_TYPE_INT, audiocontext->bitdepth, NULL);
6872 *codec_name = g_strdup ("TTA audio");
6873 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_WAVPACK4)) {
6874 caps = gst_caps_new_simple ("audio/x-wavpack",
6875 "width", G_TYPE_INT, audiocontext->bitdepth,
6876 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
6877 *codec_name = g_strdup ("Wavpack audio");
6878 context->postprocess_frame = gst_matroska_demux_add_wvpk_header;
6879 audiocontext->wvpk_block_index = 0;
6880 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4)) ||
6881 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4)) ||
6882 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))) {
6883 gint raversion = -1;
6885 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4))
6887 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))
6892 caps = gst_caps_new_simple ("audio/x-pn-realaudio",
6893 "raversion", G_TYPE_INT, raversion, NULL);
6894 /* Extract extra information from caps, mapping varies based on codec */
6895 if (data && (size >= 0x50)) {
6902 guint extra_data_size;
6904 GST_ERROR ("real audio raversion:%d", raversion);
6905 if (raversion == 8) {
6907 flavor = GST_READ_UINT16_BE (data + 22);
6908 packet_size = GST_READ_UINT32_BE (data + 24);
6909 height = GST_READ_UINT16_BE (data + 40);
6910 leaf_size = GST_READ_UINT16_BE (data + 44);
6911 sample_width = GST_READ_UINT16_BE (data + 58);
6912 extra_data_size = GST_READ_UINT32_BE (data + 74);
6915 ("flavor:%d, packet_size:%d, height:%d, leaf_size:%d, sample_width:%d, extra_data_size:%d",
6916 flavor, packet_size, height, leaf_size, sample_width,
6918 gst_caps_set_simple (caps, "flavor", G_TYPE_INT, flavor, "packet_size",
6919 G_TYPE_INT, packet_size, "height", G_TYPE_INT, height, "leaf_size",
6920 G_TYPE_INT, leaf_size, "width", G_TYPE_INT, sample_width, NULL);
6922 if ((size - 78) >= extra_data_size) {
6923 priv = gst_buffer_new_and_alloc (extra_data_size);
6924 memcpy (GST_BUFFER_DATA (priv), data + 78, extra_data_size);
6925 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
6926 gst_buffer_unref (priv);
6931 *codec_name = g_strdup_printf ("RealAudio %d.0", raversion);
6932 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_SIPR)) {
6933 caps = gst_caps_new_simple ("audio/x-sipro", NULL);
6934 *codec_name = g_strdup ("Sipro/ACELP.NET Voice Codec");
6935 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_RALF)) {
6936 caps = gst_caps_new_simple ("audio/x-ralf-mpeg4-generic", NULL);
6937 *codec_name = g_strdup ("Real Audio Lossless");
6938 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_ATRC)) {
6939 caps = gst_caps_new_simple ("audio/x-vnd.sony.atrac3", NULL);
6940 *codec_name = g_strdup ("Sony ATRAC3");
6942 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
6947 if (audiocontext->samplerate > 0 && audiocontext->channels > 0) {
6950 for (i = 0; i < gst_caps_get_size (caps); i++) {
6951 gst_structure_set (gst_caps_get_structure (caps, i),
6952 "channels", G_TYPE_INT, audiocontext->channels,
6953 "rate", G_TYPE_INT, audiocontext->samplerate, NULL);
6957 gst_caps_do_simplify (caps);
6964 gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
6965 subtitlecontext, const gchar * codec_id, gpointer data, guint size)
6967 GstCaps *caps = NULL;
6968 GstMatroskaTrackContext *context =
6969 (GstMatroskaTrackContext *) subtitlecontext;
6971 /* for backwards compatibility */
6972 if (!g_ascii_strcasecmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASCII))
6973 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8;
6974 else if (!g_ascii_strcasecmp (codec_id, "S_SSA"))
6975 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_SSA;
6976 else if (!g_ascii_strcasecmp (codec_id, "S_ASS"))
6977 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_ASS;
6978 else if (!g_ascii_strcasecmp (codec_id, "S_USF"))
6979 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_USF;
6981 /* TODO: Add GST_MATROSKA_CODEC_ID_SUBTITLE_BMP support
6982 * Check if we have to do something with codec_private */
6983 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8)) {
6984 caps = gst_caps_new_simple ("text/plain", NULL);
6985 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
6986 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_SSA)) {
6987 caps = gst_caps_new_simple ("application/x-ssa", NULL);
6988 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
6989 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASS)) {
6990 caps = gst_caps_new_simple ("application/x-ass", NULL);
6991 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
6992 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_USF)) {
6993 caps = gst_caps_new_simple ("application/x-usf", NULL);
6994 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
6995 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB)) {
6996 caps = gst_caps_new_simple ("video/x-dvd-subpicture", NULL);
6997 ((GstMatroskaTrackContext *) subtitlecontext)->send_dvd_event = TRUE;
6998 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_HDMVPGS)) {
6999 caps = gst_caps_new_simple ("subpicture/x-pgs", NULL);
7000 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_KATE)) {
7001 caps = gst_caps_new_simple ("subtitle/x-kate", NULL);
7002 context->send_xiph_headers = TRUE;
7004 GST_DEBUG ("Unknown subtitle stream: codec_id='%s'", codec_id);
7005 caps = gst_caps_new_simple ("application/x-subtitle-unknown", NULL);
7008 if (data != NULL && size > 0) {
7011 buf = gst_buffer_new_and_alloc (size);
7012 memcpy (GST_BUFFER_DATA (buf), data, size);
7013 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, buf, NULL);
7014 gst_buffer_unref (buf);
7021 gst_matroska_demux_set_index (GstElement * element, GstIndex * index)
7023 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
7025 GST_OBJECT_LOCK (demux);
7026 if (demux->element_index)
7027 gst_object_unref (demux->element_index);
7028 demux->element_index = index ? gst_object_ref (index) : NULL;
7029 GST_OBJECT_UNLOCK (demux);
7030 GST_DEBUG_OBJECT (demux, "Set index %" GST_PTR_FORMAT, demux->element_index);
7034 gst_matroska_demux_get_index (GstElement * element)
7036 GstIndex *result = NULL;
7037 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
7039 GST_OBJECT_LOCK (demux);
7040 if (demux->element_index)
7041 result = gst_object_ref (demux->element_index);
7042 GST_OBJECT_UNLOCK (demux);
7044 GST_DEBUG_OBJECT (demux, "Returning index %" GST_PTR_FORMAT, result);
7049 static GstStateChangeReturn
7050 gst_matroska_demux_change_state (GstElement * element,
7051 GstStateChange transition)
7053 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
7054 GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
7056 /* handle upwards state changes here */
7057 switch (transition) {
7062 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
7064 /* handle downwards state changes */
7065 switch (transition) {
7066 case GST_STATE_CHANGE_PAUSED_TO_READY:
7067 gst_matroska_demux_reset (GST_ELEMENT (demux));
7077 gst_matroska_demux_plugin_init (GstPlugin * plugin)
7081 /* create an elementfactory for the matroska_demux element */
7082 if (!gst_element_register (plugin, "matroskademux",
7083 GST_RANK_PRIMARY, GST_TYPE_MATROSKA_DEMUX))