1 /* GStreamer Matroska muxer/demuxer
2 * (c) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
3 * (c) 2006 Tim-Philipp Müller <tim centricular net>
4 * (c) 2008 Sebastian Dröge <slomo@circular-chaos.org>
5 * (c) 2011 Debarshi Ray <rishi@gnu.org>
7 * matroska-demux.c: matroska file/stream demuxer
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Library General Public License for more details.
19 * You should have received a copy of the GNU Library General Public
20 * License along with this library; if not, write to the
21 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22 * Boston, MA 02111-1307, USA.
25 /* TODO: check CRC32 if present
26 * TODO: there can be a segment after the first segment. Handle like
27 * chained oggs. Fixes #334082
28 * TODO: Test samples: http://www.matroska.org/samples/matrix/index.html
29 * http://samples.mplayerhq.hu/Matroska/
30 * TODO: check if demuxing is done correct for all codecs according to spec
31 * TODO: seeking with incomplete or without CUE
35 * SECTION:element-matroskademux
37 * matroskademux demuxes a Matroska file into the different contained streams.
40 * <title>Example launch line</title>
42 * gst-launch -v filesrc location=/path/to/mkv ! matroskademux ! vorbisdec ! audioconvert ! audioresample ! autoaudiosink
43 * ]| This pipeline demuxes a Matroska file and outputs the contained Vorbis audio.
54 #include <glib/gprintf.h>
56 /* For AVI compatibility mode
57 and for fourcc stuff */
58 #include <gst/riff/riff-read.h>
59 #include <gst/riff/riff-ids.h>
60 #include <gst/riff/riff-media.h>
62 #include <gst/audio/audio.h>
63 #include <gst/tag/tag.h>
64 #include <gst/pbutils/pbutils.h>
66 #include "matroska-demux.h"
67 #include "matroska-ids.h"
69 GST_DEBUG_CATEGORY_STATIC (matroskademux_debug);
70 #define GST_CAT_DEFAULT matroskademux_debug
72 #define DEBUG_ELEMENT_START(demux, ebml, element) \
73 GST_DEBUG_OBJECT (demux, "Parsing " element " element at offset %" \
74 G_GUINT64_FORMAT, gst_ebml_read_get_pos (ebml))
76 #define DEBUG_ELEMENT_STOP(demux, ebml, element, ret) \
77 GST_DEBUG_OBJECT (demux, "Parsing " element " element " \
78 " finished with '%s'", gst_flow_get_name (ret))
88 #define DEFAULT_MAX_GAP_TIME (2 * GST_SECOND)
90 static GstStaticPadTemplate sink_templ = GST_STATIC_PAD_TEMPLATE ("sink",
93 GST_STATIC_CAPS ("video/x-matroska; video/webm")
96 /* TODO: fill in caps! */
98 static GstStaticPadTemplate audio_src_templ =
99 GST_STATIC_PAD_TEMPLATE ("audio_%u",
102 GST_STATIC_CAPS ("ANY")
105 static GstStaticPadTemplate video_src_templ =
106 GST_STATIC_PAD_TEMPLATE ("video_%u",
109 GST_STATIC_CAPS ("ANY")
112 static GstStaticPadTemplate subtitle_src_templ =
113 GST_STATIC_PAD_TEMPLATE ("subtitle_%u",
116 GST_STATIC_CAPS ("text/x-pango-markup; application/x-ssa; "
117 "application/x-ass;application/x-usf; video/x-dvd-subpicture; "
118 "subpicture/x-pgs; subtitle/x-kate; " "application/x-subtitle-unknown")
121 static GstFlowReturn gst_matroska_demux_parse_id (GstMatroskaDemux * demux,
122 guint32 id, guint64 length, guint needed);
124 /* element functions */
125 static void gst_matroska_demux_loop (GstPad * pad);
127 static gboolean gst_matroska_demux_element_send_event (GstElement * element,
129 static gboolean gst_matroska_demux_element_query (GstElement * element,
133 static gboolean gst_matroska_demux_sink_activate (GstPad * sinkpad,
135 static gboolean gst_matroska_demux_sink_activate_mode (GstPad * sinkpad,
136 GstObject * parent, GstPadMode mode, gboolean active);
138 static gboolean gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
139 GstPad * pad, GstEvent * event);
140 static gboolean gst_matroska_demux_handle_src_event (GstPad * pad,
141 GstObject * parent, GstEvent * event);
142 static gboolean gst_matroska_demux_handle_src_query (GstPad * pad,
143 GstObject * parent, GstQuery * query);
145 static gboolean gst_matroska_demux_handle_sink_event (GstPad * pad,
146 GstObject * parent, GstEvent * event);
147 static GstFlowReturn gst_matroska_demux_chain (GstPad * pad,
148 GstObject * object, GstBuffer * buffer);
150 static GstStateChangeReturn
151 gst_matroska_demux_change_state (GstElement * element,
152 GstStateChange transition);
155 gst_matroska_demux_set_index (GstElement * element, GstIndex * index);
156 static GstIndex *gst_matroska_demux_get_index (GstElement * element);
160 static GstCaps *gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext
161 * videocontext, const gchar * codec_id, guint8 * data, guint size,
162 gchar ** codec_name, guint32 * riff_fourcc);
163 static GstCaps *gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext
164 * audiocontext, const gchar * codec_id, guint8 * data, guint size,
165 gchar ** codec_name, guint16 * riff_audio_fmt);
167 * gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
168 subtitlecontext, const gchar * codec_id, gpointer data, guint size);
171 static void gst_matroska_demux_reset (GstElement * element);
172 static gboolean perform_seek_to_offset (GstMatroskaDemux * demux,
175 /* gobject functions */
176 static void gst_matroska_demux_set_property (GObject * object,
177 guint prop_id, const GValue * value, GParamSpec * pspec);
178 static void gst_matroska_demux_get_property (GObject * object,
179 guint prop_id, GValue * value, GParamSpec * pspec);
181 GType gst_matroska_demux_get_type (void);
182 #define parent_class gst_matroska_demux_parent_class
183 G_DEFINE_TYPE (GstMatroskaDemux, gst_matroska_demux, GST_TYPE_ELEMENT);
186 gst_matroska_demux_finalize (GObject * object)
188 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (object);
190 if (demux->common.src) {
191 g_ptr_array_free (demux->common.src, TRUE);
192 demux->common.src = NULL;
195 if (demux->common.global_tags) {
196 gst_tag_list_free (demux->common.global_tags);
197 demux->common.global_tags = NULL;
200 g_object_unref (demux->common.adapter);
202 G_OBJECT_CLASS (parent_class)->finalize (object);
206 gst_matroska_demux_class_init (GstMatroskaDemuxClass * klass)
208 GObjectClass *gobject_class = (GObjectClass *) klass;
209 GstElementClass *gstelement_class = (GstElementClass *) klass;
211 GST_DEBUG_CATEGORY_INIT (matroskademux_debug, "matroskademux", 0,
214 gobject_class->finalize = gst_matroska_demux_finalize;
216 gobject_class->get_property = gst_matroska_demux_get_property;
217 gobject_class->set_property = gst_matroska_demux_set_property;
219 g_object_class_install_property (gobject_class, ARG_MAX_GAP_TIME,
220 g_param_spec_uint64 ("max-gap-time", "Maximum gap time",
221 "The demuxer sends out segment events for skipping "
222 "gaps longer than this (0 = disabled).", 0, G_MAXUINT64,
223 DEFAULT_MAX_GAP_TIME, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
225 gstelement_class->change_state =
226 GST_DEBUG_FUNCPTR (gst_matroska_demux_change_state);
227 gstelement_class->send_event =
228 GST_DEBUG_FUNCPTR (gst_matroska_demux_element_send_event);
229 gstelement_class->query =
230 GST_DEBUG_FUNCPTR (gst_matroska_demux_element_query);
232 gstelement_class->set_index =
233 GST_DEBUG_FUNCPTR (gst_matroska_demux_set_index);
234 gstelement_class->get_index =
235 GST_DEBUG_FUNCPTR (gst_matroska_demux_get_index);
238 gst_element_class_add_pad_template (gstelement_class,
239 gst_static_pad_template_get (&video_src_templ));
240 gst_element_class_add_pad_template (gstelement_class,
241 gst_static_pad_template_get (&audio_src_templ));
242 gst_element_class_add_pad_template (gstelement_class,
243 gst_static_pad_template_get (&subtitle_src_templ));
244 gst_element_class_add_pad_template (gstelement_class,
245 gst_static_pad_template_get (&sink_templ));
247 gst_element_class_set_static_metadata (gstelement_class, "Matroska demuxer",
249 "Demuxes Matroska/WebM streams into video/audio/subtitles",
250 "GStreamer maintainers <gstreamer-devel@lists.sourceforge.net>");
254 gst_matroska_demux_init (GstMatroskaDemux * demux)
256 demux->common.sinkpad = gst_pad_new_from_static_template (&sink_templ,
258 gst_pad_set_activate_function (demux->common.sinkpad,
259 GST_DEBUG_FUNCPTR (gst_matroska_demux_sink_activate));
260 gst_pad_set_activatemode_function (demux->common.sinkpad,
261 GST_DEBUG_FUNCPTR (gst_matroska_demux_sink_activate_mode));
262 gst_pad_set_chain_function (demux->common.sinkpad,
263 GST_DEBUG_FUNCPTR (gst_matroska_demux_chain));
264 gst_pad_set_event_function (demux->common.sinkpad,
265 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_sink_event));
266 gst_element_add_pad (GST_ELEMENT (demux), demux->common.sinkpad);
268 /* initial stream no. */
269 demux->common.src = NULL;
271 demux->common.writing_app = NULL;
272 demux->common.muxing_app = NULL;
273 demux->common.index = NULL;
274 demux->common.global_tags = NULL;
276 demux->common.adapter = gst_adapter_new ();
278 /* property defaults */
279 demux->max_gap_time = DEFAULT_MAX_GAP_TIME;
281 GST_OBJECT_FLAG_SET (demux, GST_ELEMENT_FLAG_INDEXABLE);
284 gst_matroska_demux_reset (GST_ELEMENT (demux));
288 gst_matroska_track_free (GstMatroskaTrackContext * track)
290 g_free (track->codec_id);
291 g_free (track->codec_name);
292 g_free (track->name);
293 g_free (track->language);
294 g_free (track->codec_priv);
295 g_free (track->codec_state);
297 if (track->encodings != NULL) {
300 for (i = 0; i < track->encodings->len; ++i) {
301 GstMatroskaTrackEncoding *enc = &g_array_index (track->encodings,
302 GstMatroskaTrackEncoding,
305 g_free (enc->comp_settings);
307 g_array_free (track->encodings, TRUE);
310 if (track->pending_tags)
311 gst_tag_list_free (track->pending_tags);
313 if (track->index_table)
314 g_array_free (track->index_table, TRUE);
320 * Returns the aggregated GstFlowReturn.
323 gst_matroska_demux_combine_flows (GstMatroskaDemux * demux,
324 GstMatroskaTrackContext * track, GstFlowReturn ret)
328 /* store the value */
329 track->last_flow = ret;
331 /* any other error that is not-linked can be returned right away */
332 if (ret != GST_FLOW_NOT_LINKED)
335 /* only return NOT_LINKED if all other pads returned NOT_LINKED */
336 g_assert (demux->common.src->len == demux->common.num_streams);
337 for (i = 0; i < demux->common.src->len; i++) {
338 GstMatroskaTrackContext *ostream = g_ptr_array_index (demux->common.src,
344 ret = ostream->last_flow;
345 /* some other return value (must be SUCCESS but we can return
346 * other values as well) */
347 if (ret != GST_FLOW_NOT_LINKED)
350 /* if we get here, all other pads were unlinked and we return
353 GST_LOG_OBJECT (demux, "combined return %s", gst_flow_get_name (ret));
358 gst_matroska_demux_free_parsed_el (gpointer mem, gpointer user_data)
360 g_slice_free (guint64, mem);
364 gst_matroska_demux_reset (GstElement * element)
366 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
369 GST_DEBUG_OBJECT (demux, "Resetting state");
372 demux->common.state = GST_MATROSKA_READ_STATE_START;
374 /* clean up existing streams */
375 if (demux->common.src) {
376 g_assert (demux->common.src->len == demux->common.num_streams);
377 for (i = 0; i < demux->common.src->len; i++) {
378 GstMatroskaTrackContext *context = g_ptr_array_index (demux->common.src,
381 if (context->pad != NULL)
382 gst_element_remove_pad (GST_ELEMENT (demux), context->pad);
384 gst_caps_replace (&context->caps, NULL);
385 gst_matroska_track_free (context);
387 g_ptr_array_free (demux->common.src, TRUE);
389 demux->common.src = g_ptr_array_new ();
391 demux->common.num_streams = 0;
392 demux->num_a_streams = 0;
393 demux->num_t_streams = 0;
394 demux->num_v_streams = 0;
396 /* reset media info */
397 g_free (demux->common.writing_app);
398 demux->common.writing_app = NULL;
399 g_free (demux->common.muxing_app);
400 demux->common.muxing_app = NULL;
403 if (demux->common.index) {
404 g_array_free (demux->common.index, TRUE);
405 demux->common.index = NULL;
408 if (demux->clusters) {
409 g_array_free (demux->clusters, TRUE);
410 demux->clusters = NULL;
415 demux->common.time_scale = 1000000;
416 demux->common.created = G_MININT64;
418 demux->common.index_parsed = FALSE;
419 demux->tracks_parsed = FALSE;
420 demux->common.segmentinfo_parsed = FALSE;
421 demux->common.attachments_parsed = FALSE;
422 demux->common.chapters_parsed = FALSE;
424 g_list_foreach (demux->common.tags_parsed,
425 (GFunc) gst_matroska_demux_free_parsed_el, NULL);
426 g_list_free (demux->common.tags_parsed);
427 demux->common.tags_parsed = NULL;
429 g_list_foreach (demux->seek_parsed,
430 (GFunc) gst_matroska_demux_free_parsed_el, NULL);
431 g_list_free (demux->seek_parsed);
432 demux->seek_parsed = NULL;
434 gst_segment_init (&demux->common.segment, GST_FORMAT_TIME);
435 demux->last_stop_end = GST_CLOCK_TIME_NONE;
436 demux->seek_block = 0;
437 demux->stream_start_time = GST_CLOCK_TIME_NONE;
439 demux->common.offset = 0;
440 demux->cluster_time = GST_CLOCK_TIME_NONE;
441 demux->cluster_offset = 0;
442 demux->next_cluster_offset = 0;
443 demux->index_offset = 0;
444 demux->seekable = FALSE;
445 demux->need_segment = FALSE;
446 demux->building_index = FALSE;
447 if (demux->seek_event) {
448 gst_event_unref (demux->seek_event);
449 demux->seek_event = NULL;
452 demux->seek_index = NULL;
453 demux->seek_entry = 0;
455 if (demux->new_segment) {
456 gst_event_unref (demux->new_segment);
457 demux->new_segment = NULL;
460 if (demux->common.element_index) {
461 gst_object_unref (demux->common.element_index);
462 demux->common.element_index = NULL;
464 demux->common.element_index_writer_id = -1;
467 if (demux->common.global_tags) {
468 gst_tag_list_free (demux->common.global_tags);
470 demux->common.global_tags = gst_tag_list_new_empty ();
472 if (demux->common.cached_buffer) {
473 if (demux->common.cached_data) {
474 gst_buffer_unmap (demux->common.cached_buffer, &demux->common.cached_map);
475 demux->common.cached_data = NULL;
477 gst_buffer_unref (demux->common.cached_buffer);
478 demux->common.cached_buffer = NULL;
481 /* free chapters TOC if any */
482 if (demux->common.toc) {
483 gst_toc_free (demux->common.toc);
484 demux->common.toc = NULL;
487 demux->invalid_duration = FALSE;
491 gst_matroska_decode_buffer (GstMatroskaTrackContext * context, GstBuffer * buf)
497 g_return_val_if_fail (GST_IS_BUFFER (buf), NULL);
499 GST_DEBUG ("decoding buffer %p", buf);
501 gst_buffer_map (buf, &map, GST_MAP_READ);
505 g_return_val_if_fail (size > 0, buf);
507 if (gst_matroska_decode_data (context->encodings, &data, &size,
508 GST_MATROSKA_TRACK_ENCODING_SCOPE_FRAME, FALSE)) {
509 gst_buffer_unmap (buf, &map);
510 gst_buffer_unref (buf);
511 return gst_buffer_new_wrapped (data, size);
513 GST_DEBUG ("decode data failed");
514 gst_buffer_unmap (buf, &map);
515 gst_buffer_unref (buf);
521 gst_matroska_demux_add_stream (GstMatroskaDemux * demux, GstEbmlRead * ebml)
523 GstElementClass *klass = GST_ELEMENT_GET_CLASS (demux);
524 GstMatroskaTrackContext *context;
525 GstPadTemplate *templ = NULL;
526 GstCaps *caps = NULL;
527 gchar *padname = NULL;
529 guint32 id, riff_fourcc = 0;
530 guint16 riff_audio_fmt = 0;
531 GstTagList *list = NULL;
534 DEBUG_ELEMENT_START (demux, ebml, "TrackEntry");
536 /* start with the master */
537 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
538 DEBUG_ELEMENT_STOP (demux, ebml, "TrackEntry", ret);
542 /* allocate generic... if we know the type, we'll g_renew()
543 * with the precise type */
544 context = g_new0 (GstMatroskaTrackContext, 1);
545 g_ptr_array_add (demux->common.src, context);
546 context->index = demux->common.num_streams;
547 context->index_writer_id = -1;
548 context->type = 0; /* no type yet */
549 context->default_duration = 0;
551 context->set_discont = TRUE;
552 context->timecodescale = 1.0;
554 GST_MATROSKA_TRACK_ENABLED | GST_MATROSKA_TRACK_DEFAULT |
555 GST_MATROSKA_TRACK_LACING;
556 context->last_flow = GST_FLOW_OK;
557 context->to_offset = G_MAXINT64;
558 context->alignment = 1;
559 demux->common.num_streams++;
560 g_assert (demux->common.src->len == demux->common.num_streams);
562 GST_DEBUG_OBJECT (demux, "Stream number %d", context->index);
564 /* try reading the trackentry headers */
565 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
566 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
570 /* track number (unique stream ID) */
571 case GST_MATROSKA_ID_TRACKNUMBER:{
574 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
578 GST_ERROR_OBJECT (demux, "Invalid TrackNumber 0");
579 ret = GST_FLOW_ERROR;
581 } else if (!gst_matroska_read_common_tracknumber_unique (&demux->common,
583 GST_ERROR_OBJECT (demux, "TrackNumber %" G_GUINT64_FORMAT
584 " is not unique", num);
585 ret = GST_FLOW_ERROR;
589 GST_DEBUG_OBJECT (demux, "TrackNumber: %" G_GUINT64_FORMAT, num);
593 /* track UID (unique identifier) */
594 case GST_MATROSKA_ID_TRACKUID:{
597 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
601 GST_ERROR_OBJECT (demux, "Invalid TrackUID 0");
602 ret = GST_FLOW_ERROR;
606 GST_DEBUG_OBJECT (demux, "TrackUID: %" G_GUINT64_FORMAT, num);
611 /* track type (video, audio, combined, subtitle, etc.) */
612 case GST_MATROSKA_ID_TRACKTYPE:{
615 if ((ret = gst_ebml_read_uint (ebml, &id, &track_type)) != GST_FLOW_OK) {
619 if (context->type != 0 && context->type != track_type) {
620 GST_WARNING_OBJECT (demux,
621 "More than one tracktype defined in a TrackEntry - skipping");
623 } else if (track_type < 1 || track_type > 254) {
624 GST_WARNING_OBJECT (demux, "Invalid TrackType %" G_GUINT64_FORMAT,
629 GST_DEBUG_OBJECT (demux, "TrackType: %" G_GUINT64_FORMAT, track_type);
631 /* ok, so we're actually going to reallocate this thing */
632 switch (track_type) {
633 case GST_MATROSKA_TRACK_TYPE_VIDEO:
634 gst_matroska_track_init_video_context (&context);
636 case GST_MATROSKA_TRACK_TYPE_AUDIO:
637 gst_matroska_track_init_audio_context (&context);
639 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
640 gst_matroska_track_init_subtitle_context (&context);
642 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
643 case GST_MATROSKA_TRACK_TYPE_LOGO:
644 case GST_MATROSKA_TRACK_TYPE_BUTTONS:
645 case GST_MATROSKA_TRACK_TYPE_CONTROL:
647 GST_WARNING_OBJECT (demux,
648 "Unknown or unsupported TrackType %" G_GUINT64_FORMAT,
653 g_ptr_array_index (demux->common.src, demux->common.num_streams - 1)
658 /* tracktype specific stuff for video */
659 case GST_MATROSKA_ID_TRACKVIDEO:{
660 GstMatroskaTrackVideoContext *videocontext;
662 DEBUG_ELEMENT_START (demux, ebml, "TrackVideo");
664 if (!gst_matroska_track_init_video_context (&context)) {
665 GST_WARNING_OBJECT (demux,
666 "TrackVideo element in non-video track - ignoring track");
667 ret = GST_FLOW_ERROR;
669 } else if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
672 videocontext = (GstMatroskaTrackVideoContext *) context;
673 g_ptr_array_index (demux->common.src, demux->common.num_streams - 1)
676 while (ret == GST_FLOW_OK &&
677 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
678 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
682 /* Should be one level up but some broken muxers write it here. */
683 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
686 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
690 GST_WARNING_OBJECT (demux, "Invalid TrackDefaultDuration 0");
694 GST_DEBUG_OBJECT (demux,
695 "TrackDefaultDuration: %" G_GUINT64_FORMAT, num);
696 context->default_duration = num;
700 /* video framerate */
701 /* NOTE: This one is here only for backward compatibility.
702 * Use _TRACKDEFAULDURATION one level up. */
703 case GST_MATROSKA_ID_VIDEOFRAMERATE:{
706 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
710 GST_WARNING_OBJECT (demux, "Invalid TrackVideoFPS %lf", num);
714 GST_DEBUG_OBJECT (demux, "TrackVideoFrameRate: %lf", num);
715 if (context->default_duration == 0)
716 context->default_duration =
717 gst_gdouble_to_guint64 ((gdouble) GST_SECOND * (1.0 / num));
718 videocontext->default_fps = num;
722 /* width of the size to display the video at */
723 case GST_MATROSKA_ID_VIDEODISPLAYWIDTH:{
726 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
730 GST_WARNING_OBJECT (demux, "Invalid TrackVideoDisplayWidth 0");
734 GST_DEBUG_OBJECT (demux,
735 "TrackVideoDisplayWidth: %" G_GUINT64_FORMAT, num);
736 videocontext->display_width = num;
740 /* height of the size to display the video at */
741 case GST_MATROSKA_ID_VIDEODISPLAYHEIGHT:{
744 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
748 GST_WARNING_OBJECT (demux, "Invalid TrackVideoDisplayHeight 0");
752 GST_DEBUG_OBJECT (demux,
753 "TrackVideoDisplayHeight: %" G_GUINT64_FORMAT, num);
754 videocontext->display_height = num;
758 /* width of the video in the file */
759 case GST_MATROSKA_ID_VIDEOPIXELWIDTH:{
762 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
766 GST_WARNING_OBJECT (demux, "Invalid TrackVideoPixelWidth 0");
770 GST_DEBUG_OBJECT (demux,
771 "TrackVideoPixelWidth: %" G_GUINT64_FORMAT, num);
772 videocontext->pixel_width = num;
776 /* height of the video in the file */
777 case GST_MATROSKA_ID_VIDEOPIXELHEIGHT:{
780 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
784 GST_WARNING_OBJECT (demux, "Invalid TrackVideoPixelHeight 0");
788 GST_DEBUG_OBJECT (demux,
789 "TrackVideoPixelHeight: %" G_GUINT64_FORMAT, num);
790 videocontext->pixel_height = num;
794 /* whether the video is interlaced */
795 case GST_MATROSKA_ID_VIDEOFLAGINTERLACED:{
798 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
802 context->flags |= GST_MATROSKA_VIDEOTRACK_INTERLACED;
804 context->flags &= ~GST_MATROSKA_VIDEOTRACK_INTERLACED;
805 GST_DEBUG_OBJECT (demux, "TrackVideoInterlaced: %d",
806 (context->flags & GST_MATROSKA_VIDEOTRACK_INTERLACED) ? 1 :
811 /* aspect ratio behaviour */
812 case GST_MATROSKA_ID_VIDEOASPECTRATIOTYPE:{
815 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
818 if (num != GST_MATROSKA_ASPECT_RATIO_MODE_FREE &&
819 num != GST_MATROSKA_ASPECT_RATIO_MODE_KEEP &&
820 num != GST_MATROSKA_ASPECT_RATIO_MODE_FIXED) {
821 GST_WARNING_OBJECT (demux,
822 "Unknown TrackVideoAspectRatioType 0x%x", (guint) num);
825 GST_DEBUG_OBJECT (demux,
826 "TrackVideoAspectRatioType: %" G_GUINT64_FORMAT, num);
827 videocontext->asr_mode = num;
831 /* colourspace (only matters for raw video) fourcc */
832 case GST_MATROSKA_ID_VIDEOCOLOURSPACE:{
837 gst_ebml_read_binary (ebml, &id, &data,
838 &datalen)) != GST_FLOW_OK)
843 GST_WARNING_OBJECT (demux,
844 "Invalid TrackVideoColourSpace length %" G_GUINT64_FORMAT,
849 memcpy (&videocontext->fourcc, data, 4);
850 GST_DEBUG_OBJECT (demux,
851 "TrackVideoColourSpace: %" GST_FOURCC_FORMAT,
852 GST_FOURCC_ARGS (videocontext->fourcc));
858 GST_WARNING_OBJECT (demux,
859 "Unknown TrackVideo subelement 0x%x - ignoring", id);
861 case GST_MATROSKA_ID_VIDEOSTEREOMODE:
862 case GST_MATROSKA_ID_VIDEODISPLAYUNIT:
863 case GST_MATROSKA_ID_VIDEOPIXELCROPBOTTOM:
864 case GST_MATROSKA_ID_VIDEOPIXELCROPTOP:
865 case GST_MATROSKA_ID_VIDEOPIXELCROPLEFT:
866 case GST_MATROSKA_ID_VIDEOPIXELCROPRIGHT:
867 case GST_MATROSKA_ID_VIDEOGAMMAVALUE:
868 ret = gst_ebml_read_skip (ebml);
873 DEBUG_ELEMENT_STOP (demux, ebml, "TrackVideo", ret);
877 /* tracktype specific stuff for audio */
878 case GST_MATROSKA_ID_TRACKAUDIO:{
879 GstMatroskaTrackAudioContext *audiocontext;
881 DEBUG_ELEMENT_START (demux, ebml, "TrackAudio");
883 if (!gst_matroska_track_init_audio_context (&context)) {
884 GST_WARNING_OBJECT (demux,
885 "TrackAudio element in non-audio track - ignoring track");
886 ret = GST_FLOW_ERROR;
890 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
893 audiocontext = (GstMatroskaTrackAudioContext *) context;
894 g_ptr_array_index (demux->common.src, demux->common.num_streams - 1)
897 while (ret == GST_FLOW_OK &&
898 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
899 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
904 case GST_MATROSKA_ID_AUDIOSAMPLINGFREQ:{
907 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
912 GST_WARNING_OBJECT (demux,
913 "Invalid TrackAudioSamplingFrequency %lf", num);
917 GST_DEBUG_OBJECT (demux, "TrackAudioSamplingFrequency: %lf", num);
918 audiocontext->samplerate = num;
923 case GST_MATROSKA_ID_AUDIOBITDEPTH:{
926 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
930 GST_WARNING_OBJECT (demux, "Invalid TrackAudioBitDepth 0");
934 GST_DEBUG_OBJECT (demux, "TrackAudioBitDepth: %" G_GUINT64_FORMAT,
936 audiocontext->bitdepth = num;
941 case GST_MATROSKA_ID_AUDIOCHANNELS:{
944 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
948 GST_WARNING_OBJECT (demux, "Invalid TrackAudioChannels 0");
952 GST_DEBUG_OBJECT (demux, "TrackAudioChannels: %" G_GUINT64_FORMAT,
954 audiocontext->channels = num;
959 GST_WARNING_OBJECT (demux,
960 "Unknown TrackAudio subelement 0x%x - ignoring", id);
962 case GST_MATROSKA_ID_AUDIOCHANNELPOSITIONS:
963 case GST_MATROSKA_ID_AUDIOOUTPUTSAMPLINGFREQ:
964 ret = gst_ebml_read_skip (ebml);
969 DEBUG_ELEMENT_STOP (demux, ebml, "TrackAudio", ret);
974 /* codec identifier */
975 case GST_MATROSKA_ID_CODECID:{
978 if ((ret = gst_ebml_read_ascii (ebml, &id, &text)) != GST_FLOW_OK)
981 GST_DEBUG_OBJECT (demux, "CodecID: %s", GST_STR_NULL (text));
982 context->codec_id = text;
986 /* codec private data */
987 case GST_MATROSKA_ID_CODECPRIVATE:{
992 gst_ebml_read_binary (ebml, &id, &data, &size)) != GST_FLOW_OK)
995 context->codec_priv = data;
996 context->codec_priv_size = size;
998 GST_DEBUG_OBJECT (demux, "CodecPrivate of size %" G_GUINT64_FORMAT,
1003 /* name of the codec */
1004 case GST_MATROSKA_ID_CODECNAME:{
1007 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1010 GST_DEBUG_OBJECT (demux, "CodecName: %s", GST_STR_NULL (text));
1011 context->codec_name = text;
1015 /* name of this track */
1016 case GST_MATROSKA_ID_TRACKNAME:{
1019 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1022 context->name = text;
1023 GST_DEBUG_OBJECT (demux, "TrackName: %s", GST_STR_NULL (text));
1027 /* language (matters for audio/subtitles, mostly) */
1028 case GST_MATROSKA_ID_TRACKLANGUAGE:{
1031 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1035 context->language = text;
1038 if (strlen (context->language) >= 4 && context->language[3] == '-')
1039 context->language[3] = '\0';
1041 GST_DEBUG_OBJECT (demux, "TrackLanguage: %s",
1042 GST_STR_NULL (context->language));
1046 /* whether this is actually used */
1047 case GST_MATROSKA_ID_TRACKFLAGENABLED:{
1050 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1054 context->flags |= GST_MATROSKA_TRACK_ENABLED;
1056 context->flags &= ~GST_MATROSKA_TRACK_ENABLED;
1058 GST_DEBUG_OBJECT (demux, "TrackEnabled: %d",
1059 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
1063 /* whether it's the default for this track type */
1064 case GST_MATROSKA_ID_TRACKFLAGDEFAULT:{
1067 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1071 context->flags |= GST_MATROSKA_TRACK_DEFAULT;
1073 context->flags &= ~GST_MATROSKA_TRACK_DEFAULT;
1075 GST_DEBUG_OBJECT (demux, "TrackDefault: %d",
1076 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
1080 /* whether the track must be used during playback */
1081 case GST_MATROSKA_ID_TRACKFLAGFORCED:{
1084 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1088 context->flags |= GST_MATROSKA_TRACK_FORCED;
1090 context->flags &= ~GST_MATROSKA_TRACK_FORCED;
1092 GST_DEBUG_OBJECT (demux, "TrackForced: %d",
1093 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
1097 /* lacing (like MPEG, where blocks don't end/start on frame
1099 case GST_MATROSKA_ID_TRACKFLAGLACING:{
1102 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1106 context->flags |= GST_MATROSKA_TRACK_LACING;
1108 context->flags &= ~GST_MATROSKA_TRACK_LACING;
1110 GST_DEBUG_OBJECT (demux, "TrackLacing: %d",
1111 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
1115 /* default length (in time) of one data block in this track */
1116 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
1119 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1124 GST_WARNING_OBJECT (demux, "Invalid TrackDefaultDuration 0");
1128 GST_DEBUG_OBJECT (demux, "TrackDefaultDuration: %" G_GUINT64_FORMAT,
1130 context->default_duration = num;
1134 case GST_MATROSKA_ID_CONTENTENCODINGS:{
1135 ret = gst_matroska_read_common_read_track_encodings (&demux->common,
1140 case GST_MATROSKA_ID_TRACKTIMECODESCALE:{
1143 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
1147 GST_WARNING_OBJECT (demux, "Invalid TrackTimeCodeScale %lf", num);
1151 GST_DEBUG_OBJECT (demux, "TrackTimeCodeScale: %lf", num);
1152 context->timecodescale = num;
1157 GST_WARNING ("Unknown TrackEntry subelement 0x%x - ignoring", id);
1160 /* we ignore these because they're nothing useful (i.e. crap)
1161 * or simply not implemented yet. */
1162 case GST_MATROSKA_ID_TRACKMINCACHE:
1163 case GST_MATROSKA_ID_TRACKMAXCACHE:
1164 case GST_MATROSKA_ID_MAXBLOCKADDITIONID:
1165 case GST_MATROSKA_ID_TRACKATTACHMENTLINK:
1166 case GST_MATROSKA_ID_TRACKOVERLAY:
1167 case GST_MATROSKA_ID_TRACKTRANSLATE:
1168 case GST_MATROSKA_ID_TRACKOFFSET:
1169 case GST_MATROSKA_ID_CODECSETTINGS:
1170 case GST_MATROSKA_ID_CODECINFOURL:
1171 case GST_MATROSKA_ID_CODECDOWNLOADURL:
1172 case GST_MATROSKA_ID_CODECDECODEALL:
1173 ret = gst_ebml_read_skip (ebml);
1178 DEBUG_ELEMENT_STOP (demux, ebml, "TrackEntry", ret);
1180 /* Decode codec private data if necessary */
1181 if (context->encodings && context->encodings->len > 0 && context->codec_priv
1182 && context->codec_priv_size > 0) {
1183 if (!gst_matroska_decode_data (context->encodings,
1184 &context->codec_priv, &context->codec_priv_size,
1185 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
1186 GST_WARNING_OBJECT (demux, "Decoding codec private data failed");
1187 ret = GST_FLOW_ERROR;
1191 if (context->type == 0 || context->codec_id == NULL || (ret != GST_FLOW_OK
1192 && ret != GST_FLOW_EOS)) {
1193 if (ret == GST_FLOW_OK || ret == GST_FLOW_EOS)
1194 GST_WARNING_OBJECT (ebml, "Unknown stream/codec in track entry header");
1196 demux->common.num_streams--;
1197 g_ptr_array_remove_index (demux->common.src, demux->common.num_streams);
1198 g_assert (demux->common.src->len == demux->common.num_streams);
1200 gst_matroska_track_free (context);
1206 /* now create the GStreamer connectivity */
1207 switch (context->type) {
1208 case GST_MATROSKA_TRACK_TYPE_VIDEO:{
1209 GstMatroskaTrackVideoContext *videocontext =
1210 (GstMatroskaTrackVideoContext *) context;
1212 padname = g_strdup_printf ("video_%u", demux->num_v_streams++);
1213 templ = gst_element_class_get_pad_template (klass, "video_%u");
1214 caps = gst_matroska_demux_video_caps (videocontext,
1215 context->codec_id, context->codec_priv,
1216 context->codec_priv_size, &codec, &riff_fourcc);
1219 list = gst_tag_list_new (GST_TAG_VIDEO_CODEC, codec, NULL);
1225 case GST_MATROSKA_TRACK_TYPE_AUDIO:{
1226 GstMatroskaTrackAudioContext *audiocontext =
1227 (GstMatroskaTrackAudioContext *) context;
1229 padname = g_strdup_printf ("audio_%u", demux->num_a_streams++);
1230 templ = gst_element_class_get_pad_template (klass, "audio_%u");
1231 caps = gst_matroska_demux_audio_caps (audiocontext,
1232 context->codec_id, context->codec_priv, context->codec_priv_size,
1233 &codec, &riff_audio_fmt);
1236 list = gst_tag_list_new (GST_TAG_AUDIO_CODEC, codec, NULL);
1242 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:{
1243 GstMatroskaTrackSubtitleContext *subtitlecontext =
1244 (GstMatroskaTrackSubtitleContext *) context;
1246 padname = g_strdup_printf ("subtitle_%u", demux->num_t_streams++);
1247 templ = gst_element_class_get_pad_template (klass, "subtitle_%u");
1248 caps = gst_matroska_demux_subtitle_caps (subtitlecontext,
1249 context->codec_id, context->codec_priv, context->codec_priv_size);
1253 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1254 case GST_MATROSKA_TRACK_TYPE_LOGO:
1255 case GST_MATROSKA_TRACK_TYPE_BUTTONS:
1256 case GST_MATROSKA_TRACK_TYPE_CONTROL:
1258 /* we should already have quit by now */
1259 g_assert_not_reached ();
1262 if ((context->language == NULL || *context->language == '\0') &&
1263 (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO ||
1264 context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
1265 GST_LOG ("stream %d: language=eng (assuming default)", context->index);
1266 context->language = g_strdup ("eng");
1269 if (context->language) {
1273 list = gst_tag_list_new_empty ();
1275 /* Matroska contains ISO 639-2B codes, we want ISO 639-1 */
1276 lang = gst_tag_get_language_code (context->language);
1277 gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
1278 GST_TAG_LANGUAGE_CODE, (lang) ? lang : context->language, NULL);
1282 GST_WARNING_OBJECT (demux, "could not determine caps for stream with "
1283 "codec_id='%s'", context->codec_id);
1284 switch (context->type) {
1285 case GST_MATROSKA_TRACK_TYPE_VIDEO:
1286 caps = gst_caps_new_empty_simple ("video/x-unknown");
1288 case GST_MATROSKA_TRACK_TYPE_AUDIO:
1289 caps = gst_caps_new_empty_simple ("audio/x-unknown");
1291 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
1292 caps = gst_caps_new_empty_simple ("application/x-subtitle-unknown");
1294 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1296 caps = gst_caps_new_empty_simple ("application/x-matroska-unknown");
1299 gst_caps_set_simple (caps, "codec-id", G_TYPE_STRING, context->codec_id,
1302 /* add any unrecognised riff fourcc / audio format, but after codec-id */
1303 if (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO && riff_audio_fmt != 0)
1304 gst_caps_set_simple (caps, "format", G_TYPE_INT, riff_audio_fmt, NULL);
1305 else if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO && riff_fourcc != 0) {
1306 gchar *fstr = g_strdup_printf ("%" GST_FOURCC_FORMAT,
1307 GST_FOURCC_ARGS (riff_fourcc));
1308 gst_caps_set_simple (caps, "fourcc", G_TYPE_STRING, fstr, NULL);
1313 /* the pad in here */
1314 context->pad = gst_pad_new_from_template (templ, padname);
1315 context->caps = caps;
1317 gst_pad_set_event_function (context->pad,
1318 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_event));
1319 gst_pad_set_query_function (context->pad,
1320 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_query));
1322 GST_INFO_OBJECT (demux, "Adding pad '%s' with caps %" GST_PTR_FORMAT,
1325 context->pending_tags = list;
1327 gst_pad_set_element_private (context->pad, context);
1329 gst_pad_use_fixed_caps (context->pad);
1330 gst_pad_set_active (context->pad, TRUE);
1331 gst_pad_set_caps (context->pad, context->caps);
1332 gst_element_add_pad (GST_ELEMENT (demux), context->pad);
1341 gst_matroska_demux_query (GstMatroskaDemux * demux, GstPad * pad,
1344 gboolean res = FALSE;
1345 GstMatroskaTrackContext *context = NULL;
1348 context = gst_pad_get_element_private (pad);
1351 switch (GST_QUERY_TYPE (query)) {
1352 case GST_QUERY_POSITION:
1356 gst_query_parse_position (query, &format, NULL);
1358 if (format == GST_FORMAT_TIME) {
1359 GST_OBJECT_LOCK (demux);
1361 gst_query_set_position (query, GST_FORMAT_TIME,
1362 MAX (context->pos, demux->stream_start_time) -
1363 demux->stream_start_time);
1365 gst_query_set_position (query, GST_FORMAT_TIME,
1366 MAX (demux->common.segment.position, demux->stream_start_time) -
1367 demux->stream_start_time);
1368 GST_OBJECT_UNLOCK (demux);
1369 } else if (format == GST_FORMAT_DEFAULT && context
1370 && context->default_duration) {
1371 GST_OBJECT_LOCK (demux);
1372 gst_query_set_position (query, GST_FORMAT_DEFAULT,
1373 context->pos / context->default_duration);
1374 GST_OBJECT_UNLOCK (demux);
1376 GST_DEBUG_OBJECT (demux,
1377 "only position query in TIME and DEFAULT format is supported");
1383 case GST_QUERY_DURATION:
1387 gst_query_parse_duration (query, &format, NULL);
1389 if (format == GST_FORMAT_TIME) {
1390 GST_OBJECT_LOCK (demux);
1391 gst_query_set_duration (query, GST_FORMAT_TIME,
1392 demux->common.segment.duration);
1393 GST_OBJECT_UNLOCK (demux);
1394 } else if (format == GST_FORMAT_DEFAULT && context
1395 && context->default_duration) {
1396 GST_OBJECT_LOCK (demux);
1397 gst_query_set_duration (query, GST_FORMAT_DEFAULT,
1398 demux->common.segment.duration / context->default_duration);
1399 GST_OBJECT_UNLOCK (demux);
1401 GST_DEBUG_OBJECT (demux,
1402 "only duration query in TIME and DEFAULT format is supported");
1409 case GST_QUERY_SEEKING:
1413 gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
1414 GST_OBJECT_LOCK (demux);
1415 if (fmt == GST_FORMAT_TIME) {
1418 if (demux->streaming) {
1419 /* assuming we'll be able to get an index ... */
1420 seekable = demux->seekable;
1425 gst_query_set_seeking (query, GST_FORMAT_TIME, seekable,
1426 0, demux->common.segment.duration);
1429 GST_OBJECT_UNLOCK (demux);
1437 GST_OBJECT_LOCK (demux);
1438 if (demux->common.toc)
1439 toc = demux->common.toc;
1441 toc = gst_toc_new ();
1442 gst_query_set_toc (query, toc, 0);
1444 if (!demux->common.toc)
1446 GST_OBJECT_UNLOCK (demux);
1450 res = gst_pad_query_default (pad, (GstObject *) demux, query);
1458 gst_matroska_demux_element_query (GstElement * element, GstQuery * query)
1460 return gst_matroska_demux_query (GST_MATROSKA_DEMUX (element), NULL, query);
1464 gst_matroska_demux_handle_src_query (GstPad * pad, GstObject * parent,
1467 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
1469 return gst_matroska_demux_query (demux, pad, query);
1472 /* returns FALSE if there are no pads to deliver event to,
1473 * otherwise TRUE (whatever the outcome of event sending),
1474 * takes ownership of the passed event! */
1476 gst_matroska_demux_send_event (GstMatroskaDemux * demux, GstEvent * event)
1478 gboolean is_segment;
1479 gboolean ret = FALSE;
1482 g_return_val_if_fail (event != NULL, FALSE);
1484 GST_DEBUG_OBJECT (demux, "Sending event of type %s to all source pads",
1485 GST_EVENT_TYPE_NAME (event));
1487 is_segment = (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT);
1489 g_assert (demux->common.src->len == demux->common.num_streams);
1490 for (i = 0; i < demux->common.src->len; i++) {
1491 GstMatroskaTrackContext *stream;
1493 stream = g_ptr_array_index (demux->common.src, i);
1494 gst_event_ref (event);
1495 gst_pad_push_event (stream->pad, event);
1498 /* FIXME: send global tags before stream tags */
1499 if (G_UNLIKELY (is_segment && stream->pending_tags != NULL)) {
1500 GST_DEBUG_OBJECT (demux, "Sending pending_tags %p for pad %s:%s : %"
1501 GST_PTR_FORMAT, stream->pending_tags,
1502 GST_DEBUG_PAD_NAME (stream->pad), stream->pending_tags);
1503 gst_pad_push_event (stream->pad,
1504 gst_event_new_tag (stream->pending_tags));
1505 stream->pending_tags = NULL;
1509 if (G_UNLIKELY (is_segment && demux->common.global_tags != NULL)) {
1510 GstEvent *tag_event;
1511 gst_tag_list_add (demux->common.global_tags, GST_TAG_MERGE_REPLACE,
1512 GST_TAG_CONTAINER_FORMAT, "Matroska", NULL);
1513 GST_DEBUG_OBJECT (demux, "Sending global_tags %p : %" GST_PTR_FORMAT,
1514 demux->common.global_tags, demux->common.global_tags);
1516 tag_event = gst_event_new_tag (demux->common.global_tags);
1518 for (i = 0; i < demux->common.src->len; i++) {
1519 GstMatroskaTrackContext *stream;
1521 stream = g_ptr_array_index (demux->common.src, i);
1522 gst_pad_push_event (stream->pad, gst_event_ref (tag_event));
1525 gst_event_unref (tag_event);
1526 demux->common.global_tags = NULL;
1529 gst_event_unref (event);
1534 gst_matroska_demux_element_send_event (GstElement * element, GstEvent * event)
1536 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
1539 g_return_val_if_fail (event != NULL, FALSE);
1541 if (GST_EVENT_TYPE (event) == GST_EVENT_SEEK) {
1542 res = gst_matroska_demux_handle_seek_event (demux, NULL, event);
1544 GST_WARNING_OBJECT (demux, "Unhandled event of type %s",
1545 GST_EVENT_TYPE_NAME (event));
1548 gst_event_unref (event);
1553 gst_matroska_demux_move_to_entry (GstMatroskaDemux * demux,
1554 GstMatroskaIndex * entry, gboolean reset)
1558 GST_OBJECT_LOCK (demux);
1560 /* seek (relative to matroska segment) */
1561 /* position might be invalid; will error when streaming resumes ... */
1562 demux->common.offset = entry->pos + demux->common.ebml_segment_start;
1564 GST_DEBUG_OBJECT (demux, "Seeked to offset %" G_GUINT64_FORMAT ", block %d, "
1565 "time %" GST_TIME_FORMAT, entry->pos + demux->common.ebml_segment_start,
1566 entry->block, GST_TIME_ARGS (entry->time));
1568 /* update the time */
1569 gst_matroska_read_common_reset_streams (&demux->common, entry->time, TRUE);
1570 demux->common.segment.position = entry->time;
1571 demux->seek_block = entry->block;
1572 demux->seek_first = TRUE;
1573 demux->last_stop_end = GST_CLOCK_TIME_NONE;
1575 for (i = 0; i < demux->common.src->len; i++) {
1576 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
1579 stream->to_offset = G_MAXINT64;
1581 if (stream->from_offset != -1)
1582 stream->to_offset = stream->from_offset;
1584 stream->from_offset = -1;
1587 GST_OBJECT_UNLOCK (demux);
1593 gst_matroska_cluster_compare (gint64 * i1, gint64 * i2)
1603 /* searches for a cluster start from @pos,
1604 * return GST_FLOW_OK and cluster position in @pos if found */
1605 static GstFlowReturn
1606 gst_matroska_demux_search_cluster (GstMatroskaDemux * demux, gint64 * pos)
1608 gint64 newpos = *pos;
1610 GstFlowReturn ret = GST_FLOW_OK;
1611 const guint chunk = 64 * 1024;
1612 GstBuffer *buf = NULL;
1614 gpointer data = NULL;
1620 orig_offset = demux->common.offset;
1622 GST_LOG_OBJECT (demux, "searching cluster following offset %" G_GINT64_FORMAT,
1625 if (demux->clusters) {
1628 cpos = gst_util_array_binary_search (demux->clusters->data,
1629 demux->clusters->len, sizeof (gint64),
1630 (GCompareDataFunc) gst_matroska_cluster_compare,
1631 GST_SEARCH_MODE_AFTER, pos, NULL);
1634 GST_DEBUG_OBJECT (demux,
1635 "cluster reported at offset %" G_GINT64_FORMAT, *cpos);
1636 demux->common.offset = *cpos;
1637 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1638 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1639 if (ret == GST_FLOW_OK && id == GST_MATROSKA_ID_CLUSTER) {
1646 /* read in at newpos and scan for ebml cluster id */
1648 GstByteReader reader;
1652 gst_buffer_unmap (buf, &map);
1653 gst_buffer_unref (buf);
1656 ret = gst_pad_pull_range (demux->common.sinkpad, newpos, chunk, &buf);
1657 if (ret != GST_FLOW_OK)
1659 GST_DEBUG_OBJECT (demux,
1660 "read buffer size %" G_GSIZE_FORMAT " at offset %" G_GINT64_FORMAT,
1661 gst_buffer_get_size (buf), newpos);
1662 gst_buffer_map (buf, &map, GST_MAP_READ);
1665 gst_byte_reader_init (&reader, data, size);
1667 cluster_pos = gst_byte_reader_masked_scan_uint32 (&reader, 0xffffffff,
1668 GST_MATROSKA_ID_CLUSTER, 0, gst_byte_reader_get_remaining (&reader));
1669 if (cluster_pos >= 0) {
1670 newpos += cluster_pos;
1671 /* prepare resuming at next byte */
1672 if (!gst_byte_reader_skip (&reader, cluster_pos + 1)) {
1673 GST_DEBUG_OBJECT (demux, "Need more data -> continue");
1676 GST_DEBUG_OBJECT (demux,
1677 "found cluster ebml id at offset %" G_GINT64_FORMAT, newpos);
1678 /* extra checks whether we really sync'ed to a cluster:
1679 * - either it is the first and only cluster
1680 * - either there is a cluster after this one
1681 * - either cluster length is undefined
1683 /* ok if first cluster (there may not a subsequent one) */
1684 if (newpos == demux->first_cluster_offset) {
1685 GST_DEBUG_OBJECT (demux, "cluster is first cluster -> OK");
1688 demux->common.offset = newpos;
1689 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1690 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1691 if (ret != GST_FLOW_OK) {
1692 GST_DEBUG_OBJECT (demux, "need more data -> continue");
1695 g_assert (id == GST_MATROSKA_ID_CLUSTER);
1696 GST_DEBUG_OBJECT (demux, "cluster size %" G_GUINT64_FORMAT ", prefix %d",
1698 /* ok if undefined length or first cluster */
1699 if (length == GST_EBML_SIZE_UNKNOWN || length == G_MAXUINT64) {
1700 GST_DEBUG_OBJECT (demux, "cluster has undefined length -> OK");
1704 demux->common.offset += length + needed;
1705 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1706 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1707 if (ret != GST_FLOW_OK)
1709 GST_DEBUG_OBJECT (demux, "next element is %scluster",
1710 id == GST_MATROSKA_ID_CLUSTER ? "" : "not ");
1711 if (id == GST_MATROSKA_ID_CLUSTER)
1713 /* not ok, resume */
1716 /* partial cluster id may have been in tail of buffer */
1717 newpos += MAX (gst_byte_reader_get_remaining (&reader), 4) - 3;
1722 gst_buffer_unmap (buf, &map);
1723 gst_buffer_unref (buf);
1728 demux->common.offset = orig_offset;
1733 /* bisect and scan through file for cluster starting before @time,
1734 * returns fake index entry with corresponding info on cluster */
1735 static GstMatroskaIndex *
1736 gst_matroska_demux_search_pos (GstMatroskaDemux * demux, GstClockTime time)
1738 GstMatroskaIndex *entry = NULL;
1739 GstMatroskaReadState current_state;
1740 GstClockTime otime, prev_cluster_time, current_cluster_time, cluster_time;
1741 gint64 opos, newpos, startpos = 0, current_offset;
1742 gint64 prev_cluster_offset = -1, current_cluster_offset, cluster_offset;
1743 const guint chunk = 64 * 1024;
1749 /* (under)estimate new position, resync using cluster ebml id,
1750 * and scan forward to appropriate cluster
1751 * (and re-estimate if need to go backward) */
1753 prev_cluster_time = GST_CLOCK_TIME_NONE;
1755 /* store some current state */
1756 current_state = demux->common.state;
1757 g_return_val_if_fail (current_state == GST_MATROSKA_READ_STATE_DATA, NULL);
1759 current_cluster_offset = demux->cluster_offset;
1760 current_cluster_time = demux->cluster_time;
1761 current_offset = demux->common.offset;
1763 demux->common.state = GST_MATROSKA_READ_STATE_SCANNING;
1765 /* estimate using start and current position */
1766 GST_OBJECT_LOCK (demux);
1767 opos = demux->common.offset - demux->common.ebml_segment_start;
1768 otime = demux->common.segment.position;
1769 GST_OBJECT_UNLOCK (demux);
1772 time = MAX (time, demux->stream_start_time);
1774 /* avoid division by zero in first estimation below */
1775 if (otime <= demux->stream_start_time)
1779 GST_LOG_OBJECT (demux,
1780 "opos: %" G_GUINT64_FORMAT ", otime: %" GST_TIME_FORMAT ", %"
1781 GST_TIME_FORMAT " in stream time (start %" GST_TIME_FORMAT "), time %"
1782 GST_TIME_FORMAT, opos, GST_TIME_ARGS (otime),
1783 GST_TIME_ARGS (otime - demux->stream_start_time),
1784 GST_TIME_ARGS (demux->stream_start_time), GST_TIME_ARGS (time));
1786 gst_util_uint64_scale (opos - demux->common.ebml_segment_start,
1787 time - demux->stream_start_time,
1788 otime - demux->stream_start_time) - chunk;
1791 /* favour undershoot */
1792 newpos = newpos * 90 / 100;
1793 newpos += demux->common.ebml_segment_start;
1795 GST_DEBUG_OBJECT (demux,
1796 "estimated offset for %" GST_TIME_FORMAT ": %" G_GINT64_FORMAT,
1797 GST_TIME_ARGS (time), newpos);
1799 /* and at least start scanning before previous scan start to avoid looping */
1800 startpos = startpos * 90 / 100;
1801 if (startpos && startpos < newpos)
1804 /* read in at newpos and scan for ebml cluster id */
1808 ret = gst_matroska_demux_search_cluster (demux, &newpos);
1809 if (ret == GST_FLOW_EOS) {
1810 /* heuristic HACK */
1811 newpos = startpos * 80 / 100;
1812 GST_DEBUG_OBJECT (demux, "EOS; "
1813 "new estimated offset for %" GST_TIME_FORMAT ": %" G_GINT64_FORMAT,
1814 GST_TIME_ARGS (time), newpos);
1817 } else if (ret != GST_FLOW_OK) {
1824 /* then start scanning and parsing for cluster time,
1825 * re-estimate if overshoot, otherwise next cluster and so on */
1826 demux->common.offset = newpos;
1827 demux->cluster_time = cluster_time = GST_CLOCK_TIME_NONE;
1829 guint64 cluster_size = 0;
1831 /* peek and parse some elements */
1832 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1833 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1834 if (ret != GST_FLOW_OK)
1836 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
1837 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
1839 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
1840 if (ret != GST_FLOW_OK)
1843 if (id == GST_MATROSKA_ID_CLUSTER) {
1844 cluster_time = GST_CLOCK_TIME_NONE;
1845 if (length == G_MAXUINT64)
1848 cluster_size = length + needed;
1850 if (demux->cluster_time != GST_CLOCK_TIME_NONE &&
1851 cluster_time == GST_CLOCK_TIME_NONE) {
1852 cluster_time = demux->cluster_time * demux->common.time_scale;
1853 cluster_offset = demux->cluster_offset;
1854 GST_DEBUG_OBJECT (demux, "found cluster at offset %" G_GINT64_FORMAT
1855 " with time %" GST_TIME_FORMAT, cluster_offset,
1856 GST_TIME_ARGS (cluster_time));
1857 if (cluster_time > time) {
1858 GST_DEBUG_OBJECT (demux, "overshot target");
1859 /* cluster overshoots */
1860 if (cluster_offset == demux->first_cluster_offset) {
1861 /* but no prev one */
1862 GST_DEBUG_OBJECT (demux, "but using first cluster anyway");
1863 prev_cluster_time = cluster_time;
1864 prev_cluster_offset = cluster_offset;
1867 if (prev_cluster_time != GST_CLOCK_TIME_NONE) {
1868 /* prev cluster did not overshoot, so prev cluster is target */
1871 /* re-estimate using this new position info */
1872 opos = cluster_offset;
1873 otime = cluster_time;
1877 /* cluster undershoots, goto next one */
1878 prev_cluster_time = cluster_time;
1879 prev_cluster_offset = cluster_offset;
1880 /* skip cluster if length is defined,
1881 * otherwise will be skippingly parsed into */
1883 GST_DEBUG_OBJECT (demux, "skipping to next cluster");
1884 demux->common.offset = cluster_offset + cluster_size;
1885 demux->cluster_time = GST_CLOCK_TIME_NONE;
1887 GST_DEBUG_OBJECT (demux, "parsing/skipping cluster elements");
1894 if (ret == GST_FLOW_EOS) {
1895 if (prev_cluster_time != GST_CLOCK_TIME_NONE)
1901 entry = g_new0 (GstMatroskaIndex, 1);
1902 entry->time = prev_cluster_time;
1903 entry->pos = prev_cluster_offset - demux->common.ebml_segment_start;
1904 GST_DEBUG_OBJECT (demux, "simulated index entry; time %" GST_TIME_FORMAT
1905 ", pos %" G_GUINT64_FORMAT, GST_TIME_ARGS (entry->time), entry->pos);
1909 /* restore some state */
1910 demux->cluster_offset = current_cluster_offset;
1911 demux->cluster_time = current_cluster_time;
1912 demux->common.offset = current_offset;
1913 demux->common.state = current_state;
1919 gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
1920 GstPad * pad, GstEvent * event)
1922 GstMatroskaIndex *entry = NULL;
1923 GstMatroskaIndex scan_entry;
1925 GstSeekType cur_type, stop_type;
1927 gboolean flush, keyunit;
1930 GstMatroskaTrackContext *track = NULL;
1931 GstSegment seeksegment = { 0, };
1932 gboolean update = TRUE;
1933 gboolean pad_locked = FALSE;
1936 track = gst_pad_get_element_private (pad);
1938 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
1941 /* we can only seek on time */
1942 if (format != GST_FORMAT_TIME) {
1943 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
1947 /* copy segment, we need this because we still need the old
1948 * segment when we close the current segment. */
1949 memcpy (&seeksegment, &demux->common.segment, sizeof (GstSegment));
1951 /* pull mode without index means that the actual duration is not known,
1952 * we might be playing a file that's still being recorded
1953 * so, invalidate our current duration, which is only a moving target,
1954 * and should not be used to clamp anything */
1955 if (!demux->streaming && !demux->common.index && demux->invalid_duration) {
1956 seeksegment.duration = GST_CLOCK_TIME_NONE;
1960 GST_DEBUG_OBJECT (demux, "configuring seek");
1961 gst_segment_do_seek (&seeksegment, rate, format, flags,
1962 cur_type, cur, stop_type, stop, &update);
1963 /* compensate for clip start time */
1964 if (GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
1965 seeksegment.position += demux->stream_start_time;
1966 seeksegment.start += demux->stream_start_time;
1967 if (GST_CLOCK_TIME_IS_VALID (seeksegment.stop))
1968 seeksegment.stop += demux->stream_start_time;
1969 /* note that time should stay at indicated position */
1973 /* restore segment duration (if any effect),
1974 * would be determined again when parsing, but anyway ... */
1975 seeksegment.duration = demux->common.segment.duration;
1977 flush = ! !(flags & GST_SEEK_FLAG_FLUSH);
1978 keyunit = ! !(flags & GST_SEEK_FLAG_KEY_UNIT);
1980 GST_DEBUG_OBJECT (demux, "New segment %" GST_SEGMENT_FORMAT, &seeksegment);
1983 /* only have to update some segment,
1984 * but also still have to honour flush and so on */
1985 GST_DEBUG_OBJECT (demux, "... no update");
1986 /* bad goto, bad ... */
1990 /* check sanity before we start flushing and all that */
1991 GST_OBJECT_LOCK (demux);
1992 track = gst_matroska_read_common_get_seek_track (&demux->common, track);
1993 if ((entry = gst_matroska_read_common_do_index_seek (&demux->common, track,
1994 seeksegment.position, &demux->seek_index, &demux->seek_entry)) ==
1996 /* pull mode without index can scan later on */
1997 if (demux->streaming) {
1998 GST_DEBUG_OBJECT (demux, "No matching seek entry in index");
1999 GST_OBJECT_UNLOCK (demux);
2003 GST_DEBUG_OBJECT (demux, "Seek position looks sane");
2004 GST_OBJECT_UNLOCK (demux);
2006 if (demux->streaming) {
2007 /* need to seek to cluster start to pick up cluster time */
2008 /* upstream takes care of flushing and all that
2009 * ... and segment event handling takes care of the rest */
2010 return perform_seek_to_offset (demux,
2011 entry->pos + demux->common.ebml_segment_start);
2016 GST_DEBUG_OBJECT (demux, "Starting flush");
2017 gst_pad_push_event (demux->common.sinkpad, gst_event_new_flush_start ());
2018 gst_matroska_demux_send_event (demux, gst_event_new_flush_start ());
2020 GST_DEBUG_OBJECT (demux, "Non-flushing seek, pausing task");
2021 gst_pad_pause_task (demux->common.sinkpad);
2027 /* now grab the stream lock so that streaming cannot continue, for
2028 * non flushing seeks when the element is in PAUSED this could block
2030 GST_DEBUG_OBJECT (demux, "Waiting for streaming to stop");
2031 GST_PAD_STREAM_LOCK (demux->common.sinkpad);
2034 /* pull mode without index can do some scanning */
2035 if (!demux->streaming && !entry) {
2036 /* need to stop flushing upstream as we need it next */
2038 gst_pad_push_event (demux->common.sinkpad,
2039 gst_event_new_flush_stop (TRUE));
2040 entry = gst_matroska_demux_search_pos (demux, seeksegment.position);
2041 /* keep local copy */
2043 scan_entry = *entry;
2045 entry = &scan_entry;
2047 GST_DEBUG_OBJECT (demux, "Scan failed to find matching position");
2049 gst_matroska_demux_send_event (demux, gst_event_new_flush_stop (TRUE));
2055 GST_DEBUG_OBJECT (demux, "seek to key unit, adjusting segment start to %"
2056 GST_TIME_FORMAT, GST_TIME_ARGS (entry->time));
2057 seeksegment.start = MAX (entry->time, demux->stream_start_time);
2058 seeksegment.position = seeksegment.start;
2059 seeksegment.time = seeksegment.start - demux->stream_start_time;
2064 GST_DEBUG_OBJECT (demux, "Stopping flush");
2065 gst_pad_push_event (demux->common.sinkpad, gst_event_new_flush_stop (TRUE));
2066 gst_matroska_demux_send_event (demux, gst_event_new_flush_stop (TRUE));
2069 GST_OBJECT_LOCK (demux);
2070 /* now update the real segment info */
2071 GST_DEBUG_OBJECT (demux, "Committing new seek segment");
2072 memcpy (&demux->common.segment, &seeksegment, sizeof (GstSegment));
2073 GST_OBJECT_UNLOCK (demux);
2075 /* update some (segment) state */
2076 if (update && !gst_matroska_demux_move_to_entry (demux, entry, TRUE))
2079 /* notify start of new segment */
2080 if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
2083 msg = gst_message_new_segment_start (GST_OBJECT (demux),
2084 GST_FORMAT_TIME, demux->common.segment.start);
2085 gst_element_post_message (GST_ELEMENT (demux), msg);
2088 GST_OBJECT_LOCK (demux);
2089 if (demux->new_segment)
2090 gst_event_unref (demux->new_segment);
2091 /* On port from 0.10, discarded !update (for segment.update) here, FIXME? */
2092 demux->new_segment = gst_event_new_segment (&demux->common.segment);
2093 GST_OBJECT_UNLOCK (demux);
2095 /* restart our task since it might have been stopped when we did the
2097 gst_pad_start_task (demux->common.sinkpad,
2098 (GstTaskFunction) gst_matroska_demux_loop, demux->common.sinkpad);
2100 /* streaming can continue now */
2102 GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
2110 GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
2112 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Got a seek error"));
2118 * Handle whether we can perform the seek event or if we have to let the chain
2119 * function handle seeks to build the seek indexes first.
2122 gst_matroska_demux_handle_seek_push (GstMatroskaDemux * demux, GstPad * pad,
2126 GstSeekType cur_type, stop_type;
2131 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
2136 /* we can only seek on time */
2137 if (format != GST_FORMAT_TIME) {
2138 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
2142 if (stop_type != GST_SEEK_TYPE_NONE && stop != GST_CLOCK_TIME_NONE) {
2143 GST_DEBUG_OBJECT (demux, "Seek end-time not supported in streaming mode");
2147 if (!(flags & GST_SEEK_FLAG_FLUSH)) {
2148 GST_DEBUG_OBJECT (demux,
2149 "Non-flushing seek not supported in streaming mode");
2153 if (flags & GST_SEEK_FLAG_SEGMENT) {
2154 GST_DEBUG_OBJECT (demux, "Segment seek not supported in streaming mode");
2158 /* check for having parsed index already */
2159 if (!demux->common.index_parsed) {
2160 gboolean building_index;
2163 if (!demux->index_offset) {
2164 GST_DEBUG_OBJECT (demux, "no index (location); no seek in push mode");
2168 GST_OBJECT_LOCK (demux);
2169 /* handle the seek event in the chain function */
2170 demux->common.state = GST_MATROSKA_READ_STATE_SEEK;
2171 /* no more seek can be issued until state reset to _DATA */
2173 /* copy the event */
2174 if (demux->seek_event)
2175 gst_event_unref (demux->seek_event);
2176 demux->seek_event = gst_event_ref (event);
2178 /* set the building_index flag so that only one thread can setup the
2179 * structures for index seeking. */
2180 building_index = demux->building_index;
2181 if (!building_index) {
2182 demux->building_index = TRUE;
2183 offset = demux->index_offset;
2185 GST_OBJECT_UNLOCK (demux);
2187 if (!building_index) {
2188 /* seek to the first subindex or legacy index */
2189 GST_INFO_OBJECT (demux, "Seeking to Cues at %" G_GUINT64_FORMAT, offset);
2190 return perform_seek_to_offset (demux, offset);
2193 /* well, we are handling it already */
2197 /* delegate to tweaked regular seek */
2198 return gst_matroska_demux_handle_seek_event (demux, pad, event);
2202 gst_matroska_demux_handle_src_event (GstPad * pad, GstObject * parent,
2205 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
2206 gboolean res = TRUE;
2208 switch (GST_EVENT_TYPE (event)) {
2209 case GST_EVENT_SEEK:
2210 /* no seeking until we are (safely) ready */
2211 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
2212 GST_DEBUG_OBJECT (demux, "not ready for seeking yet");
2215 if (!demux->streaming)
2216 res = gst_matroska_demux_handle_seek_event (demux, pad, event);
2218 res = gst_matroska_demux_handle_seek_push (demux, pad, event);
2219 gst_event_unref (event);
2224 GstMatroskaTrackContext *context = gst_pad_get_element_private (pad);
2225 if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
2226 GstMatroskaTrackVideoContext *videocontext =
2227 (GstMatroskaTrackVideoContext *) context;
2229 GstClockTimeDiff diff;
2230 GstClockTime timestamp;
2232 gst_event_parse_qos (event, NULL, &proportion, &diff, ×tamp);
2234 GST_OBJECT_LOCK (demux);
2235 videocontext->earliest_time = timestamp + diff;
2236 GST_OBJECT_UNLOCK (demux);
2239 gst_event_unref (event);
2243 case GST_EVENT_TOC_SELECT:
2246 GstTocEntry *entry = NULL;
2247 GstEvent *seek_event;
2250 if (!demux->common.toc) {
2251 GST_DEBUG_OBJECT (demux, "no TOC to select");
2254 gst_event_parse_toc_select (event, &uid);
2256 GST_OBJECT_LOCK (demux);
2257 entry = gst_toc_find_entry (demux->common.toc, uid);
2258 if (entry == NULL) {
2259 GST_OBJECT_UNLOCK (demux);
2260 GST_WARNING_OBJECT (demux, "no TOC entry with given UID: %s", uid);
2263 gst_toc_entry_get_start_stop (entry, &start_pos, NULL);
2264 GST_OBJECT_UNLOCK (demux);
2265 seek_event = gst_event_new_seek (1.0,
2267 GST_SEEK_FLAG_FLUSH,
2268 GST_SEEK_TYPE_SET, start_pos, GST_SEEK_TYPE_SET, -1);
2269 res = gst_matroska_demux_handle_seek_event (demux, pad, seek_event);
2270 gst_event_unref (seek_event);
2274 GST_WARNING_OBJECT (demux, "received empty TOC select event");
2278 gst_event_unref (event);
2282 /* events we don't need to handle */
2283 case GST_EVENT_NAVIGATION:
2284 gst_event_unref (event);
2288 case GST_EVENT_LATENCY:
2290 res = gst_pad_push_event (demux->common.sinkpad, event);
2297 static GstFlowReturn
2298 gst_matroska_demux_seek_to_previous_keyframe (GstMatroskaDemux * demux)
2300 GstFlowReturn ret = GST_FLOW_EOS;
2301 gboolean done = TRUE;
2304 g_return_val_if_fail (demux->seek_index, GST_FLOW_EOS);
2305 g_return_val_if_fail (demux->seek_entry < demux->seek_index->len,
2308 GST_DEBUG_OBJECT (demux, "locating previous keyframe");
2310 if (!demux->seek_entry) {
2311 GST_DEBUG_OBJECT (demux, "no earlier index entry");
2315 for (i = 0; i < demux->common.src->len; i++) {
2316 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
2318 GST_DEBUG_OBJECT (demux, "segment start %" GST_TIME_FORMAT
2319 ", stream %d at %" GST_TIME_FORMAT,
2320 GST_TIME_ARGS (demux->common.segment.start), stream->index,
2321 GST_TIME_ARGS (stream->from_time));
2322 if (GST_CLOCK_TIME_IS_VALID (stream->from_time)) {
2323 if (stream->from_time > demux->common.segment.start) {
2324 GST_DEBUG_OBJECT (demux, "stream %d not finished yet", stream->index);
2328 /* nothing pushed for this stream;
2329 * likely seek entry did not start at keyframe, so all was skipped.
2330 * So we need an earlier entry */
2336 GstMatroskaIndex *entry;
2338 entry = &g_array_index (demux->seek_index, GstMatroskaIndex,
2339 --demux->seek_entry);
2340 if (!gst_matroska_demux_move_to_entry (demux, entry, FALSE))
2350 static GstFlowReturn
2351 gst_matroska_demux_parse_tracks (GstMatroskaDemux * demux, GstEbmlRead * ebml)
2353 GstFlowReturn ret = GST_FLOW_OK;
2356 DEBUG_ELEMENT_START (demux, ebml, "Tracks");
2358 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2359 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
2363 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
2364 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
2368 /* one track within the "all-tracks" header */
2369 case GST_MATROSKA_ID_TRACKENTRY:
2370 ret = gst_matroska_demux_add_stream (demux, ebml);
2374 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
2379 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
2381 demux->tracks_parsed = TRUE;
2387 * Read signed/unsigned "EBML" numbers.
2388 * Return: number of bytes processed.
2392 gst_matroska_ebmlnum_uint (guint8 * data, guint size, guint64 * num)
2394 gint len_mask = 0x80, read = 1, n = 1, num_ffs = 0;
2402 while (read <= 8 && !(total & len_mask)) {
2409 if ((total &= (len_mask - 1)) == len_mask - 1)
2414 if (data[n] == 0xff)
2416 total = (total << 8) | data[n];
2420 if (read == num_ffs && total != 0)
2429 gst_matroska_ebmlnum_sint (guint8 * data, guint size, gint64 * num)
2434 /* read as unsigned number first */
2435 if ((res = gst_matroska_ebmlnum_uint (data, size, &unum)) < 0)
2439 if (unum == G_MAXUINT64)
2442 *num = unum - ((1 << ((7 * res) - 1)) - 1);
2448 * Mostly used for subtitles. We add void filler data for each
2449 * lagging stream to make sure we don't deadlock.
2453 gst_matroska_demux_sync_streams (GstMatroskaDemux * demux)
2457 GST_OBJECT_LOCK (demux);
2459 GST_LOG_OBJECT (demux, "Sync to %" GST_TIME_FORMAT,
2460 GST_TIME_ARGS (demux->common.segment.position));
2462 g_assert (demux->common.num_streams == demux->common.src->len);
2463 for (stream_nr = 0; stream_nr < demux->common.src->len; stream_nr++) {
2464 GstMatroskaTrackContext *context;
2466 context = g_ptr_array_index (demux->common.src, stream_nr);
2468 GST_LOG_OBJECT (demux,
2469 "Checking for resync on stream %d (%" GST_TIME_FORMAT ")", stream_nr,
2470 GST_TIME_ARGS (context->pos));
2472 if (G_LIKELY (context->type != GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
2473 GST_LOG_OBJECT (demux, "Skipping sync on non-subtitle stream");
2477 /* does it lag? 0.5 seconds is a random threshold...
2478 * lag need only be considered if we have advanced into requested segment */
2479 if (GST_CLOCK_TIME_IS_VALID (context->pos) &&
2480 GST_CLOCK_TIME_IS_VALID (demux->common.segment.position) &&
2481 demux->common.segment.position > demux->common.segment.start &&
2482 context->pos + (GST_SECOND / 2) < demux->common.segment.position) {
2487 new_start = demux->common.segment.position - (GST_SECOND / 2);
2488 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop))
2489 new_start = MIN (new_start, demux->common.segment.stop);
2490 GST_DEBUG_OBJECT (demux,
2491 "Synchronizing stream %d with others by advancing time " "from %"
2492 GST_TIME_FORMAT " to %" GST_TIME_FORMAT, stream_nr,
2493 GST_TIME_ARGS (context->pos), GST_TIME_ARGS (new_start));
2495 context->pos = new_start;
2497 /* advance stream time */
2498 segment = demux->common.segment;
2499 segment.position = new_start;
2500 event = gst_event_new_segment (&segment);
2501 GST_OBJECT_UNLOCK (demux);
2502 gst_pad_push_event (context->pad, event);
2503 GST_OBJECT_LOCK (demux);
2507 GST_OBJECT_UNLOCK (demux);
2510 static GstFlowReturn
2511 gst_matroska_demux_push_hdr_buf (GstMatroskaDemux * demux,
2512 GstMatroskaTrackContext * stream, guint8 * data, guint len)
2514 GstFlowReturn ret, cret;
2515 GstBuffer *header_buf;
2517 header_buf = gst_buffer_new_wrapped (g_memdup (data, len), len);
2519 if (stream->set_discont) {
2520 GST_BUFFER_FLAG_SET (header_buf, GST_BUFFER_FLAG_DISCONT);
2521 stream->set_discont = FALSE;
2524 ret = gst_pad_push (stream->pad, header_buf);
2527 cret = gst_matroska_demux_combine_flows (demux, stream, ret);
2532 static GstFlowReturn
2533 gst_matroska_demux_push_flac_codec_priv_data (GstMatroskaDemux * demux,
2534 GstMatroskaTrackContext * stream)
2540 GST_LOG_OBJECT (demux, "priv data size = %" G_GSIZE_FORMAT,
2541 stream->codec_priv_size);
2543 pdata = (guint8 *) stream->codec_priv;
2545 /* need at least 'fLaC' marker + STREAMINFO metadata block */
2546 if (stream->codec_priv_size < ((4) + (4 + 34))) {
2547 GST_WARNING_OBJECT (demux, "not enough codec priv data for flac headers");
2548 return GST_FLOW_ERROR;
2551 if (memcmp (pdata, "fLaC", 4) != 0) {
2552 GST_WARNING_OBJECT (demux, "no flac marker at start of stream headers");
2553 return GST_FLOW_ERROR;
2556 ret = gst_matroska_demux_push_hdr_buf (demux, stream, pdata, 4);
2557 if (ret != GST_FLOW_OK)
2560 off = 4; /* skip fLaC marker */
2561 while (off < stream->codec_priv_size) {
2562 len = GST_READ_UINT8 (pdata + off + 1) << 16;
2563 len |= GST_READ_UINT8 (pdata + off + 2) << 8;
2564 len |= GST_READ_UINT8 (pdata + off + 3);
2566 GST_DEBUG_OBJECT (demux, "header packet: len=%u bytes, flags=0x%02x",
2567 len, (guint) pdata[off]);
2569 ret = gst_matroska_demux_push_hdr_buf (demux, stream, pdata + off, len + 4);
2570 if (ret != GST_FLOW_OK)
2578 static GstFlowReturn
2579 gst_matroska_demux_push_speex_codec_priv_data (GstMatroskaDemux * demux,
2580 GstMatroskaTrackContext * stream)
2583 guint8 *pdata = stream->codec_priv;
2585 GST_LOG_OBJECT (demux, "priv data size = %" G_GSIZE_FORMAT,
2586 stream->codec_priv_size);
2588 /* need at least 'fLaC' marker + STREAMINFO metadata block */
2589 if (stream->codec_priv_size < 80) {
2590 GST_WARNING_OBJECT (demux, "not enough codec priv data for speex headers");
2591 return GST_FLOW_ERROR;
2594 if (memcmp (pdata, "Speex ", 8) != 0) {
2595 GST_WARNING_OBJECT (demux, "no Speex marker at start of stream headers");
2596 return GST_FLOW_ERROR;
2599 ret = gst_matroska_demux_push_hdr_buf (demux, stream, pdata, 80);
2600 if (ret != GST_FLOW_OK)
2603 if (stream->codec_priv_size == 80)
2606 return gst_matroska_demux_push_hdr_buf (demux, stream, pdata + 80,
2607 stream->codec_priv_size - 80);
2610 static GstFlowReturn
2611 gst_matroska_demux_push_xiph_codec_priv_data (GstMatroskaDemux * demux,
2612 GstMatroskaTrackContext * stream)
2615 guint8 *p = stream->codec_priv;
2616 gint i, offset, num_packets;
2617 guint *length, last;
2619 if (stream->codec_priv == NULL || stream->codec_priv_size == 0) {
2620 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
2621 ("Missing codec private data for xiph headers, broken file"));
2622 return GST_FLOW_ERROR;
2625 /* start of the stream and vorbis audio or theora video, need to
2626 * send the codec_priv data as first three packets */
2627 num_packets = p[0] + 1;
2628 GST_DEBUG_OBJECT (demux,
2629 "%u stream headers, total length=%" G_GSIZE_FORMAT " bytes",
2630 (guint) num_packets, stream->codec_priv_size);
2632 length = g_alloca (num_packets * sizeof (guint));
2636 /* first packets, read length values */
2637 for (i = 0; i < num_packets - 1; i++) {
2639 while (offset < stream->codec_priv_size) {
2640 length[i] += p[offset];
2641 if (p[offset++] != 0xff)
2646 if (offset + last > stream->codec_priv_size)
2647 return GST_FLOW_ERROR;
2649 /* last packet is the remaining size */
2650 length[i] = stream->codec_priv_size - offset - last;
2652 for (i = 0; i < num_packets; i++) {
2653 GST_DEBUG_OBJECT (demux, "buffer %d: length=%u bytes", i,
2655 if (offset + length[i] > stream->codec_priv_size)
2656 return GST_FLOW_ERROR;
2659 gst_matroska_demux_push_hdr_buf (demux, stream, p + offset, length[i]);
2660 if (ret != GST_FLOW_OK)
2663 offset += length[i];
2669 gst_matroska_demux_push_dvd_clut_change_event (GstMatroskaDemux * demux,
2670 GstMatroskaTrackContext * stream)
2674 g_assert (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB));
2676 if (!stream->codec_priv)
2679 /* ideally, VobSub private data should be parsed and stored more convenient
2680 * elsewhere, but for now, only interested in a small part */
2682 /* make sure we have terminating 0 */
2683 buf = g_strndup (stream->codec_priv, stream->codec_priv_size);
2685 /* just locate and parse palette part */
2686 start = strstr (buf, "palette:");
2691 guint8 r, g, b, y, u, v;
2694 while (g_ascii_isspace (*start))
2696 for (i = 0; i < 16; i++) {
2697 if (sscanf (start, "%06x", &col) != 1)
2700 while ((*start == ',') || g_ascii_isspace (*start))
2702 /* sigh, need to convert this from vobsub pseudo-RGB to YUV */
2703 r = (col >> 16) & 0xff;
2704 g = (col >> 8) & 0xff;
2706 y = CLAMP ((0.1494 * r + 0.6061 * g + 0.2445 * b) * 219 / 255 + 16, 0,
2708 u = CLAMP (0.6066 * r - 0.4322 * g - 0.1744 * b + 128, 0, 255);
2709 v = CLAMP (-0.08435 * r - 0.3422 * g + 0.4266 * b + 128, 0, 255);
2710 clut[i] = (y << 16) | (u << 8) | v;
2713 /* got them all without problems; build and send event */
2717 s = gst_structure_new ("application/x-gst-dvd", "event", G_TYPE_STRING,
2718 "dvd-spu-clut-change", "clut00", G_TYPE_INT, clut[0], "clut01",
2719 G_TYPE_INT, clut[1], "clut02", G_TYPE_INT, clut[2], "clut03",
2720 G_TYPE_INT, clut[3], "clut04", G_TYPE_INT, clut[4], "clut05",
2721 G_TYPE_INT, clut[5], "clut06", G_TYPE_INT, clut[6], "clut07",
2722 G_TYPE_INT, clut[7], "clut08", G_TYPE_INT, clut[8], "clut09",
2723 G_TYPE_INT, clut[9], "clut10", G_TYPE_INT, clut[10], "clut11",
2724 G_TYPE_INT, clut[11], "clut12", G_TYPE_INT, clut[12], "clut13",
2725 G_TYPE_INT, clut[13], "clut14", G_TYPE_INT, clut[14], "clut15",
2726 G_TYPE_INT, clut[15], NULL);
2728 gst_pad_push_event (stream->pad,
2729 gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM, s));
2735 static GstFlowReturn
2736 gst_matroska_demux_add_mpeg_seq_header (GstElement * element,
2737 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2740 guint seq_header_len;
2741 guint32 header, tmp;
2743 if (stream->codec_state) {
2744 seq_header = stream->codec_state;
2745 seq_header_len = stream->codec_state_size;
2746 } else if (stream->codec_priv) {
2747 seq_header = stream->codec_priv;
2748 seq_header_len = stream->codec_priv_size;
2753 /* Sequence header only needed for keyframes */
2754 if (GST_BUFFER_FLAG_IS_SET (*buf, GST_BUFFER_FLAG_DELTA_UNIT))
2757 if (gst_buffer_get_size (*buf) < 4)
2760 gst_buffer_extract (*buf, 0, &tmp, sizeof (guint32));
2761 header = GUINT32_FROM_BE (tmp);
2763 /* Sequence start code, if not found prepend */
2764 if (header != 0x000001b3) {
2767 GST_DEBUG_OBJECT (element, "Prepending MPEG sequence header");
2769 newbuf = gst_buffer_new_wrapped (g_memdup (seq_header, seq_header_len),
2772 gst_buffer_copy_into (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
2773 GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_MEMORY, 0,
2774 gst_buffer_get_size (*buf));
2776 gst_buffer_unref (*buf);
2783 static GstFlowReturn
2784 gst_matroska_demux_add_wvpk_header (GstElement * element,
2785 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2787 GstMatroskaTrackAudioContext *audiocontext =
2788 (GstMatroskaTrackAudioContext *) stream;
2789 GstBuffer *newbuf = NULL;
2790 GstMapInfo map, outmap;
2791 guint8 *buf_data, *data;
2799 wvh.version = GST_READ_UINT16_LE (stream->codec_priv);
2802 wvh.total_samples = -1;
2803 wvh.block_index = audiocontext->wvpk_block_index;
2805 if (audiocontext->channels <= 2) {
2806 guint32 block_samples, tmp;
2807 gsize size = gst_buffer_get_size (*buf);
2809 gst_buffer_extract (*buf, 0, &tmp, sizeof (guint32));
2810 block_samples = GUINT32_FROM_LE (tmp);
2811 /* we need to reconstruct the header of the wavpack block */
2813 /* -20 because ck_size is the size of the wavpack block -8
2814 * and lace_size is the size of the wavpack block + 12
2815 * (the three guint32 of the header that already are in the buffer) */
2816 wvh.ck_size = size + sizeof (Wavpack4Header) - 20;
2818 /* block_samples, flags and crc are already in the buffer */
2819 newbuf = gst_buffer_new_allocate (NULL, sizeof (Wavpack4Header) - 12, NULL);
2821 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2827 GST_WRITE_UINT32_LE (data + 4, wvh.ck_size);
2828 GST_WRITE_UINT16_LE (data + 8, wvh.version);
2829 GST_WRITE_UINT8 (data + 10, wvh.track_no);
2830 GST_WRITE_UINT8 (data + 11, wvh.index_no);
2831 GST_WRITE_UINT32_LE (data + 12, wvh.total_samples);
2832 GST_WRITE_UINT32_LE (data + 16, wvh.block_index);
2834 /* Append data from buf: */
2835 gst_buffer_copy_into (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
2836 GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_MEMORY, 0, size);
2838 gst_buffer_unref (*buf);
2840 audiocontext->wvpk_block_index += block_samples;
2842 guint8 *outdata = NULL;
2844 gsize buf_size, size, out_size = 0;
2845 guint32 block_samples, flags, crc, blocksize;
2847 gst_buffer_map (*buf, &map, GST_MAP_READ);
2848 buf_data = map.data;
2849 buf_size = map.size;
2852 GST_ERROR_OBJECT (element, "Too small wavpack buffer");
2853 gst_buffer_unmap (*buf, &map);
2854 return GST_FLOW_ERROR;
2860 block_samples = GST_READ_UINT32_LE (data);
2865 flags = GST_READ_UINT32_LE (data);
2868 crc = GST_READ_UINT32_LE (data);
2871 blocksize = GST_READ_UINT32_LE (data);
2875 if (blocksize == 0 || size < blocksize)
2878 g_assert ((newbuf == NULL) == (outdata == NULL));
2880 if (newbuf == NULL) {
2881 out_size = sizeof (Wavpack4Header) + blocksize;
2882 newbuf = gst_buffer_new_allocate (NULL, out_size, NULL);
2884 gst_buffer_copy_into (newbuf, *buf,
2885 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS, 0, -1);
2888 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2889 outdata = outmap.data;
2891 gst_buffer_unmap (newbuf, &outmap);
2892 out_size += sizeof (Wavpack4Header) + blocksize;
2893 gst_buffer_set_size (newbuf, out_size);
2894 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2895 outdata = outmap.data;
2898 outdata[outpos] = 'w';
2899 outdata[outpos + 1] = 'v';
2900 outdata[outpos + 2] = 'p';
2901 outdata[outpos + 3] = 'k';
2904 GST_WRITE_UINT32_LE (outdata + outpos,
2905 blocksize + sizeof (Wavpack4Header) - 8);
2906 GST_WRITE_UINT16_LE (outdata + outpos + 4, wvh.version);
2907 GST_WRITE_UINT8 (outdata + outpos + 6, wvh.track_no);
2908 GST_WRITE_UINT8 (outdata + outpos + 7, wvh.index_no);
2909 GST_WRITE_UINT32_LE (outdata + outpos + 8, wvh.total_samples);
2910 GST_WRITE_UINT32_LE (outdata + outpos + 12, wvh.block_index);
2911 GST_WRITE_UINT32_LE (outdata + outpos + 16, block_samples);
2912 GST_WRITE_UINT32_LE (outdata + outpos + 20, flags);
2913 GST_WRITE_UINT32_LE (outdata + outpos + 24, crc);
2916 g_memmove (outdata + outpos, data, blocksize);
2917 outpos += blocksize;
2921 gst_buffer_unmap (*buf, &map);
2922 gst_buffer_unref (*buf);
2925 gst_buffer_unmap (newbuf, &outmap);
2928 audiocontext->wvpk_block_index += block_samples;
2934 /* @text must be null-terminated */
2936 gst_matroska_demux_subtitle_chunk_has_tag (GstElement * element,
2941 /* yes, this might all lead to false positives ... */
2942 tag = (gchar *) text;
2943 while ((tag = strchr (tag, '<'))) {
2945 if (*tag != '\0' && *(tag + 1) == '>') {
2946 /* some common convenience ones */
2947 /* maybe any character will do here ? */
2960 if (strstr (text, "<span"))
2966 static GstFlowReturn
2967 gst_matroska_demux_check_subtitle_buffer (GstElement * element,
2968 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2970 GstMatroskaTrackSubtitleContext *sub_stream;
2971 const gchar *encoding;
2977 sub_stream = (GstMatroskaTrackSubtitleContext *) stream;
2979 if (!gst_buffer_map (*buf, &map, GST_MAP_READ))
2982 if (!sub_stream->invalid_utf8) {
2983 if (g_utf8_validate ((gchar *) map.data, map.size, NULL)) {
2986 GST_WARNING_OBJECT (element, "subtitle stream %d is not valid UTF-8, this "
2987 "is broken according to the matroska specification", stream->num);
2988 sub_stream->invalid_utf8 = TRUE;
2991 /* file with broken non-UTF8 subtitle, do the best we can do to fix it */
2992 encoding = g_getenv ("GST_SUBTITLE_ENCODING");
2993 if (encoding == NULL || *encoding == '\0') {
2994 /* if local encoding is UTF-8 and no encoding specified
2995 * via the environment variable, assume ISO-8859-15 */
2996 if (g_get_charset (&encoding)) {
2997 encoding = "ISO-8859-15";
3002 g_convert_with_fallback ((gchar *) map.data, map.size, "UTF-8", encoding,
3003 (char *) "*", NULL, NULL, &err);
3006 GST_LOG_OBJECT (element, "could not convert string from '%s' to UTF-8: %s",
3007 encoding, err->message);
3011 /* invalid input encoding, fall back to ISO-8859-15 (always succeeds) */
3012 encoding = "ISO-8859-15";
3014 g_convert_with_fallback ((gchar *) map.data, map.size, "UTF-8",
3015 encoding, (char *) "*", NULL, NULL, NULL);
3018 GST_LOG_OBJECT (element, "converted subtitle text from %s to UTF-8 %s",
3019 encoding, (err) ? "(using ISO-8859-15 as fallback)" : "");
3022 utf8 = g_strdup ("invalid subtitle");
3024 newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
3025 gst_buffer_copy_into (newbuf, *buf,
3026 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_META,
3028 gst_buffer_unmap (*buf, &map);
3029 gst_buffer_unref (*buf);
3032 gst_buffer_map (*buf, &map, GST_MAP_READ);
3035 if (sub_stream->check_markup) {
3036 /* caps claim markup text, so we need to escape text,
3037 * except if text is already markup and then needs no further escaping */
3038 sub_stream->seen_markup_tag = sub_stream->seen_markup_tag ||
3039 gst_matroska_demux_subtitle_chunk_has_tag (element, (gchar *) map.data);
3041 if (!sub_stream->seen_markup_tag) {
3042 utf8 = g_markup_escape_text ((gchar *) map.data, map.size);
3044 newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
3045 gst_buffer_copy_into (newbuf, *buf,
3046 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS |
3047 GST_BUFFER_COPY_META, 0, -1);
3048 gst_buffer_unmap (*buf, &map);
3049 gst_buffer_unref (*buf);
3058 static GstFlowReturn
3059 gst_matroska_demux_check_aac (GstElement * element,
3060 GstMatroskaTrackContext * stream, GstBuffer ** buf)
3065 gst_buffer_extract (*buf, 0, data, 2);
3066 size = gst_buffer_get_size (*buf);
3068 if (size > 2 && data[0] == 0xff && (data[1] >> 4 == 0x0f)) {
3071 /* tss, ADTS data, remove codec_data
3072 * still assume it is at least parsed */
3073 stream->caps = gst_caps_make_writable (stream->caps);
3074 s = gst_caps_get_structure (stream->caps, 0);
3076 gst_structure_remove_field (s, "codec_data");
3077 gst_pad_set_caps (stream->pad, stream->caps);
3078 GST_DEBUG_OBJECT (element, "ADTS AAC audio data; removing codec-data, "
3079 "new caps: %" GST_PTR_FORMAT, stream->caps);
3082 /* disable subsequent checking */
3083 stream->postprocess_frame = NULL;
3089 gst_matroska_demux_align_buffer (GstMatroskaDemux * demux,
3090 GstBuffer * buffer, gsize alignment)
3094 gst_buffer_map (buffer, &map, GST_MAP_READ);
3096 if (map.size < sizeof (guintptr)) {
3097 gst_buffer_unmap (buffer, &map);
3101 if (((guintptr) map.data) & (alignment - 1)) {
3102 GstBuffer *new_buffer;
3103 GstAllocationParams params = { 0, 0, 0, alignment - 1, };
3105 new_buffer = gst_buffer_new_allocate (NULL,
3106 gst_buffer_get_size (buffer), ¶ms);
3108 /* Copy data "by hand", so ensure alignment is kept: */
3109 gst_buffer_fill (new_buffer, 0, map.data, map.size);
3111 gst_buffer_copy_into (new_buffer, buffer, GST_BUFFER_COPY_METADATA, 0, -1);
3112 GST_DEBUG_OBJECT (demux,
3113 "We want output aligned on %" G_GSIZE_FORMAT ", reallocated",
3116 gst_buffer_unmap (buffer, &map);
3117 gst_buffer_unref (buffer);
3122 gst_buffer_unmap (buffer, &map);
3126 static GstFlowReturn
3127 gst_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux,
3128 GstEbmlRead * ebml, guint64 cluster_time, guint64 cluster_offset,
3129 gboolean is_simpleblock)
3131 GstMatroskaTrackContext *stream = NULL;
3132 GstFlowReturn ret = GST_FLOW_OK;
3133 gboolean readblock = FALSE;
3135 guint64 block_duration = -1;
3136 GstBuffer *buf = NULL;
3138 gint stream_num = -1, n, laces = 0;
3140 gint *lace_size = NULL;
3143 gint64 referenceblock = 0;
3146 offset = gst_ebml_read_get_offset (ebml);
3148 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3149 if (!is_simpleblock) {
3150 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK) {
3154 id = GST_MATROSKA_ID_SIMPLEBLOCK;
3158 /* one block inside the group. Note, block parsing is one
3159 * of the harder things, so this code is a bit complicated.
3160 * See http://www.matroska.org/ for documentation. */
3161 case GST_MATROSKA_ID_SIMPLEBLOCK:
3162 case GST_MATROSKA_ID_BLOCK:
3168 gst_buffer_unmap (buf, &map);
3169 gst_buffer_unref (buf);
3172 if ((ret = gst_ebml_read_buffer (ebml, &id, &buf)) != GST_FLOW_OK)
3175 gst_buffer_map (buf, &map, GST_MAP_READ);
3179 /* first byte(s): blocknum */
3180 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
3185 /* fetch stream from num */
3186 stream_num = gst_matroska_read_common_stream_from_num (&demux->common,
3188 if (G_UNLIKELY (size < 3)) {
3189 GST_WARNING_OBJECT (demux, "Invalid size %u", size);
3190 /* non-fatal, try next block(group) */
3193 } else if (G_UNLIKELY (stream_num < 0 ||
3194 stream_num >= demux->common.num_streams)) {
3195 /* let's not give up on a stray invalid track number */
3196 GST_WARNING_OBJECT (demux,
3197 "Invalid stream %d for track number %" G_GUINT64_FORMAT
3198 "; ignoring block", stream_num, num);
3202 stream = g_ptr_array_index (demux->common.src, stream_num);
3204 /* time (relative to cluster time) */
3205 time = ((gint16) GST_READ_UINT16_BE (data));
3208 flags = GST_READ_UINT8 (data);
3212 GST_LOG_OBJECT (demux, "time %" G_GUINT64_FORMAT ", flags %d", time,
3215 switch ((flags & 0x06) >> 1) {
3216 case 0x0: /* no lacing */
3218 lace_size = g_new (gint, 1);
3219 lace_size[0] = size;
3222 case 0x1: /* xiph lacing */
3223 case 0x2: /* fixed-size lacing */
3224 case 0x3: /* EBML lacing */
3226 goto invalid_lacing;
3227 laces = GST_READ_UINT8 (data) + 1;
3230 lace_size = g_new0 (gint, laces);
3232 switch ((flags & 0x06) >> 1) {
3233 case 0x1: /* xiph lacing */ {
3234 guint temp, total = 0;
3236 for (n = 0; ret == GST_FLOW_OK && n < laces - 1; n++) {
3239 goto invalid_lacing;
3240 temp = GST_READ_UINT8 (data);
3241 lace_size[n] += temp;
3247 total += lace_size[n];
3249 lace_size[n] = size - total;
3253 case 0x2: /* fixed-size lacing */
3254 for (n = 0; n < laces; n++)
3255 lace_size[n] = size / laces;
3258 case 0x3: /* EBML lacing */ {
3261 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
3265 total = lace_size[0] = num;
3266 for (n = 1; ret == GST_FLOW_OK && n < laces - 1; n++) {
3270 if ((r = gst_matroska_ebmlnum_sint (data, size, &snum)) < 0)
3274 lace_size[n] = lace_size[n - 1] + snum;
3275 total += lace_size[n];
3278 lace_size[n] = size - total;
3285 if (stream->send_xiph_headers) {
3286 ret = gst_matroska_demux_push_xiph_codec_priv_data (demux, stream);
3287 stream->send_xiph_headers = FALSE;
3290 if (stream->send_flac_headers) {
3291 ret = gst_matroska_demux_push_flac_codec_priv_data (demux, stream);
3292 stream->send_flac_headers = FALSE;
3295 if (stream->send_speex_headers) {
3296 ret = gst_matroska_demux_push_speex_codec_priv_data (demux, stream);
3297 stream->send_speex_headers = FALSE;
3300 if (stream->send_dvd_event) {
3301 gst_matroska_demux_push_dvd_clut_change_event (demux, stream);
3302 /* FIXME: should we send this event again after (flushing) seek ? */
3303 stream->send_dvd_event = FALSE;
3306 if (ret != GST_FLOW_OK)
3313 case GST_MATROSKA_ID_BLOCKDURATION:{
3314 ret = gst_ebml_read_uint (ebml, &id, &block_duration);
3315 GST_DEBUG_OBJECT (demux, "BlockDuration: %" G_GUINT64_FORMAT,
3320 case GST_MATROSKA_ID_REFERENCEBLOCK:{
3321 ret = gst_ebml_read_sint (ebml, &id, &referenceblock);
3322 GST_DEBUG_OBJECT (demux, "ReferenceBlock: %" G_GINT64_FORMAT,
3327 case GST_MATROSKA_ID_CODECSTATE:{
3329 guint64 data_len = 0;
3332 gst_ebml_read_binary (ebml, &id, &data,
3333 &data_len)) != GST_FLOW_OK)
3336 if (G_UNLIKELY (stream == NULL)) {
3337 GST_WARNING_OBJECT (demux,
3338 "Unexpected CodecState subelement - ignoring");
3342 g_free (stream->codec_state);
3343 stream->codec_state = data;
3344 stream->codec_state_size = data_len;
3346 /* Decode if necessary */
3347 if (stream->encodings && stream->encodings->len > 0
3348 && stream->codec_state && stream->codec_state_size > 0) {
3349 if (!gst_matroska_decode_data (stream->encodings,
3350 &stream->codec_state, &stream->codec_state_size,
3351 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
3352 GST_WARNING_OBJECT (demux, "Decoding codec state failed");
3356 GST_DEBUG_OBJECT (demux, "CodecState of %" G_GSIZE_FORMAT " bytes",
3357 stream->codec_state_size);
3362 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3366 case GST_MATROSKA_ID_BLOCKVIRTUAL:
3367 case GST_MATROSKA_ID_BLOCKADDITIONS:
3368 case GST_MATROSKA_ID_REFERENCEPRIORITY:
3369 case GST_MATROSKA_ID_REFERENCEVIRTUAL:
3370 case GST_MATROSKA_ID_SLICES:
3371 GST_DEBUG_OBJECT (demux,
3372 "Skipping BlockGroup subelement 0x%x - ignoring", id);
3373 ret = gst_ebml_read_skip (ebml);
3381 /* reading a number or so could have failed */
3382 if (ret != GST_FLOW_OK)
3385 if (ret == GST_FLOW_OK && readblock) {
3386 guint64 duration = 0;
3387 gint64 lace_time = 0;
3388 gboolean delta_unit;
3390 stream = g_ptr_array_index (demux->common.src, stream_num);
3392 if (cluster_time != GST_CLOCK_TIME_NONE) {
3393 /* FIXME: What to do with negative timestamps? Give timestamp 0 or -1?
3394 * Drop unless the lace contains timestamp 0? */
3395 if (time < 0 && (-time) > cluster_time) {
3398 if (stream->timecodescale == 1.0)
3399 lace_time = (cluster_time + time) * demux->common.time_scale;
3402 gst_util_guint64_to_gdouble ((cluster_time + time) *
3403 demux->common.time_scale) * stream->timecodescale;
3406 lace_time = GST_CLOCK_TIME_NONE;
3409 /* need to refresh segment info ASAP */
3410 if (GST_CLOCK_TIME_IS_VALID (lace_time) && demux->need_segment) {
3411 GstSegment *segment = &demux->common.segment;
3412 guint64 segment_duration = 0;
3414 GST_DEBUG_OBJECT (demux,
3415 "generating segment starting at %" GST_TIME_FORMAT,
3416 GST_TIME_ARGS (lace_time));
3417 if (!GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
3418 demux->stream_start_time = lace_time;
3419 GST_DEBUG_OBJECT (demux,
3420 "Setting stream start time to %" GST_TIME_FORMAT,
3421 GST_TIME_ARGS (lace_time));
3423 if (GST_CLOCK_TIME_IS_VALID (segment->stop))
3424 segment_duration = segment->stop - segment->start;
3425 else if (GST_CLOCK_TIME_IS_VALID (segment->position))
3426 segment_duration = segment->position - segment->start;
3427 segment->base += segment_duration / fabs (segment->rate);
3428 segment->start = MAX (lace_time, demux->stream_start_time);
3429 segment->stop = GST_CLOCK_TIME_NONE;
3430 segment->position = segment->start - demux->stream_start_time;
3431 /* now convey our segment notion downstream */
3432 gst_matroska_demux_send_event (demux, gst_event_new_segment (segment));
3433 demux->need_segment = FALSE;
3436 if (block_duration != -1) {
3437 if (stream->timecodescale == 1.0)
3438 duration = gst_util_uint64_scale (block_duration,
3439 demux->common.time_scale, 1);
3442 gst_util_gdouble_to_guint64 (gst_util_guint64_to_gdouble
3443 (gst_util_uint64_scale (block_duration, demux->common.time_scale,
3444 1)) * stream->timecodescale);
3445 } else if (stream->default_duration) {
3446 duration = stream->default_duration * laces;
3448 /* else duration is diff between timecode of this and next block */
3450 /* For SimpleBlock, look at the keyframe bit in flags. Otherwise,
3451 a ReferenceBlock implies that this is not a keyframe. In either
3452 case, it only makes sense for video streams. */
3453 delta_unit = stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
3454 ((is_simpleblock && !(flags & 0x80)) || referenceblock);
3456 if (delta_unit && stream->set_discont) {
3457 /* When doing seeks or such, we need to restart on key frames or
3458 * decoders might choke. */
3459 GST_DEBUG_OBJECT (demux, "skipping delta unit");
3463 for (n = 0; n < laces; n++) {
3466 if (G_UNLIKELY (lace_size[n] > size)) {
3467 GST_WARNING_OBJECT (demux, "Invalid lace size");
3471 /* QoS for video track with an index. the assumption is that
3472 index entries point to keyframes, but if that is not true we
3473 will instad skip until the next keyframe. */
3474 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
3475 stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
3476 stream->index_table && demux->common.segment.rate > 0.0) {
3477 GstMatroskaTrackVideoContext *videocontext =
3478 (GstMatroskaTrackVideoContext *) stream;
3479 GstClockTime earliest_time;
3480 GstClockTime earliest_stream_time;
3482 GST_OBJECT_LOCK (demux);
3483 earliest_time = videocontext->earliest_time;
3484 GST_OBJECT_UNLOCK (demux);
3485 earliest_stream_time = gst_segment_to_position (&demux->common.segment,
3486 GST_FORMAT_TIME, earliest_time);
3488 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
3489 GST_CLOCK_TIME_IS_VALID (earliest_stream_time) &&
3490 lace_time <= earliest_stream_time) {
3491 /* find index entry (keyframe) <= earliest_stream_time */
3492 GstMatroskaIndex *entry =
3493 gst_util_array_binary_search (stream->index_table->data,
3494 stream->index_table->len, sizeof (GstMatroskaIndex),
3495 (GCompareDataFunc) gst_matroska_index_seek_find,
3496 GST_SEARCH_MODE_BEFORE, &earliest_stream_time, NULL);
3498 /* if that entry (keyframe) is after the current the current
3499 buffer, we can skip pushing (and thus decoding) all
3500 buffers until that keyframe. */
3501 if (entry && GST_CLOCK_TIME_IS_VALID (entry->time) &&
3502 entry->time > lace_time) {
3503 GST_LOG_OBJECT (demux, "Skipping lace before late keyframe");
3504 stream->set_discont = TRUE;
3510 sub = gst_buffer_copy_region (buf, GST_BUFFER_COPY_ALL,
3511 gst_buffer_get_size (buf) - size, lace_size[n]);
3512 GST_DEBUG_OBJECT (demux, "created subbuffer %p", sub);
3515 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
3517 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
3519 if (stream->encodings != NULL && stream->encodings->len > 0)
3520 sub = gst_matroska_decode_buffer (stream, sub);
3523 GST_WARNING_OBJECT (demux, "Decoding buffer failed");
3527 GST_BUFFER_TIMESTAMP (sub) = lace_time;
3529 if (GST_CLOCK_TIME_IS_VALID (lace_time)) {
3530 GstClockTime last_stop_end;
3532 /* Check if this stream is after segment stop */
3533 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop) &&
3534 lace_time >= demux->common.segment.stop) {
3535 GST_DEBUG_OBJECT (demux,
3536 "Stream %d after segment stop %" GST_TIME_FORMAT, stream->index,
3537 GST_TIME_ARGS (demux->common.segment.stop));
3538 gst_buffer_unref (sub);
3541 if (offset >= stream->to_offset) {
3542 GST_DEBUG_OBJECT (demux, "Stream %d after playback section",
3544 gst_buffer_unref (sub);
3548 /* handle gaps, e.g. non-zero start-time, or an cue index entry
3549 * that landed us with timestamps not quite intended */
3550 GST_OBJECT_LOCK (demux);
3551 if (demux->max_gap_time &&
3552 GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) &&
3553 demux->common.segment.rate > 0.0) {
3554 GstClockTimeDiff diff;
3556 /* only send segments with increasing start times,
3557 * otherwise if these go back and forth downstream (sinks) increase
3558 * accumulated time and running_time */
3559 diff = GST_CLOCK_DIFF (demux->last_stop_end, lace_time);
3560 if (diff > 0 && diff > demux->max_gap_time
3561 && lace_time > demux->common.segment.start
3562 && (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop)
3563 || lace_time < demux->common.segment.stop)) {
3565 GstEvent *event1, *event2;
3566 GST_DEBUG_OBJECT (demux,
3567 "Gap of %" G_GINT64_FORMAT " ns detected in"
3568 "stream %d (%" GST_TIME_FORMAT " -> %" GST_TIME_FORMAT "). "
3569 "Sending updated SEGMENT events", diff,
3570 stream->index, GST_TIME_ARGS (stream->pos),
3571 GST_TIME_ARGS (lace_time));
3572 /* send segment events such that the gap is not accounted in
3573 * segment base time, hence running_time */
3574 /* close ahead of gap */
3575 segment = demux->common.segment;
3576 segment.start = demux->last_stop_end;
3577 segment.stop = demux->last_stop_end;
3578 segment.position = demux->last_stop_end;
3579 event1 = gst_event_new_segment (&segment);
3581 segment.start = lace_time;
3582 segment.stop = demux->common.segment.stop;
3583 segment.position = lace_time;
3584 event2 = gst_event_new_segment (&segment);
3585 GST_OBJECT_UNLOCK (demux);
3586 gst_matroska_demux_send_event (demux, event1);
3587 gst_matroska_demux_send_event (demux, event2);
3588 GST_OBJECT_LOCK (demux);
3589 /* align segment view with downstream,
3590 * prevents double-counting base time when closing segment */
3591 /* FIXME: in 0.10, the segment base/accum got updated here, but
3592 * maybe we don't need that because of the double accounting
3593 * mentioned above? */
3594 demux->common.segment = segment;
3598 if (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.position)
3599 || demux->common.segment.position < lace_time) {
3600 demux->common.segment.position = lace_time;
3602 GST_OBJECT_UNLOCK (demux);
3604 last_stop_end = lace_time;
3606 GST_BUFFER_DURATION (sub) = duration / laces;
3607 last_stop_end += GST_BUFFER_DURATION (sub);
3610 if (!GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) ||
3611 demux->last_stop_end < last_stop_end)
3612 demux->last_stop_end = last_stop_end;
3614 GST_OBJECT_LOCK (demux);
3615 if (demux->common.segment.duration == -1 ||
3616 demux->stream_start_time + demux->common.segment.duration <
3618 demux->common.segment.duration =
3619 last_stop_end - demux->stream_start_time;
3620 GST_OBJECT_UNLOCK (demux);
3621 if (!demux->invalid_duration) {
3622 gst_element_post_message (GST_ELEMENT_CAST (demux),
3623 gst_message_new_duration (GST_OBJECT_CAST (demux),
3624 GST_FORMAT_TIME, GST_CLOCK_TIME_NONE));
3625 demux->invalid_duration = TRUE;
3628 GST_OBJECT_UNLOCK (demux);
3632 stream->pos = lace_time;
3634 gst_matroska_demux_sync_streams (demux);
3636 if (stream->set_discont) {
3637 GST_DEBUG_OBJECT (demux, "marking DISCONT");
3638 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DISCONT);
3639 stream->set_discont = FALSE;
3642 /* reverse playback book-keeping */
3643 if (!GST_CLOCK_TIME_IS_VALID (stream->from_time))
3644 stream->from_time = lace_time;
3645 if (stream->from_offset == -1)
3646 stream->from_offset = offset;
3648 GST_DEBUG_OBJECT (demux,
3649 "Pushing lace %d, data of size %" G_GSIZE_FORMAT
3650 " for stream %d, time=%" GST_TIME_FORMAT " and duration=%"
3651 GST_TIME_FORMAT, n, gst_buffer_get_size (sub), stream_num,
3652 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (sub)),
3653 GST_TIME_ARGS (GST_BUFFER_DURATION (sub)));
3656 if (demux->common.element_index) {
3657 if (stream->index_writer_id == -1)
3658 gst_index_get_writer_id (demux->common.element_index,
3659 GST_OBJECT (stream->pad), &stream->index_writer_id);
3661 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
3662 G_GUINT64_FORMAT " for writer id %d",
3663 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (sub)), cluster_offset,
3664 stream->index_writer_id);
3665 gst_index_add_association (demux->common.element_index,
3666 stream->index_writer_id, GST_BUFFER_FLAG_IS_SET (sub,
3667 GST_BUFFER_FLAG_DELTA_UNIT) ? 0 : GST_ASSOCIATION_FLAG_KEY_UNIT,
3668 GST_FORMAT_TIME, GST_BUFFER_TIMESTAMP (sub), GST_FORMAT_BYTES,
3669 cluster_offset, NULL);
3673 /* Postprocess the buffers depending on the codec used */
3674 if (stream->postprocess_frame) {
3675 GST_LOG_OBJECT (demux, "running post process");
3676 ret = stream->postprocess_frame (GST_ELEMENT (demux), stream, &sub);
3679 /* At this point, we have a sub-buffer pointing at data within a larger
3680 buffer. This data might not be aligned with anything. If the data is
3681 raw samples though, we want it aligned to the raw type (eg, 4 bytes
3682 for 32 bit samples, etc), or bad things will happen downstream as
3683 elements typically assume minimal alignment.
3684 Therefore, create an aligned copy if necessary. */
3685 g_assert (stream->alignment <= G_MEM_ALIGN);
3686 sub = gst_matroska_demux_align_buffer (demux, sub, stream->alignment);
3688 ret = gst_pad_push (stream->pad, sub);
3689 if (demux->common.segment.rate < 0) {
3690 if (lace_time > demux->common.segment.stop && ret == GST_FLOW_EOS) {
3691 /* In reverse playback we can get a GST_FLOW_EOS when
3692 * we are at the end of the segment, so we just need to jump
3693 * back to the previous section. */
3694 GST_DEBUG_OBJECT (demux, "downstream has reached end of segment");
3699 ret = gst_matroska_demux_combine_flows (demux, stream, ret);
3702 size -= lace_size[n];
3703 if (lace_time != GST_CLOCK_TIME_NONE && duration)
3704 lace_time += duration / laces;
3706 lace_time = GST_CLOCK_TIME_NONE;
3712 gst_buffer_unmap (buf, &map);
3713 gst_buffer_unref (buf);
3725 ret = gst_matroska_demux_combine_flows (demux, stream, ret);
3730 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Invalid lacing size"));
3731 /* non-fatal, try next block(group) */
3737 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Data error"));
3738 /* non-fatal, try next block(group) */
3744 /* return FALSE if block(group) should be skipped (due to a seek) */
3745 static inline gboolean
3746 gst_matroska_demux_seek_block (GstMatroskaDemux * demux)
3748 if (G_UNLIKELY (demux->seek_block)) {
3749 if (!(--demux->seek_block)) {
3752 GST_LOG_OBJECT (demux, "should skip block due to seek");
3760 static GstFlowReturn
3761 gst_matroska_demux_parse_contents_seekentry (GstMatroskaDemux * demux,
3765 guint64 seek_pos = (guint64) - 1;
3766 guint32 seek_id = 0;
3769 DEBUG_ELEMENT_START (demux, ebml, "Seek");
3771 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3772 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
3776 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3777 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3781 case GST_MATROSKA_ID_SEEKID:
3785 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
3788 GST_DEBUG_OBJECT (demux, "SeekID: %" G_GUINT64_FORMAT, t);
3793 case GST_MATROSKA_ID_SEEKPOSITION:
3797 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
3800 if (t > G_MAXINT64) {
3801 GST_WARNING_OBJECT (demux,
3802 "Too large SeekPosition %" G_GUINT64_FORMAT, t);
3806 GST_DEBUG_OBJECT (demux, "SeekPosition: %" G_GUINT64_FORMAT, t);
3812 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3818 if (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)
3821 if (!seek_id || seek_pos == (guint64) - 1) {
3822 GST_WARNING_OBJECT (demux, "Incomplete seekhead entry (0x%x/%"
3823 G_GUINT64_FORMAT ")", seek_id, seek_pos);
3828 case GST_MATROSKA_ID_SEEKHEAD:
3831 case GST_MATROSKA_ID_CUES:
3832 case GST_MATROSKA_ID_TAGS:
3833 case GST_MATROSKA_ID_TRACKS:
3834 case GST_MATROSKA_ID_SEGMENTINFO:
3835 case GST_MATROSKA_ID_ATTACHMENTS:
3836 case GST_MATROSKA_ID_CHAPTERS:
3838 guint64 before_pos, length;
3842 length = gst_matroska_read_common_get_length (&demux->common);
3843 before_pos = demux->common.offset;
3845 if (length == (guint64) - 1) {
3846 GST_DEBUG_OBJECT (demux, "no upstream length, skipping SeakHead entry");
3850 /* check for validity */
3851 if (seek_pos + demux->common.ebml_segment_start + 12 >= length) {
3852 GST_WARNING_OBJECT (demux,
3853 "SeekHead reference lies outside file!" " (%"
3854 G_GUINT64_FORMAT "+%" G_GUINT64_FORMAT "+12 >= %"
3855 G_GUINT64_FORMAT ")", seek_pos, demux->common.ebml_segment_start,
3860 /* only pick up index location when streaming */
3861 if (demux->streaming) {
3862 if (seek_id == GST_MATROSKA_ID_CUES) {
3863 demux->index_offset = seek_pos + demux->common.ebml_segment_start;
3864 GST_DEBUG_OBJECT (demux, "Cues located at offset %" G_GUINT64_FORMAT,
3865 demux->index_offset);
3871 demux->common.offset = seek_pos + demux->common.ebml_segment_start;
3874 if ((ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
3875 GST_ELEMENT_CAST (demux), &id, &length, &needed)) !=
3879 if (id != seek_id) {
3880 GST_WARNING_OBJECT (demux,
3881 "We looked for ID=0x%x but got ID=0x%x (pos=%" G_GUINT64_FORMAT ")",
3882 seek_id, id, seek_pos + demux->common.ebml_segment_start);
3885 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
3890 demux->common.offset = before_pos;
3894 case GST_MATROSKA_ID_CLUSTER:
3896 guint64 pos = seek_pos + demux->common.ebml_segment_start;
3898 GST_LOG_OBJECT (demux, "Cluster position");
3899 if (G_UNLIKELY (!demux->clusters))
3900 demux->clusters = g_array_sized_new (TRUE, TRUE, sizeof (guint64), 100);
3901 g_array_append_val (demux->clusters, pos);
3906 GST_DEBUG_OBJECT (demux, "Ignoring Seek entry for ID=0x%x", seek_id);
3909 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
3914 static GstFlowReturn
3915 gst_matroska_demux_parse_contents (GstMatroskaDemux * demux, GstEbmlRead * ebml)
3917 GstFlowReturn ret = GST_FLOW_OK;
3920 DEBUG_ELEMENT_START (demux, ebml, "SeekHead");
3922 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3923 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
3927 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3928 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3932 case GST_MATROSKA_ID_SEEKENTRY:
3934 ret = gst_matroska_demux_parse_contents_seekentry (demux, ebml);
3935 /* Ignore EOS and errors here */
3936 if (ret != GST_FLOW_OK) {
3937 GST_DEBUG_OBJECT (demux, "Ignoring %s", gst_flow_get_name (ret));
3944 ret = gst_matroska_read_common_parse_skip (&demux->common,
3945 ebml, "SeekHead", id);
3950 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
3952 /* Sort clusters by position for easier searching */
3953 if (demux->clusters)
3954 g_array_sort (demux->clusters, (GCompareFunc) gst_matroska_cluster_compare);
3959 #define GST_FLOW_OVERFLOW GST_FLOW_CUSTOM_ERROR
3961 #define MAX_BLOCK_SIZE (15 * 1024 * 1024)
3963 static inline GstFlowReturn
3964 gst_matroska_demux_check_read_size (GstMatroskaDemux * demux, guint64 bytes)
3966 if (G_UNLIKELY (bytes > MAX_BLOCK_SIZE)) {
3967 /* only a few blocks are expected/allowed to be large,
3968 * and will be recursed into, whereas others will be read and must fit */
3969 if (demux->streaming) {
3970 /* fatal in streaming case, as we can't step over easily */
3971 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
3972 ("reading large block of size %" G_GUINT64_FORMAT " not supported; "
3973 "file might be corrupt.", bytes));
3974 return GST_FLOW_ERROR;
3976 /* indicate higher level to quietly give up */
3977 GST_DEBUG_OBJECT (demux,
3978 "too large block of size %" G_GUINT64_FORMAT, bytes);
3979 return GST_FLOW_ERROR;
3986 /* returns TRUE if we truely are in error state, and should give up */
3987 static inline gboolean
3988 gst_matroska_demux_check_parse_error (GstMatroskaDemux * demux)
3990 if (!demux->streaming && demux->next_cluster_offset > 0) {
3991 /* just repositioning to where next cluster should be and try from there */
3992 GST_WARNING_OBJECT (demux, "parse error, trying next cluster expected at %"
3993 G_GUINT64_FORMAT, demux->next_cluster_offset);
3994 demux->common.offset = demux->next_cluster_offset;
3995 demux->next_cluster_offset = 0;
4000 /* sigh, one last attempt above and beyond call of duty ...;
4001 * search for cluster mark following current pos */
4002 pos = demux->common.offset;
4003 GST_WARNING_OBJECT (demux, "parse error, looking for next cluster");
4004 if (gst_matroska_demux_search_cluster (demux, &pos) != GST_FLOW_OK) {
4005 /* did not work, give up */
4008 GST_DEBUG_OBJECT (demux, "... found at %" G_GUINT64_FORMAT, pos);
4009 /* try that position */
4010 demux->common.offset = pos;
4016 static inline GstFlowReturn
4017 gst_matroska_demux_flush (GstMatroskaDemux * demux, guint flush)
4019 GST_LOG_OBJECT (demux, "skipping %d bytes", flush);
4020 demux->common.offset += flush;
4021 if (demux->streaming) {
4024 /* hard to skip large blocks when streaming */
4025 ret = gst_matroska_demux_check_read_size (demux, flush);
4026 if (ret != GST_FLOW_OK)
4028 if (flush <= gst_adapter_available (demux->common.adapter))
4029 gst_adapter_flush (demux->common.adapter, flush);
4031 return GST_FLOW_EOS;
4036 /* initializes @ebml with @bytes from input stream at current offset.
4037 * Returns EOS if insufficient available,
4038 * ERROR if too much was attempted to read. */
4039 static inline GstFlowReturn
4040 gst_matroska_demux_take (GstMatroskaDemux * demux, guint64 bytes,
4043 GstBuffer *buffer = NULL;
4044 GstFlowReturn ret = GST_FLOW_OK;
4046 GST_LOG_OBJECT (demux, "taking %" G_GUINT64_FORMAT " bytes for parsing",
4048 ret = gst_matroska_demux_check_read_size (demux, bytes);
4049 if (G_UNLIKELY (ret != GST_FLOW_OK)) {
4050 if (!demux->streaming) {
4051 /* in pull mode, we can skip */
4052 if ((ret = gst_matroska_demux_flush (demux, bytes)) == GST_FLOW_OK)
4053 ret = GST_FLOW_OVERFLOW;
4055 /* otherwise fatal */
4056 ret = GST_FLOW_ERROR;
4060 if (demux->streaming) {
4061 if (gst_adapter_available (demux->common.adapter) >= bytes)
4062 buffer = gst_adapter_take_buffer (demux->common.adapter, bytes);
4066 ret = gst_matroska_read_common_peek_bytes (&demux->common,
4067 demux->common.offset, bytes, &buffer, NULL);
4068 if (G_LIKELY (buffer)) {
4069 gst_ebml_read_init (ebml, GST_ELEMENT_CAST (demux), buffer,
4070 demux->common.offset);
4071 demux->common.offset += bytes;
4078 gst_matroska_demux_check_seekability (GstMatroskaDemux * demux)
4081 gboolean seekable = FALSE;
4082 gint64 start = -1, stop = -1;
4084 query = gst_query_new_seeking (GST_FORMAT_BYTES);
4085 if (!gst_pad_peer_query (demux->common.sinkpad, query)) {
4086 GST_DEBUG_OBJECT (demux, "seeking query failed");
4090 gst_query_parse_seeking (query, NULL, &seekable, &start, &stop);
4092 /* try harder to query upstream size if we didn't get it the first time */
4093 if (seekable && stop == -1) {
4094 GST_DEBUG_OBJECT (demux, "doing duration query to fix up unset stop");
4095 gst_pad_peer_query_duration (demux->common.sinkpad, GST_FORMAT_BYTES,
4099 /* if upstream doesn't know the size, it's likely that it's not seekable in
4100 * practice even if it technically may be seekable */
4101 if (seekable && (start != 0 || stop <= start)) {
4102 GST_DEBUG_OBJECT (demux, "seekable but unknown start/stop -> disable");
4107 GST_INFO_OBJECT (demux, "seekable: %d (%" G_GUINT64_FORMAT " - %"
4108 G_GUINT64_FORMAT ")", seekable, start, stop);
4109 demux->seekable = seekable;
4111 gst_query_unref (query);
4114 static GstFlowReturn
4115 gst_matroska_demux_find_tracks (GstMatroskaDemux * demux)
4121 GstFlowReturn ret = GST_FLOW_OK;
4123 GST_WARNING_OBJECT (demux,
4124 "Found Cluster element before Tracks, searching Tracks");
4127 before_pos = demux->common.offset;
4129 /* Search Tracks element */
4131 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4132 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4133 if (ret != GST_FLOW_OK)
4136 if (id != GST_MATROSKA_ID_TRACKS) {
4137 /* we may be skipping large cluster here, so forego size check etc */
4138 /* ... but we can't skip undefined size; force error */
4139 if (length == G_MAXUINT64) {
4140 ret = gst_matroska_demux_check_read_size (demux, length);
4143 demux->common.offset += needed;
4144 demux->common.offset += length;
4149 /* will lead to track parsing ... */
4150 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4155 demux->common.offset = before_pos;
4160 #define GST_READ_CHECK(stmt) \
4162 if (G_UNLIKELY ((ret = (stmt)) != GST_FLOW_OK)) { \
4163 if (ret == GST_FLOW_OVERFLOW) { \
4164 ret = GST_FLOW_OK; \
4170 static GstFlowReturn
4171 gst_matroska_demux_parse_id (GstMatroskaDemux * demux, guint32 id,
4172 guint64 length, guint needed)
4174 GstEbmlRead ebml = { 0, };
4175 GstFlowReturn ret = GST_FLOW_OK;
4178 GST_LOG_OBJECT (demux, "Parsing Element id 0x%x, "
4179 "size %" G_GUINT64_FORMAT ", prefix %d", id, length, needed);
4181 /* if we plan to read and parse this element, we need prefix (id + length)
4182 * and the contents */
4183 /* mind about overflow wrap-around when dealing with undefined size */
4185 if (G_LIKELY (length != G_MAXUINT64))
4188 switch (demux->common.state) {
4189 case GST_MATROSKA_READ_STATE_START:
4191 case GST_EBML_ID_HEADER:
4192 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4193 ret = gst_matroska_read_common_parse_header (&demux->common, &ebml);
4194 if (ret != GST_FLOW_OK)
4196 demux->common.state = GST_MATROSKA_READ_STATE_SEGMENT;
4197 gst_matroska_demux_check_seekability (demux);
4200 goto invalid_header;
4204 case GST_MATROSKA_READ_STATE_SEGMENT:
4206 case GST_MATROSKA_ID_SEGMENT:
4207 /* eat segment prefix */
4208 GST_READ_CHECK (gst_matroska_demux_flush (demux, needed));
4209 GST_DEBUG_OBJECT (demux,
4210 "Found Segment start at offset %" G_GUINT64_FORMAT,
4211 demux->common.offset);
4212 /* seeks are from the beginning of the segment,
4213 * after the segment ID/length */
4214 demux->common.ebml_segment_start = demux->common.offset;
4215 demux->common.state = GST_MATROSKA_READ_STATE_HEADER;
4218 GST_WARNING_OBJECT (demux,
4219 "Expected a Segment ID (0x%x), but received 0x%x!",
4220 GST_MATROSKA_ID_SEGMENT, id);
4221 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4225 case GST_MATROSKA_READ_STATE_SCANNING:
4226 if (id != GST_MATROSKA_ID_CLUSTER &&
4227 id != GST_MATROSKA_ID_CLUSTERTIMECODE)
4230 case GST_MATROSKA_READ_STATE_HEADER:
4231 case GST_MATROSKA_READ_STATE_DATA:
4232 case GST_MATROSKA_READ_STATE_SEEK:
4234 case GST_MATROSKA_ID_SEGMENTINFO:
4235 if (!demux->common.segmentinfo_parsed) {
4236 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4237 ret = gst_matroska_read_common_parse_info (&demux->common,
4238 GST_ELEMENT_CAST (demux), &ebml);
4240 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4243 case GST_MATROSKA_ID_TRACKS:
4244 if (!demux->tracks_parsed) {
4245 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4246 ret = gst_matroska_demux_parse_tracks (demux, &ebml);
4248 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4251 case GST_MATROSKA_ID_CLUSTER:
4252 if (G_UNLIKELY (!demux->tracks_parsed)) {
4253 if (demux->streaming) {
4254 GST_DEBUG_OBJECT (demux, "Cluster before Track");
4255 goto not_streamable;
4257 ret = gst_matroska_demux_find_tracks (demux);
4258 if (!demux->tracks_parsed)
4262 if (G_UNLIKELY (demux->common.state
4263 == GST_MATROSKA_READ_STATE_HEADER)) {
4264 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
4265 demux->first_cluster_offset = demux->common.offset;
4266 GST_DEBUG_OBJECT (demux, "signaling no more pads");
4267 gst_element_no_more_pads (GST_ELEMENT (demux));
4268 /* send initial segment - we wait till we know the first
4269 incoming timestamp, so we can properly set the start of
4271 demux->need_segment = TRUE;
4273 demux->cluster_time = GST_CLOCK_TIME_NONE;
4274 demux->cluster_offset = demux->common.offset;
4275 if (G_UNLIKELY (!demux->seek_first && demux->seek_block)) {
4276 GST_DEBUG_OBJECT (demux, "seek target block %" G_GUINT64_FORMAT
4277 " not found in Cluster, trying next Cluster's first block instead",
4279 demux->seek_block = 0;
4281 demux->seek_first = FALSE;
4282 /* record next cluster for recovery */
4283 if (read != G_MAXUINT64)
4284 demux->next_cluster_offset = demux->cluster_offset + read;
4285 /* eat cluster prefix */
4286 gst_matroska_demux_flush (demux, needed);
4288 case GST_MATROSKA_ID_CLUSTERTIMECODE:
4292 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4293 if ((ret = gst_ebml_read_uint (&ebml, &id, &num)) != GST_FLOW_OK)
4295 GST_DEBUG_OBJECT (demux, "ClusterTimeCode: %" G_GUINT64_FORMAT, num);
4296 demux->cluster_time = num;
4298 if (demux->common.element_index) {
4299 if (demux->common.element_index_writer_id == -1)
4300 gst_index_get_writer_id (demux->common.element_index,
4301 GST_OBJECT (demux), &demux->common.element_index_writer_id);
4302 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
4303 G_GUINT64_FORMAT " for writer id %d",
4304 GST_TIME_ARGS (demux->cluster_time), demux->cluster_offset,
4305 demux->common.element_index_writer_id);
4306 gst_index_add_association (demux->common.element_index,
4307 demux->common.element_index_writer_id,
4308 GST_ASSOCIATION_FLAG_KEY_UNIT,
4309 GST_FORMAT_TIME, demux->cluster_time,
4310 GST_FORMAT_BYTES, demux->cluster_offset, NULL);
4315 case GST_MATROSKA_ID_BLOCKGROUP:
4316 if (!gst_matroska_demux_seek_block (demux))
4318 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4319 DEBUG_ELEMENT_START (demux, &ebml, "BlockGroup");
4320 if ((ret = gst_ebml_read_master (&ebml, &id)) == GST_FLOW_OK) {
4321 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4322 &ebml, demux->cluster_time, demux->cluster_offset, FALSE);
4324 DEBUG_ELEMENT_STOP (demux, &ebml, "BlockGroup", ret);
4326 case GST_MATROSKA_ID_SIMPLEBLOCK:
4327 if (!gst_matroska_demux_seek_block (demux))
4329 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4330 DEBUG_ELEMENT_START (demux, &ebml, "SimpleBlock");
4331 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4332 &ebml, demux->cluster_time, demux->cluster_offset, TRUE);
4333 DEBUG_ELEMENT_STOP (demux, &ebml, "SimpleBlock", ret);
4335 case GST_MATROSKA_ID_ATTACHMENTS:
4336 if (!demux->common.attachments_parsed) {
4337 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4338 ret = gst_matroska_read_common_parse_attachments (&demux->common,
4339 GST_ELEMENT_CAST (demux), &ebml);
4341 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4344 case GST_MATROSKA_ID_TAGS:
4345 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4346 ret = gst_matroska_read_common_parse_metadata (&demux->common,
4347 GST_ELEMENT_CAST (demux), &ebml);
4349 case GST_MATROSKA_ID_CHAPTERS:
4350 if (!demux->common.chapters_parsed) {
4351 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4353 gst_matroska_read_common_parse_chapters (&demux->common, &ebml);
4355 if (demux->common.toc) {
4356 gst_matroska_demux_send_event (demux,
4357 gst_event_new_toc (demux->common.toc, FALSE));
4358 gst_element_post_message (GST_ELEMENT_CAST (demux),
4359 gst_message_new_toc (GST_OBJECT_CAST (demux),
4360 demux->common.toc, FALSE));
4363 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4365 case GST_MATROSKA_ID_SEEKHEAD:
4366 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4367 ret = gst_matroska_demux_parse_contents (demux, &ebml);
4369 case GST_MATROSKA_ID_CUES:
4370 if (demux->common.index_parsed) {
4371 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4374 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4375 ret = gst_matroska_read_common_parse_index (&demux->common, &ebml);
4376 /* only push based; delayed index building */
4377 if (ret == GST_FLOW_OK
4378 && demux->common.state == GST_MATROSKA_READ_STATE_SEEK) {
4381 GST_OBJECT_LOCK (demux);
4382 event = demux->seek_event;
4383 demux->seek_event = NULL;
4384 GST_OBJECT_UNLOCK (demux);
4387 /* unlikely to fail, since we managed to seek to this point */
4388 if (!gst_matroska_demux_handle_seek_event (demux, NULL, event))
4390 /* resume data handling, main thread clear to seek again */
4391 GST_OBJECT_LOCK (demux);
4392 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
4393 GST_OBJECT_UNLOCK (demux);
4396 case GST_MATROSKA_ID_POSITION:
4397 case GST_MATROSKA_ID_PREVSIZE:
4398 case GST_MATROSKA_ID_ENCRYPTEDBLOCK:
4399 case GST_MATROSKA_ID_SILENTTRACKS:
4400 GST_DEBUG_OBJECT (demux,
4401 "Skipping Cluster subelement 0x%x - ignoring", id);
4405 GST_DEBUG_OBJECT (demux, "skipping Element 0x%x", id);
4406 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4412 if (ret == GST_FLOW_PARSE)
4416 gst_ebml_read_clear (&ebml);
4422 /* simply exit, maybe not enough data yet */
4423 /* no ebml to clear if read error */
4428 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4429 ("Failed to parse Element 0x%x", id));
4430 ret = GST_FLOW_ERROR;
4435 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4436 ("File layout does not permit streaming"));
4437 ret = GST_FLOW_ERROR;
4442 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4443 ("No Tracks element found"));
4444 ret = GST_FLOW_ERROR;
4449 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Invalid header"));
4450 ret = GST_FLOW_ERROR;
4455 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Failed to seek"));
4456 ret = GST_FLOW_ERROR;
4462 gst_matroska_demux_loop (GstPad * pad)
4464 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (pad));
4470 /* If we have to close a segment, send a new segment to do this now */
4471 if (G_LIKELY (demux->common.state == GST_MATROSKA_READ_STATE_DATA)) {
4472 if (G_UNLIKELY (demux->new_segment)) {
4473 gst_matroska_demux_send_event (demux, demux->new_segment);
4474 demux->new_segment = NULL;
4478 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4479 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4480 if (ret == GST_FLOW_EOS)
4482 if (ret != GST_FLOW_OK) {
4483 if (gst_matroska_demux_check_parse_error (demux))
4489 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
4490 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
4493 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4494 if (ret == GST_FLOW_EOS)
4496 if (ret != GST_FLOW_OK)
4499 /* check if we're at the end of a configured segment */
4500 if (G_LIKELY (demux->common.src->len)) {
4503 g_assert (demux->common.num_streams == demux->common.src->len);
4504 for (i = 0; i < demux->common.src->len; i++) {
4505 GstMatroskaTrackContext *context = g_ptr_array_index (demux->common.src,
4507 GST_DEBUG_OBJECT (context->pad, "pos %" GST_TIME_FORMAT,
4508 GST_TIME_ARGS (context->pos));
4509 if (context->eos == FALSE)
4513 GST_INFO_OBJECT (demux, "All streams are EOS");
4519 if (G_UNLIKELY (demux->common.offset ==
4520 gst_matroska_read_common_get_length (&demux->common))) {
4521 GST_LOG_OBJECT (demux, "Reached end of stream");
4531 if (demux->common.segment.rate < 0.0) {
4532 ret = gst_matroska_demux_seek_to_previous_keyframe (demux);
4533 if (ret == GST_FLOW_OK)
4540 const gchar *reason = gst_flow_get_name (ret);
4541 gboolean push_eos = FALSE;
4543 GST_LOG_OBJECT (demux, "pausing task, reason %s", reason);
4544 gst_pad_pause_task (demux->common.sinkpad);
4546 if (ret == GST_FLOW_EOS) {
4547 /* perform EOS logic */
4549 /* If we were in the headers, make sure we send no-more-pads.
4550 This will ensure decodebin2 does not get stuck thinking
4551 the chain is not complete yet, and waiting indefinitely. */
4552 if (G_UNLIKELY (demux->common.state == GST_MATROSKA_READ_STATE_HEADER)) {
4553 if (demux->common.src->len == 0) {
4554 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
4555 ("No pads created"));
4557 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL),
4558 ("Failed to finish reading headers"));
4560 gst_element_no_more_pads (GST_ELEMENT (demux));
4563 /* Close the segment, i.e. update segment stop with the duration
4564 * if no stop was set */
4565 if (GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) &&
4566 !GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop) &&
4567 GST_CLOCK_TIME_IS_VALID (demux->common.segment.start) &&
4568 demux->last_stop_end > demux->common.segment.start) {
4569 GstSegment segment = demux->common.segment;
4572 segment.stop = demux->last_stop_end;
4573 event = gst_event_new_segment (&segment);
4574 gst_matroska_demux_send_event (demux, event);
4577 if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
4580 /* for segment playback we need to post when (in stream time)
4581 * we stopped, this is either stop (when set) or the duration. */
4582 if ((stop = demux->common.segment.stop) == -1)
4583 stop = demux->last_stop_end;
4585 GST_LOG_OBJECT (demux, "Sending segment done, at end of segment");
4586 gst_element_post_message (GST_ELEMENT (demux),
4587 gst_message_new_segment_done (GST_OBJECT (demux), GST_FORMAT_TIME,
4592 } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS) {
4593 /* for fatal errors we post an error message */
4594 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
4595 ("stream stopped, reason %s", reason));
4599 /* send EOS, and prevent hanging if no streams yet */
4600 GST_LOG_OBJECT (demux, "Sending EOS, at end of stream");
4601 if (!gst_matroska_demux_send_event (demux, gst_event_new_eos ()) &&
4602 (ret == GST_FLOW_EOS)) {
4603 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4604 (NULL), ("got eos but no streams (yet)"));
4612 * Create and push a flushing seek event upstream
4615 perform_seek_to_offset (GstMatroskaDemux * demux, guint64 offset)
4620 GST_DEBUG_OBJECT (demux, "Seeking to %" G_GUINT64_FORMAT, offset);
4623 gst_event_new_seek (1.0, GST_FORMAT_BYTES,
4624 GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, GST_SEEK_TYPE_SET, offset,
4625 GST_SEEK_TYPE_NONE, -1);
4627 res = gst_pad_push_event (demux->common.sinkpad, event);
4629 /* segment event will update offset */
4633 static GstFlowReturn
4634 gst_matroska_demux_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
4636 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4638 GstFlowReturn ret = GST_FLOW_OK;
4643 if (G_UNLIKELY (GST_BUFFER_IS_DISCONT (buffer))) {
4644 GST_DEBUG_OBJECT (demux, "got DISCONT");
4645 gst_adapter_clear (demux->common.adapter);
4646 GST_OBJECT_LOCK (demux);
4647 gst_matroska_read_common_reset_streams (&demux->common,
4648 GST_CLOCK_TIME_NONE, FALSE);
4649 GST_OBJECT_UNLOCK (demux);
4652 gst_adapter_push (demux->common.adapter, buffer);
4656 available = gst_adapter_available (demux->common.adapter);
4658 ret = gst_matroska_read_common_peek_id_length_push (&demux->common,
4659 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4660 if (G_UNLIKELY (ret != GST_FLOW_OK && ret != GST_FLOW_EOS))
4663 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
4664 "size %" G_GUINT64_FORMAT ", needed %d, available %d",
4665 demux->common.offset, id, length, needed, available);
4667 if (needed > available)
4670 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4671 if (ret == GST_FLOW_EOS) {
4672 /* need more data */
4674 } else if (ret != GST_FLOW_OK) {
4681 gst_matroska_demux_handle_sink_event (GstPad * pad, GstObject * parent,
4684 gboolean res = TRUE;
4685 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4687 GST_DEBUG_OBJECT (demux,
4688 "have event type %s: %p on sink pad", GST_EVENT_TYPE_NAME (event), event);
4690 switch (GST_EVENT_TYPE (event)) {
4691 case GST_EVENT_SEGMENT:
4693 const GstSegment *segment;
4695 /* some debug output */
4696 gst_event_parse_segment (event, &segment);
4697 /* FIXME: do we need to update segment base here (like accum in 0.10)? */
4698 GST_DEBUG_OBJECT (demux,
4699 "received format %d segment %" GST_SEGMENT_FORMAT, segment->format,
4702 if (demux->common.state < GST_MATROSKA_READ_STATE_DATA) {
4703 GST_DEBUG_OBJECT (demux, "still starting");
4707 /* we only expect a BYTE segment, e.g. following a seek */
4708 if (segment->format != GST_FORMAT_BYTES) {
4709 GST_DEBUG_OBJECT (demux, "unsupported segment format, ignoring");
4713 GST_DEBUG_OBJECT (demux, "clearing segment state");
4714 GST_OBJECT_LOCK (demux);
4715 /* clear current segment leftover */
4716 gst_adapter_clear (demux->common.adapter);
4717 /* and some streaming setup */
4718 demux->common.offset = segment->start;
4719 /* do not know where we are;
4720 * need to come across a cluster and generate segment */
4721 demux->common.segment.position = GST_CLOCK_TIME_NONE;
4722 demux->cluster_time = GST_CLOCK_TIME_NONE;
4723 demux->cluster_offset = 0;
4724 demux->need_segment = TRUE;
4725 /* but keep some of the upstream segment */
4726 demux->common.segment.rate = segment->rate;
4727 GST_OBJECT_UNLOCK (demux);
4729 /* chain will send initial segment after pads have been added,
4730 * or otherwise come up with one */
4731 GST_DEBUG_OBJECT (demux, "eating event");
4732 gst_event_unref (event);
4738 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
4739 gst_event_unref (event);
4740 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4741 (NULL), ("got eos and didn't receive a complete header object"));
4742 } else if (demux->common.num_streams == 0) {
4743 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4744 (NULL), ("got eos but no streams (yet)"));
4746 gst_matroska_demux_send_event (demux, event);
4750 case GST_EVENT_FLUSH_STOP:
4754 gst_adapter_clear (demux->common.adapter);
4755 GST_OBJECT_LOCK (demux);
4756 gst_matroska_read_common_reset_streams (&demux->common,
4757 GST_CLOCK_TIME_NONE, TRUE);
4758 dur = demux->common.segment.duration;
4759 gst_segment_init (&demux->common.segment, GST_FORMAT_TIME);
4760 demux->common.segment.duration = dur;
4761 demux->cluster_time = GST_CLOCK_TIME_NONE;
4762 demux->cluster_offset = 0;
4763 GST_OBJECT_UNLOCK (demux);
4767 res = gst_pad_event_default (pad, parent, event);
4775 gst_matroska_demux_sink_activate (GstPad * sinkpad, GstObject * parent)
4777 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4779 gboolean pull_mode = FALSE;
4781 query = gst_query_new_scheduling ();
4783 if (gst_pad_peer_query (sinkpad, query))
4784 pull_mode = gst_query_has_scheduling_mode (query, GST_PAD_MODE_PULL);
4786 gst_query_unref (query);
4789 GST_DEBUG ("going to pull mode");
4790 demux->streaming = FALSE;
4791 return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PULL, TRUE);
4793 GST_DEBUG ("going to push (streaming) mode");
4794 demux->streaming = TRUE;
4795 return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PUSH, TRUE);
4800 gst_matroska_demux_sink_activate_mode (GstPad * sinkpad, GstObject * parent,
4801 GstPadMode mode, gboolean active)
4804 case GST_PAD_MODE_PULL:
4806 /* if we have a scheduler we can start the task */
4807 gst_pad_start_task (sinkpad, (GstTaskFunction) gst_matroska_demux_loop,
4810 gst_pad_stop_task (sinkpad);
4813 case GST_PAD_MODE_PUSH:
4821 gst_duration_to_fraction (guint64 duration, gint * dest_n, gint * dest_d)
4823 static const int common_den[] = { 1, 2, 3, 4, 1001 };
4828 for (i = 0; i < G_N_ELEMENTS (common_den); i++) {
4830 n = floor (0.5 + (d * 1e9) / duration);
4831 a = gst_util_uint64_scale_int (1000000000, d, n);
4832 if (duration >= a - 1 && duration <= a + 1) {
4837 gst_util_double_to_fraction (1e9 / duration, &n, &d);
4846 gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext *
4847 videocontext, const gchar * codec_id, guint8 * data, guint size,
4848 gchar ** codec_name, guint32 * riff_fourcc)
4850 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) videocontext;
4851 GstCaps *caps = NULL;
4853 g_assert (videocontext != NULL);
4854 g_assert (codec_name != NULL);
4856 context->send_xiph_headers = FALSE;
4857 context->send_flac_headers = FALSE;
4858 context->send_speex_headers = FALSE;
4863 /* TODO: check if we have all codec types from matroska-ids.h
4864 * check if we have to do more special things with codec_private
4867 * GST_MATROSKA_CODEC_ID_VIDEO_QUICKTIME
4868 * GST_MATROSKA_CODEC_ID_VIDEO_SNOW
4871 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VFW_FOURCC)) {
4872 gst_riff_strf_vids *vids = NULL;
4875 GstBuffer *buf = NULL;
4877 vids = (gst_riff_strf_vids *) data;
4879 /* assure size is big enough */
4881 GST_WARNING ("Too small BITMAPINFOHEADER (%d bytes)", size);
4884 if (size < sizeof (gst_riff_strf_vids)) {
4885 vids = g_new (gst_riff_strf_vids, 1);
4886 memcpy (vids, data, size);
4889 /* little-endian -> byte-order */
4890 vids->size = GUINT32_FROM_LE (vids->size);
4891 vids->width = GUINT32_FROM_LE (vids->width);
4892 vids->height = GUINT32_FROM_LE (vids->height);
4893 vids->planes = GUINT16_FROM_LE (vids->planes);
4894 vids->bit_cnt = GUINT16_FROM_LE (vids->bit_cnt);
4895 vids->compression = GUINT32_FROM_LE (vids->compression);
4896 vids->image_size = GUINT32_FROM_LE (vids->image_size);
4897 vids->xpels_meter = GUINT32_FROM_LE (vids->xpels_meter);
4898 vids->ypels_meter = GUINT32_FROM_LE (vids->ypels_meter);
4899 vids->num_colors = GUINT32_FROM_LE (vids->num_colors);
4900 vids->imp_colors = GUINT32_FROM_LE (vids->imp_colors);
4902 if (size > sizeof (gst_riff_strf_vids)) { /* some extra_data */
4903 gsize offset = sizeof (gst_riff_strf_vids);
4906 gst_buffer_new_wrapped (g_memdup ((guint8 *) vids + offset,
4907 size - offset), size - offset);
4911 *riff_fourcc = vids->compression;
4913 caps = gst_riff_create_video_caps (vids->compression, NULL, vids,
4914 buf, NULL, codec_name);
4917 GST_WARNING ("Unhandled RIFF fourcc %" GST_FOURCC_FORMAT,
4918 GST_FOURCC_ARGS (vids->compression));
4922 gst_buffer_unref (buf);
4924 if (vids != (gst_riff_strf_vids *) data)
4927 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_UNCOMPRESSED)) {
4928 const gchar *format = NULL;
4930 switch (videocontext->fourcc) {
4931 case GST_MAKE_FOURCC ('I', '4', '2', '0'):
4932 *codec_name = g_strdup ("Raw planar YUV 4:2:0");
4935 case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
4936 *codec_name = g_strdup ("Raw packed YUV 4:2:2");
4939 case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
4940 *codec_name = g_strdup ("Raw packed YUV 4:2:0");
4943 case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
4944 *codec_name = g_strdup ("Raw packed YUV 4:2:2");
4947 case GST_MAKE_FOURCC ('A', 'Y', 'U', 'V'):
4948 *codec_name = g_strdup ("Raw packed YUV 4:4:4 with alpha channel");
4953 GST_DEBUG ("Unknown fourcc %" GST_FOURCC_FORMAT,
4954 GST_FOURCC_ARGS (videocontext->fourcc));
4958 caps = gst_caps_new_simple ("video/x-raw",
4959 "format", G_TYPE_STRING, format, NULL);
4960 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_SP)) {
4961 caps = gst_caps_new_simple ("video/x-divx",
4962 "divxversion", G_TYPE_INT, 4, NULL);
4963 *codec_name = g_strdup ("MPEG-4 simple profile");
4964 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP) ||
4965 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AP)) {
4967 caps = gst_caps_new_full (gst_structure_new ("video/x-divx",
4968 "divxversion", G_TYPE_INT, 5, NULL),
4969 gst_structure_new ("video/x-xvid", NULL),
4970 gst_structure_new ("video/mpeg",
4971 "mpegversion", G_TYPE_INT, 4,
4972 "systemstream", G_TYPE_BOOLEAN, FALSE, NULL), NULL);
4974 caps = gst_caps_new_simple ("video/mpeg",
4975 "mpegversion", G_TYPE_INT, 4,
4976 "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
4980 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
4981 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
4982 gst_buffer_unref (priv);
4984 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP))
4985 *codec_name = g_strdup ("MPEG-4 advanced simple profile");
4987 *codec_name = g_strdup ("MPEG-4 advanced profile");
4988 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MSMPEG4V3)) {
4990 caps = gst_caps_new_full (gst_structure_new ("video/x-divx",
4991 "divxversion", G_TYPE_INT, 3, NULL),
4992 gst_structure_new ("video/x-msmpeg",
4993 "msmpegversion", G_TYPE_INT, 43, NULL), NULL);
4995 caps = gst_caps_new_simple ("video/x-msmpeg",
4996 "msmpegversion", G_TYPE_INT, 43, NULL);
4997 *codec_name = g_strdup ("Microsoft MPEG-4 v.3");
4998 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1) ||
4999 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG2)) {
5002 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1))
5007 caps = gst_caps_new_simple ("video/mpeg",
5008 "systemstream", G_TYPE_BOOLEAN, FALSE,
5009 "mpegversion", G_TYPE_INT, mpegversion, NULL);
5010 *codec_name = g_strdup_printf ("MPEG-%d video", mpegversion);
5011 context->postprocess_frame = gst_matroska_demux_add_mpeg_seq_header;
5012 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MJPEG)) {
5013 caps = gst_caps_new_empty_simple ("image/jpeg");
5014 *codec_name = g_strdup ("Motion-JPEG");
5015 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AVC)) {
5016 caps = gst_caps_new_empty_simple ("video/x-h264");
5020 /* First byte is the version, second is the profile indication, and third
5021 * is the 5 contraint_set_flags and 3 reserved bits. Fourth byte is the
5022 * level indication. */
5023 gst_codec_utils_h264_caps_set_level_and_profile (caps, data + 1,
5026 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
5027 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5028 gst_buffer_unref (priv);
5030 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "avc",
5031 "alignment", G_TYPE_STRING, "au", NULL);
5033 GST_WARNING ("No codec data found, assuming output is byte-stream");
5034 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
5037 *codec_name = g_strdup ("H264");
5038 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1)) ||
5039 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2)) ||
5040 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3)) ||
5041 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))) {
5042 gint rmversion = -1;
5044 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1))
5046 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2))
5048 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3))
5050 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))
5053 caps = gst_caps_new_simple ("video/x-pn-realvideo",
5054 "rmversion", G_TYPE_INT, rmversion, NULL);
5055 GST_DEBUG ("data:%p, size:0x%x", data, size);
5056 /* We need to extract the extradata ! */
5057 if (data && (size >= 0x22)) {
5062 subformat = GST_READ_UINT32_BE (data + 0x1a);
5063 rformat = GST_READ_UINT32_BE (data + 0x1e);
5066 gst_buffer_new_wrapped (g_memdup (data + 0x1a, size - 0x1a),
5068 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, "format",
5069 G_TYPE_INT, rformat, "subformat", G_TYPE_INT, subformat, NULL);
5070 gst_buffer_unref (priv);
5073 *codec_name = g_strdup_printf ("RealVideo %d.0", rmversion);
5074 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_THEORA)) {
5075 caps = gst_caps_new_empty_simple ("video/x-theora");
5076 context->send_xiph_headers = TRUE;
5077 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_DIRAC)) {
5078 caps = gst_caps_new_empty_simple ("video/x-dirac");
5079 *codec_name = g_strdup_printf ("Dirac");
5080 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8)) {
5081 caps = gst_caps_new_empty_simple ("video/x-vp8");
5082 *codec_name = g_strdup_printf ("On2 VP8");
5084 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
5090 GstStructure *structure;
5092 for (i = 0; i < gst_caps_get_size (caps); i++) {
5093 structure = gst_caps_get_structure (caps, i);
5095 /* FIXME: use the real unit here! */
5096 GST_DEBUG ("video size %dx%d, target display size %dx%d (any unit)",
5097 videocontext->pixel_width,
5098 videocontext->pixel_height,
5099 videocontext->display_width, videocontext->display_height);
5101 /* pixel width and height are the w and h of the video in pixels */
5102 if (videocontext->pixel_width > 0 && videocontext->pixel_height > 0) {
5103 gint w = videocontext->pixel_width;
5104 gint h = videocontext->pixel_height;
5106 gst_structure_set (structure,
5107 "width", G_TYPE_INT, w, "height", G_TYPE_INT, h, NULL);
5110 if (videocontext->display_width > 0 || videocontext->display_height > 0) {
5113 if (videocontext->display_width <= 0)
5114 videocontext->display_width = videocontext->pixel_width;
5115 if (videocontext->display_height <= 0)
5116 videocontext->display_height = videocontext->pixel_height;
5118 /* calculate the pixel aspect ratio using the display and pixel w/h */
5119 n = videocontext->display_width * videocontext->pixel_height;
5120 d = videocontext->display_height * videocontext->pixel_width;
5121 GST_DEBUG ("setting PAR to %d/%d", n, d);
5122 gst_structure_set (structure, "pixel-aspect-ratio",
5124 videocontext->display_width * videocontext->pixel_height,
5125 videocontext->display_height * videocontext->pixel_width, NULL);
5128 if (videocontext->default_fps > 0.0) {
5129 GValue fps_double = { 0, };
5130 GValue fps_fraction = { 0, };
5132 g_value_init (&fps_double, G_TYPE_DOUBLE);
5133 g_value_init (&fps_fraction, GST_TYPE_FRACTION);
5134 g_value_set_double (&fps_double, videocontext->default_fps);
5135 g_value_transform (&fps_double, &fps_fraction);
5137 GST_DEBUG ("using default fps %f", videocontext->default_fps);
5139 gst_structure_set_value (structure, "framerate", &fps_fraction);
5140 g_value_unset (&fps_double);
5141 g_value_unset (&fps_fraction);
5142 } else if (context->default_duration > 0) {
5145 gst_duration_to_fraction (context->default_duration, &fps_n, &fps_d);
5147 GST_INFO ("using default duration %" G_GUINT64_FORMAT
5148 " framerate %d/%d", context->default_duration, fps_n, fps_d);
5150 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
5151 fps_n, fps_d, NULL);
5153 /* sort of a hack to get most codecs to support,
5154 * even if the default_duration is missing */
5155 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
5159 if (videocontext->parent.flags & GST_MATROSKA_VIDEOTRACK_INTERLACED)
5160 gst_structure_set (structure, "interlaced", G_TYPE_BOOLEAN, TRUE, NULL);
5163 caps = gst_caps_simplify (caps);
5170 * Some AAC specific code... *sigh*
5171 * FIXME: maybe we should use '15' and code the sample rate explicitly
5172 * if the sample rate doesn't match the predefined rates exactly? (tpm)
5176 aac_rate_idx (gint rate)
5180 else if (75132 <= rate)
5182 else if (55426 <= rate)
5184 else if (46009 <= rate)
5186 else if (37566 <= rate)
5188 else if (27713 <= rate)
5190 else if (23004 <= rate)
5192 else if (18783 <= rate)
5194 else if (13856 <= rate)
5196 else if (11502 <= rate)
5198 else if (9391 <= rate)
5205 aac_profile_idx (const gchar * codec_id)
5209 if (strlen (codec_id) <= 12)
5211 else if (!strncmp (&codec_id[12], "MAIN", 4))
5213 else if (!strncmp (&codec_id[12], "LC", 2))
5215 else if (!strncmp (&codec_id[12], "SSR", 3))
5223 #define AAC_SYNC_EXTENSION_TYPE 0x02b7
5226 gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext *
5227 audiocontext, const gchar * codec_id, guint8 * data, guint size,
5228 gchar ** codec_name, guint16 * riff_audio_fmt)
5230 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) audiocontext;
5231 GstCaps *caps = NULL;
5233 g_assert (audiocontext != NULL);
5234 g_assert (codec_name != NULL);
5237 *riff_audio_fmt = 0;
5239 context->send_xiph_headers = FALSE;
5240 context->send_flac_headers = FALSE;
5241 context->send_speex_headers = FALSE;
5243 /* TODO: check if we have all codec types from matroska-ids.h
5244 * check if we have to do more special things with codec_private
5245 * check if we need bitdepth in different places too
5246 * implement channel position magic
5248 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID9
5249 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID10
5250 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDMC
5251 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDM2
5254 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1) ||
5255 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2) ||
5256 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L3)) {
5259 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1))
5261 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2))
5266 caps = gst_caps_new_simple ("audio/mpeg",
5267 "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, layer, NULL);
5268 *codec_name = g_strdup_printf ("MPEG-1 layer %d", layer);
5269 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE) ||
5270 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_LE)) {
5273 GstAudioFormat format;
5275 sign = (audiocontext->bitdepth != 8);
5276 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE))
5277 endianness = G_BIG_ENDIAN;
5279 endianness = G_LITTLE_ENDIAN;
5281 format = gst_audio_format_build_integer (sign, endianness,
5282 audiocontext->bitdepth, audiocontext->bitdepth);
5284 /* FIXME: Channel mask and reordering */
5285 caps = gst_caps_new_simple ("audio/x-raw",
5286 "format", G_TYPE_STRING, gst_audio_format_to_string (format),
5287 "layout", G_TYPE_STRING, "interleaved", NULL);
5289 *codec_name = g_strdup_printf ("Raw %d-bit PCM audio",
5290 audiocontext->bitdepth);
5291 context->alignment = audiocontext->bitdepth / 8;
5292 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_FLOAT)) {
5293 const gchar *format;
5294 if (audiocontext->bitdepth == 32)
5298 /* FIXME: Channel mask and reordering */
5299 caps = gst_caps_new_simple ("audio/x-raw",
5300 "format", G_TYPE_STRING, format,
5301 "layout", G_TYPE_STRING, "interleaved", NULL);
5302 *codec_name = g_strdup_printf ("Raw %d-bit floating-point audio",
5303 audiocontext->bitdepth);
5304 context->alignment = audiocontext->bitdepth / 8;
5305 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AC3,
5306 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AC3))) {
5307 caps = gst_caps_new_simple ("audio/x-ac3",
5308 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5309 *codec_name = g_strdup ("AC-3 audio");
5310 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_EAC3,
5311 strlen (GST_MATROSKA_CODEC_ID_AUDIO_EAC3))) {
5312 caps = gst_caps_new_simple ("audio/x-eac3",
5313 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5314 *codec_name = g_strdup ("E-AC-3 audio");
5315 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_DTS)) {
5316 caps = gst_caps_new_empty_simple ("audio/x-dts");
5317 *codec_name = g_strdup ("DTS audio");
5318 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_VORBIS)) {
5319 caps = gst_caps_new_empty_simple ("audio/x-vorbis");
5320 context->send_xiph_headers = TRUE;
5321 /* vorbis decoder does tags */
5322 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_FLAC)) {
5323 caps = gst_caps_new_empty_simple ("audio/x-flac");
5324 context->send_flac_headers = TRUE;
5325 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_SPEEX)) {
5326 caps = gst_caps_new_empty_simple ("audio/x-speex");
5327 context->send_speex_headers = TRUE;
5328 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_ACM)) {
5329 gst_riff_strf_auds auds;
5332 GstBuffer *codec_data;
5334 /* little-endian -> byte-order */
5335 auds.format = GST_READ_UINT16_LE (data);
5336 auds.channels = GST_READ_UINT16_LE (data + 2);
5337 auds.rate = GST_READ_UINT32_LE (data + 4);
5338 auds.av_bps = GST_READ_UINT32_LE (data + 8);
5339 auds.blockalign = GST_READ_UINT16_LE (data + 12);
5340 auds.size = GST_READ_UINT16_LE (data + 16);
5342 /* 18 is the waveformatex size */
5343 codec_data = gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY,
5344 data + 18, auds.size, 0, auds.size, NULL, NULL);
5347 *riff_audio_fmt = auds.format;
5349 /* FIXME: Handle reorder map */
5350 caps = gst_riff_create_audio_caps (auds.format, NULL, &auds, NULL,
5351 codec_data, codec_name, NULL);
5352 gst_buffer_unref (codec_data);
5355 GST_WARNING ("Unhandled RIFF audio format 0x%02x", auds.format);
5358 } else if (g_str_has_prefix (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC)) {
5359 GstBuffer *priv = NULL;
5361 gint rate_idx, profile;
5362 guint8 *data = NULL;
5364 /* unspecified AAC profile with opaque private codec data */
5365 if (strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC) == 0) {
5366 if (context->codec_priv_size >= 2) {
5367 guint obj_type, freq_index, explicit_freq_bytes = 0;
5369 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
5371 freq_index = (GST_READ_UINT16_BE (context->codec_priv) & 0x780) >> 7;
5372 obj_type = (GST_READ_UINT16_BE (context->codec_priv) & 0xF800) >> 11;
5373 if (freq_index == 15)
5374 explicit_freq_bytes = 3;
5375 GST_DEBUG ("obj_type = %u, freq_index = %u", obj_type, freq_index);
5376 priv = gst_buffer_new_wrapped (g_memdup (context->codec_priv,
5377 context->codec_priv_size), context->codec_priv_size);
5378 /* assume SBR if samplerate <= 24kHz */
5379 if (obj_type == 5 || (freq_index >= 6 && freq_index != 15) ||
5380 (context->codec_priv_size == (5 + explicit_freq_bytes))) {
5381 audiocontext->samplerate *= 2;
5384 GST_WARNING ("Opaque A_AAC codec ID, but no codec private data");
5385 /* this is pretty broken;
5386 * maybe we need to make up some default private,
5387 * or maybe ADTS data got dumped in.
5388 * Let's set up some private data now, and check actual data later */
5389 /* just try this and see what happens ... */
5390 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
5391 context->postprocess_frame = gst_matroska_demux_check_aac;
5395 /* make up decoder-specific data if it is not supplied */
5399 priv = gst_buffer_new_allocate (NULL, 5, NULL);
5400 gst_buffer_map (priv, &map, GST_MAP_WRITE);
5402 rate_idx = aac_rate_idx (audiocontext->samplerate);
5403 profile = aac_profile_idx (codec_id);
5405 data[0] = ((profile + 1) << 3) | ((rate_idx & 0xE) >> 1);
5406 data[1] = ((rate_idx & 0x1) << 7) | (audiocontext->channels << 3);
5408 if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2,
5409 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2))) {
5411 gst_buffer_unmap (priv, &map);
5412 gst_buffer_set_size (priv, 2);
5413 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4,
5414 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4))) {
5417 if (g_strrstr (codec_id, "SBR")) {
5418 /* HE-AAC (aka SBR AAC) */
5419 audiocontext->samplerate *= 2;
5420 rate_idx = aac_rate_idx (audiocontext->samplerate);
5421 data[2] = AAC_SYNC_EXTENSION_TYPE >> 3;
5422 data[3] = ((AAC_SYNC_EXTENSION_TYPE & 0x07) << 5) | 5;
5423 data[4] = (1 << 7) | (rate_idx << 3);
5424 gst_buffer_unmap (priv, &map);
5426 gst_buffer_unmap (priv, &map);
5427 gst_buffer_set_size (priv, 2);
5430 gst_buffer_unmap (priv, &map);
5431 gst_buffer_unref (priv);
5433 GST_ERROR ("Unknown AAC profile and no codec private data");
5438 caps = gst_caps_new_simple ("audio/mpeg",
5439 "mpegversion", G_TYPE_INT, mpegversion,
5440 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5441 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5442 *codec_name = g_strdup_printf ("MPEG-%d AAC audio", mpegversion);
5443 gst_buffer_unref (priv);
5445 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TTA)) {
5446 caps = gst_caps_new_simple ("audio/x-tta",
5447 "width", G_TYPE_INT, audiocontext->bitdepth, NULL);
5448 *codec_name = g_strdup ("TTA audio");
5449 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_WAVPACK4)) {
5450 caps = gst_caps_new_simple ("audio/x-wavpack",
5451 "width", G_TYPE_INT, audiocontext->bitdepth,
5452 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5453 *codec_name = g_strdup ("Wavpack audio");
5454 context->postprocess_frame = gst_matroska_demux_add_wvpk_header;
5455 audiocontext->wvpk_block_index = 0;
5456 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4)) ||
5457 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4)) ||
5458 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))) {
5459 gint raversion = -1;
5461 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4))
5463 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))
5468 caps = gst_caps_new_simple ("audio/x-pn-realaudio",
5469 "raversion", G_TYPE_INT, raversion, NULL);
5470 /* Extract extra information from caps, mapping varies based on codec */
5471 if (data && (size >= 0x50)) {
5478 guint extra_data_size;
5480 GST_ERROR ("real audio raversion:%d", raversion);
5481 if (raversion == 8) {
5483 flavor = GST_READ_UINT16_BE (data + 22);
5484 packet_size = GST_READ_UINT32_BE (data + 24);
5485 height = GST_READ_UINT16_BE (data + 40);
5486 leaf_size = GST_READ_UINT16_BE (data + 44);
5487 sample_width = GST_READ_UINT16_BE (data + 58);
5488 extra_data_size = GST_READ_UINT32_BE (data + 74);
5491 ("flavor:%d, packet_size:%d, height:%d, leaf_size:%d, sample_width:%d, extra_data_size:%d",
5492 flavor, packet_size, height, leaf_size, sample_width,
5494 gst_caps_set_simple (caps, "flavor", G_TYPE_INT, flavor, "packet_size",
5495 G_TYPE_INT, packet_size, "height", G_TYPE_INT, height, "leaf_size",
5496 G_TYPE_INT, leaf_size, "width", G_TYPE_INT, sample_width, NULL);
5498 if ((size - 78) >= extra_data_size) {
5499 priv = gst_buffer_new_wrapped (g_memdup (data + 78, extra_data_size),
5501 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5502 gst_buffer_unref (priv);
5507 *codec_name = g_strdup_printf ("RealAudio %d.0", raversion);
5508 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_SIPR)) {
5509 caps = gst_caps_new_empty_simple ("audio/x-sipro");
5510 *codec_name = g_strdup ("Sipro/ACELP.NET Voice Codec");
5511 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_RALF)) {
5512 caps = gst_caps_new_empty_simple ("audio/x-ralf-mpeg4-generic");
5513 *codec_name = g_strdup ("Real Audio Lossless");
5514 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_ATRC)) {
5515 caps = gst_caps_new_empty_simple ("audio/x-vnd.sony.atrac3");
5516 *codec_name = g_strdup ("Sony ATRAC3");
5518 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
5523 if (audiocontext->samplerate > 0 && audiocontext->channels > 0) {
5526 for (i = 0; i < gst_caps_get_size (caps); i++) {
5527 gst_structure_set (gst_caps_get_structure (caps, i),
5528 "channels", G_TYPE_INT, audiocontext->channels,
5529 "rate", G_TYPE_INT, audiocontext->samplerate, NULL);
5533 caps = gst_caps_simplify (caps);
5540 gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
5541 subtitlecontext, const gchar * codec_id, gpointer data, guint size)
5543 GstCaps *caps = NULL;
5544 GstMatroskaTrackContext *context =
5545 (GstMatroskaTrackContext *) subtitlecontext;
5547 /* for backwards compatibility */
5548 if (!g_ascii_strcasecmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASCII))
5549 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8;
5550 else if (!g_ascii_strcasecmp (codec_id, "S_SSA"))
5551 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_SSA;
5552 else if (!g_ascii_strcasecmp (codec_id, "S_ASS"))
5553 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_ASS;
5554 else if (!g_ascii_strcasecmp (codec_id, "S_USF"))
5555 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_USF;
5557 /* TODO: Add GST_MATROSKA_CODEC_ID_SUBTITLE_BMP support
5558 * Check if we have to do something with codec_private */
5559 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8)) {
5560 /* well, plain text simply does not have a lot of markup ... */
5561 caps = gst_caps_new_empty_simple ("text/x-pango-markup");
5562 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5563 subtitlecontext->check_markup = TRUE;
5564 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_SSA)) {
5565 caps = gst_caps_new_empty_simple ("application/x-ssa");
5566 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5567 subtitlecontext->check_markup = FALSE;
5568 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASS)) {
5569 caps = gst_caps_new_empty_simple ("application/x-ass");
5570 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5571 subtitlecontext->check_markup = FALSE;
5572 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_USF)) {
5573 caps = gst_caps_new_empty_simple ("application/x-usf");
5574 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5575 subtitlecontext->check_markup = FALSE;
5576 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB)) {
5577 caps = gst_caps_new_empty_simple ("video/x-dvd-subpicture");
5578 ((GstMatroskaTrackContext *) subtitlecontext)->send_dvd_event = TRUE;
5579 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_HDMVPGS)) {
5580 caps = gst_caps_new_empty_simple ("subpicture/x-pgs");
5581 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_KATE)) {
5582 caps = gst_caps_new_empty_simple ("subtitle/x-kate");
5583 context->send_xiph_headers = TRUE;
5585 GST_DEBUG ("Unknown subtitle stream: codec_id='%s'", codec_id);
5586 caps = gst_caps_new_empty_simple ("application/x-subtitle-unknown");
5589 if (data != NULL && size > 0) {
5592 buf = gst_buffer_new_wrapped (g_memdup (data, size), size);
5593 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, buf, NULL);
5594 gst_buffer_unref (buf);
5602 gst_matroska_demux_set_index (GstElement * element, GstIndex * index)
5604 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5606 GST_OBJECT_LOCK (demux);
5607 if (demux->common.element_index)
5608 gst_object_unref (demux->common.element_index);
5609 demux->common.element_index = index ? gst_object_ref (index) : NULL;
5610 GST_OBJECT_UNLOCK (demux);
5611 GST_DEBUG_OBJECT (demux, "Set index %" GST_PTR_FORMAT,
5612 demux->common.element_index);
5616 gst_matroska_demux_get_index (GstElement * element)
5618 GstIndex *result = NULL;
5619 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5621 GST_OBJECT_LOCK (demux);
5622 if (demux->common.element_index)
5623 result = gst_object_ref (demux->common.element_index);
5624 GST_OBJECT_UNLOCK (demux);
5626 GST_DEBUG_OBJECT (demux, "Returning index %" GST_PTR_FORMAT, result);
5632 static GstStateChangeReturn
5633 gst_matroska_demux_change_state (GstElement * element,
5634 GstStateChange transition)
5636 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5637 GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
5639 /* handle upwards state changes here */
5640 switch (transition) {
5645 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
5647 /* handle downwards state changes */
5648 switch (transition) {
5649 case GST_STATE_CHANGE_PAUSED_TO_READY:
5650 gst_matroska_demux_reset (GST_ELEMENT (demux));
5660 gst_matroska_demux_set_property (GObject * object,
5661 guint prop_id, const GValue * value, GParamSpec * pspec)
5663 GstMatroskaDemux *demux;
5665 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
5666 demux = GST_MATROSKA_DEMUX (object);
5669 case ARG_MAX_GAP_TIME:
5670 GST_OBJECT_LOCK (demux);
5671 demux->max_gap_time = g_value_get_uint64 (value);
5672 GST_OBJECT_UNLOCK (demux);
5675 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
5681 gst_matroska_demux_get_property (GObject * object,
5682 guint prop_id, GValue * value, GParamSpec * pspec)
5684 GstMatroskaDemux *demux;
5686 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
5687 demux = GST_MATROSKA_DEMUX (object);
5690 case ARG_MAX_GAP_TIME:
5691 GST_OBJECT_LOCK (demux);
5692 g_value_set_uint64 (value, demux->max_gap_time);
5693 GST_OBJECT_UNLOCK (demux);
5696 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
5702 gst_matroska_demux_plugin_init (GstPlugin * plugin)
5706 /* parser helper separate debug */
5707 GST_DEBUG_CATEGORY_INIT (ebmlread_debug, "ebmlread",
5708 0, "EBML stream helper class");
5710 /* create an elementfactory for the matroska_demux element */
5711 if (!gst_element_register (plugin, "matroskademux",
5712 GST_RANK_PRIMARY, GST_TYPE_MATROSKA_DEMUX))