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., 51 Franklin St, Fifth Floor,
22 * Boston, MA 02110-1301, 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-1.0 -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>
65 #include <gst/video/video.h>
67 #include "matroska-demux.h"
68 #include "matroska-ids.h"
70 GST_DEBUG_CATEGORY_STATIC (matroskademux_debug);
71 #define GST_CAT_DEFAULT matroskademux_debug
73 #define DEBUG_ELEMENT_START(demux, ebml, element) \
74 GST_DEBUG_OBJECT (demux, "Parsing " element " element at offset %" \
75 G_GUINT64_FORMAT, gst_ebml_read_get_pos (ebml))
77 #define DEBUG_ELEMENT_STOP(demux, ebml, element, ret) \
78 GST_DEBUG_OBJECT (demux, "Parsing " element " element " \
79 " finished with '%s'", gst_flow_get_name (ret))
89 #define DEFAULT_MAX_GAP_TIME (2 * GST_SECOND)
91 static GstStaticPadTemplate sink_templ = GST_STATIC_PAD_TEMPLATE ("sink",
94 GST_STATIC_CAPS ("audio/x-matroska; video/x-matroska; "
95 "video/x-matroska-3d; audio/webm; video/webm")
98 /* TODO: fill in caps! */
100 static GstStaticPadTemplate audio_src_templ =
101 GST_STATIC_PAD_TEMPLATE ("audio_%u",
104 GST_STATIC_CAPS ("ANY")
107 static GstStaticPadTemplate video_src_templ =
108 GST_STATIC_PAD_TEMPLATE ("video_%u",
111 GST_STATIC_CAPS ("ANY")
114 static GstStaticPadTemplate subtitle_src_templ =
115 GST_STATIC_PAD_TEMPLATE ("subtitle_%u",
118 GST_STATIC_CAPS ("text/x-raw, format=pango-markup; application/x-ssa; "
119 "application/x-ass;application/x-usf; subpicture/x-dvd; "
120 "subpicture/x-pgs; subtitle/x-kate; " "application/x-subtitle-unknown")
123 static GstFlowReturn gst_matroska_demux_parse_id (GstMatroskaDemux * demux,
124 guint32 id, guint64 length, guint needed);
126 /* element functions */
127 static void gst_matroska_demux_loop (GstPad * pad);
129 static gboolean gst_matroska_demux_element_send_event (GstElement * element,
131 static gboolean gst_matroska_demux_element_query (GstElement * element,
135 static gboolean gst_matroska_demux_sink_activate (GstPad * sinkpad,
137 static gboolean gst_matroska_demux_sink_activate_mode (GstPad * sinkpad,
138 GstObject * parent, GstPadMode mode, gboolean active);
140 static gboolean gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
141 GstPad * pad, GstEvent * event);
142 static gboolean gst_matroska_demux_handle_src_event (GstPad * pad,
143 GstObject * parent, GstEvent * event);
144 static gboolean gst_matroska_demux_handle_src_query (GstPad * pad,
145 GstObject * parent, GstQuery * query);
147 static gboolean gst_matroska_demux_handle_sink_event (GstPad * pad,
148 GstObject * parent, GstEvent * event);
149 static GstFlowReturn gst_matroska_demux_chain (GstPad * pad,
150 GstObject * object, GstBuffer * buffer);
152 static GstStateChangeReturn
153 gst_matroska_demux_change_state (GstElement * element,
154 GstStateChange transition);
157 gst_matroska_demux_set_index (GstElement * element, GstIndex * index);
158 static GstIndex *gst_matroska_demux_get_index (GstElement * element);
162 static GstCaps *gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext
163 * videocontext, const gchar * codec_id, guint8 * data, guint size,
164 gchar ** codec_name, guint32 * riff_fourcc);
165 static GstCaps *gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext
166 * audiocontext, const gchar * codec_id, guint8 * data, guint size,
167 gchar ** codec_name, guint16 * riff_audio_fmt);
169 * gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
170 subtitlecontext, const gchar * codec_id, gpointer data, guint size);
173 static void gst_matroska_demux_reset (GstElement * element);
174 static gboolean perform_seek_to_offset (GstMatroskaDemux * demux,
175 gdouble rate, guint64 offset, guint32 seqnum);
177 /* gobject functions */
178 static void gst_matroska_demux_set_property (GObject * object,
179 guint prop_id, const GValue * value, GParamSpec * pspec);
180 static void gst_matroska_demux_get_property (GObject * object,
181 guint prop_id, GValue * value, GParamSpec * pspec);
183 GType gst_matroska_demux_get_type (void);
184 #define parent_class gst_matroska_demux_parent_class
185 G_DEFINE_TYPE (GstMatroskaDemux, gst_matroska_demux, GST_TYPE_ELEMENT);
188 gst_matroska_demux_finalize (GObject * object)
190 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (object);
192 gst_matroska_read_common_finalize (&demux->common);
193 gst_flow_combiner_free (demux->flowcombiner);
194 G_OBJECT_CLASS (parent_class)->finalize (object);
198 gst_matroska_demux_class_init (GstMatroskaDemuxClass * klass)
200 GObjectClass *gobject_class = (GObjectClass *) klass;
201 GstElementClass *gstelement_class = (GstElementClass *) klass;
203 GST_DEBUG_CATEGORY_INIT (matroskademux_debug, "matroskademux", 0,
206 gobject_class->finalize = gst_matroska_demux_finalize;
208 gobject_class->get_property = gst_matroska_demux_get_property;
209 gobject_class->set_property = gst_matroska_demux_set_property;
211 g_object_class_install_property (gobject_class, ARG_MAX_GAP_TIME,
212 g_param_spec_uint64 ("max-gap-time", "Maximum gap time",
213 "The demuxer sends out segment events for skipping "
214 "gaps longer than this (0 = disabled).", 0, G_MAXUINT64,
215 DEFAULT_MAX_GAP_TIME, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
217 gstelement_class->change_state =
218 GST_DEBUG_FUNCPTR (gst_matroska_demux_change_state);
219 gstelement_class->send_event =
220 GST_DEBUG_FUNCPTR (gst_matroska_demux_element_send_event);
221 gstelement_class->query =
222 GST_DEBUG_FUNCPTR (gst_matroska_demux_element_query);
224 gstelement_class->set_index =
225 GST_DEBUG_FUNCPTR (gst_matroska_demux_set_index);
226 gstelement_class->get_index =
227 GST_DEBUG_FUNCPTR (gst_matroska_demux_get_index);
230 gst_element_class_add_pad_template (gstelement_class,
231 gst_static_pad_template_get (&video_src_templ));
232 gst_element_class_add_pad_template (gstelement_class,
233 gst_static_pad_template_get (&audio_src_templ));
234 gst_element_class_add_pad_template (gstelement_class,
235 gst_static_pad_template_get (&subtitle_src_templ));
236 gst_element_class_add_pad_template (gstelement_class,
237 gst_static_pad_template_get (&sink_templ));
239 gst_element_class_set_static_metadata (gstelement_class, "Matroska demuxer",
241 "Demuxes Matroska/WebM streams into video/audio/subtitles",
242 "GStreamer maintainers <gstreamer-devel@lists.sourceforge.net>");
246 gst_matroska_demux_init (GstMatroskaDemux * demux)
248 demux->common.sinkpad = gst_pad_new_from_static_template (&sink_templ,
250 gst_pad_set_activate_function (demux->common.sinkpad,
251 GST_DEBUG_FUNCPTR (gst_matroska_demux_sink_activate));
252 gst_pad_set_activatemode_function (demux->common.sinkpad,
253 GST_DEBUG_FUNCPTR (gst_matroska_demux_sink_activate_mode));
254 gst_pad_set_chain_function (demux->common.sinkpad,
255 GST_DEBUG_FUNCPTR (gst_matroska_demux_chain));
256 gst_pad_set_event_function (demux->common.sinkpad,
257 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_sink_event));
258 gst_element_add_pad (GST_ELEMENT (demux), demux->common.sinkpad);
260 /* init defaults for common read context */
261 gst_matroska_read_common_init (&demux->common);
263 /* property defaults */
264 demux->max_gap_time = DEFAULT_MAX_GAP_TIME;
266 GST_OBJECT_FLAG_SET (demux, GST_ELEMENT_FLAG_INDEXABLE);
268 demux->flowcombiner = gst_flow_combiner_new ();
271 gst_matroska_demux_reset (GST_ELEMENT (demux));
275 gst_matroska_demux_reset (GstElement * element)
277 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
279 GST_DEBUG_OBJECT (demux, "Resetting state");
281 gst_matroska_read_common_reset (GST_ELEMENT (demux), &demux->common);
283 demux->num_a_streams = 0;
284 demux->num_t_streams = 0;
285 demux->num_v_streams = 0;
287 demux->have_group_id = FALSE;
288 demux->group_id = G_MAXUINT;
291 demux->tracks_parsed = FALSE;
293 if (demux->clusters) {
294 g_array_free (demux->clusters, TRUE);
295 demux->clusters = NULL;
298 g_list_foreach (demux->seek_parsed,
299 (GFunc) gst_matroska_read_common_free_parsed_el, NULL);
300 g_list_free (demux->seek_parsed);
301 demux->seek_parsed = NULL;
303 demux->last_stop_end = GST_CLOCK_TIME_NONE;
304 demux->seek_block = 0;
305 demux->stream_start_time = GST_CLOCK_TIME_NONE;
306 demux->to_time = GST_CLOCK_TIME_NONE;
307 demux->cluster_time = GST_CLOCK_TIME_NONE;
308 demux->cluster_offset = 0;
309 demux->next_cluster_offset = 0;
310 demux->index_offset = 0;
311 demux->seekable = FALSE;
312 demux->need_segment = FALSE;
313 demux->segment_seqnum = 0;
314 demux->requested_seek_time = GST_CLOCK_TIME_NONE;
315 demux->seek_offset = -1;
316 demux->building_index = FALSE;
317 if (demux->seek_event) {
318 gst_event_unref (demux->seek_event);
319 demux->seek_event = NULL;
322 demux->seek_index = NULL;
323 demux->seek_entry = 0;
325 if (demux->new_segment) {
326 gst_event_unref (demux->new_segment);
327 demux->new_segment = NULL;
330 demux->invalid_duration = FALSE;
332 gst_flow_combiner_clear (demux->flowcombiner);
336 gst_matroska_decode_buffer (GstMatroskaTrackContext * context, GstBuffer * buf)
342 g_return_val_if_fail (GST_IS_BUFFER (buf), NULL);
344 GST_DEBUG ("decoding buffer %p", buf);
346 gst_buffer_map (buf, &map, GST_MAP_READ);
350 g_return_val_if_fail (size > 0, buf);
352 if (gst_matroska_decode_data (context->encodings, &data, &size,
353 GST_MATROSKA_TRACK_ENCODING_SCOPE_FRAME, FALSE)) {
354 gst_buffer_unmap (buf, &map);
355 gst_buffer_unref (buf);
356 return gst_buffer_new_wrapped (data, size);
358 GST_DEBUG ("decode data failed");
359 gst_buffer_unmap (buf, &map);
360 gst_buffer_unref (buf);
366 gst_matroska_demux_add_stream_headers_to_caps (GstMatroskaDemux * demux,
367 GstBufferList * list, GstCaps * caps)
370 GValue arr_val = G_VALUE_INIT;
371 GValue buf_val = G_VALUE_INIT;
374 g_assert (gst_caps_is_writable (caps));
376 g_value_init (&arr_val, GST_TYPE_ARRAY);
377 g_value_init (&buf_val, GST_TYPE_BUFFER);
379 num = gst_buffer_list_length (list);
380 for (i = 0; i < num; ++i) {
381 g_value_set_boxed (&buf_val, gst_buffer_list_get (list, i));
382 gst_value_array_append_value (&arr_val, &buf_val);
385 s = gst_caps_get_structure (caps, 0);
386 gst_structure_take_value (s, "streamheader", &arr_val);
387 g_value_unset (&buf_val);
391 gst_matroska_demux_add_stream (GstMatroskaDemux * demux, GstEbmlRead * ebml)
393 GstElementClass *klass = GST_ELEMENT_GET_CLASS (demux);
394 GstMatroskaTrackContext *context;
395 GstPadTemplate *templ = NULL;
396 GstStreamFlags stream_flags;
397 GstCaps *caps = NULL;
398 gchar *padname = NULL;
400 guint32 id, riff_fourcc = 0;
401 guint16 riff_audio_fmt = 0;
402 GstTagList *list = NULL;
403 GstEvent *stream_start;
407 DEBUG_ELEMENT_START (demux, ebml, "TrackEntry");
409 /* start with the master */
410 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
411 DEBUG_ELEMENT_STOP (demux, ebml, "TrackEntry", ret);
415 /* allocate generic... if we know the type, we'll g_renew()
416 * with the precise type */
417 context = g_new0 (GstMatroskaTrackContext, 1);
418 g_ptr_array_add (demux->common.src, context);
419 context->index = demux->common.num_streams;
420 context->index_writer_id = -1;
421 context->type = 0; /* no type yet */
422 context->default_duration = 0;
424 context->set_discont = TRUE;
425 context->timecodescale = 1.0;
427 GST_MATROSKA_TRACK_ENABLED | GST_MATROSKA_TRACK_DEFAULT |
428 GST_MATROSKA_TRACK_LACING;
429 context->from_time = GST_CLOCK_TIME_NONE;
430 context->from_offset = -1;
431 context->to_offset = G_MAXINT64;
432 context->alignment = 1;
433 demux->common.num_streams++;
434 g_assert (demux->common.src->len == demux->common.num_streams);
436 GST_DEBUG_OBJECT (demux, "Stream number %d", context->index);
438 /* try reading the trackentry headers */
439 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
440 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
444 /* track number (unique stream ID) */
445 case GST_MATROSKA_ID_TRACKNUMBER:{
448 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
452 GST_ERROR_OBJECT (demux, "Invalid TrackNumber 0");
453 ret = GST_FLOW_ERROR;
455 } else if (!gst_matroska_read_common_tracknumber_unique (&demux->common,
457 GST_ERROR_OBJECT (demux, "TrackNumber %" G_GUINT64_FORMAT
458 " is not unique", num);
459 ret = GST_FLOW_ERROR;
463 GST_DEBUG_OBJECT (demux, "TrackNumber: %" G_GUINT64_FORMAT, num);
467 /* track UID (unique identifier) */
468 case GST_MATROSKA_ID_TRACKUID:{
471 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
475 GST_ERROR_OBJECT (demux, "Invalid TrackUID 0");
476 ret = GST_FLOW_ERROR;
480 GST_DEBUG_OBJECT (demux, "TrackUID: %" G_GUINT64_FORMAT, num);
485 /* track type (video, audio, combined, subtitle, etc.) */
486 case GST_MATROSKA_ID_TRACKTYPE:{
489 if ((ret = gst_ebml_read_uint (ebml, &id, &track_type)) != GST_FLOW_OK) {
493 if (context->type != 0 && context->type != track_type) {
494 GST_WARNING_OBJECT (demux,
495 "More than one tracktype defined in a TrackEntry - skipping");
497 } else if (track_type < 1 || track_type > 254) {
498 GST_WARNING_OBJECT (demux, "Invalid TrackType %" G_GUINT64_FORMAT,
503 GST_DEBUG_OBJECT (demux, "TrackType: %" G_GUINT64_FORMAT, track_type);
505 /* ok, so we're actually going to reallocate this thing */
506 switch (track_type) {
507 case GST_MATROSKA_TRACK_TYPE_VIDEO:
508 gst_matroska_track_init_video_context (&context);
510 case GST_MATROSKA_TRACK_TYPE_AUDIO:
511 gst_matroska_track_init_audio_context (&context);
513 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
514 gst_matroska_track_init_subtitle_context (&context);
516 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
517 case GST_MATROSKA_TRACK_TYPE_LOGO:
518 case GST_MATROSKA_TRACK_TYPE_BUTTONS:
519 case GST_MATROSKA_TRACK_TYPE_CONTROL:
521 GST_WARNING_OBJECT (demux,
522 "Unknown or unsupported TrackType %" G_GUINT64_FORMAT,
527 g_ptr_array_index (demux->common.src, demux->common.num_streams - 1)
532 /* tracktype specific stuff for video */
533 case GST_MATROSKA_ID_TRACKVIDEO:{
534 GstMatroskaTrackVideoContext *videocontext;
536 DEBUG_ELEMENT_START (demux, ebml, "TrackVideo");
538 if (!gst_matroska_track_init_video_context (&context)) {
539 GST_WARNING_OBJECT (demux,
540 "TrackVideo element in non-video track - ignoring track");
541 ret = GST_FLOW_ERROR;
543 } else if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
546 videocontext = (GstMatroskaTrackVideoContext *) context;
547 g_ptr_array_index (demux->common.src, demux->common.num_streams - 1)
550 while (ret == GST_FLOW_OK &&
551 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
552 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
556 /* Should be one level up but some broken muxers write it here. */
557 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
560 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
564 GST_WARNING_OBJECT (demux, "Invalid TrackDefaultDuration 0");
568 GST_DEBUG_OBJECT (demux,
569 "TrackDefaultDuration: %" G_GUINT64_FORMAT, num);
570 context->default_duration = num;
574 /* video framerate */
575 /* NOTE: This one is here only for backward compatibility.
576 * Use _TRACKDEFAULDURATION one level up. */
577 case GST_MATROSKA_ID_VIDEOFRAMERATE:{
580 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
584 GST_WARNING_OBJECT (demux, "Invalid TrackVideoFPS %lf", num);
588 GST_DEBUG_OBJECT (demux, "TrackVideoFrameRate: %lf", num);
589 if (context->default_duration == 0)
590 context->default_duration =
591 gst_gdouble_to_guint64 ((gdouble) GST_SECOND * (1.0 / num));
592 videocontext->default_fps = num;
596 /* width of the size to display the video at */
597 case GST_MATROSKA_ID_VIDEODISPLAYWIDTH:{
600 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
604 GST_WARNING_OBJECT (demux, "Invalid TrackVideoDisplayWidth 0");
608 GST_DEBUG_OBJECT (demux,
609 "TrackVideoDisplayWidth: %" G_GUINT64_FORMAT, num);
610 videocontext->display_width = num;
614 /* height of the size to display the video at */
615 case GST_MATROSKA_ID_VIDEODISPLAYHEIGHT:{
618 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
622 GST_WARNING_OBJECT (demux, "Invalid TrackVideoDisplayHeight 0");
626 GST_DEBUG_OBJECT (demux,
627 "TrackVideoDisplayHeight: %" G_GUINT64_FORMAT, num);
628 videocontext->display_height = num;
632 /* width of the video in the file */
633 case GST_MATROSKA_ID_VIDEOPIXELWIDTH:{
636 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
640 GST_WARNING_OBJECT (demux, "Invalid TrackVideoPixelWidth 0");
644 GST_DEBUG_OBJECT (demux,
645 "TrackVideoPixelWidth: %" G_GUINT64_FORMAT, num);
646 videocontext->pixel_width = num;
650 /* height of the video in the file */
651 case GST_MATROSKA_ID_VIDEOPIXELHEIGHT:{
654 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
658 GST_WARNING_OBJECT (demux, "Invalid TrackVideoPixelHeight 0");
662 GST_DEBUG_OBJECT (demux,
663 "TrackVideoPixelHeight: %" G_GUINT64_FORMAT, num);
664 videocontext->pixel_height = num;
668 /* whether the video is interlaced */
669 case GST_MATROSKA_ID_VIDEOFLAGINTERLACED:{
672 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
676 context->flags |= GST_MATROSKA_VIDEOTRACK_INTERLACED;
678 context->flags &= ~GST_MATROSKA_VIDEOTRACK_INTERLACED;
679 GST_DEBUG_OBJECT (demux, "TrackVideoInterlaced: %d",
680 (context->flags & GST_MATROSKA_VIDEOTRACK_INTERLACED) ? 1 :
685 /* aspect ratio behaviour */
686 case GST_MATROSKA_ID_VIDEOASPECTRATIOTYPE:{
689 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
692 if (num != GST_MATROSKA_ASPECT_RATIO_MODE_FREE &&
693 num != GST_MATROSKA_ASPECT_RATIO_MODE_KEEP &&
694 num != GST_MATROSKA_ASPECT_RATIO_MODE_FIXED) {
695 GST_WARNING_OBJECT (demux,
696 "Unknown TrackVideoAspectRatioType 0x%x", (guint) num);
699 GST_DEBUG_OBJECT (demux,
700 "TrackVideoAspectRatioType: %" G_GUINT64_FORMAT, num);
701 videocontext->asr_mode = num;
705 /* colourspace (only matters for raw video) fourcc */
706 case GST_MATROSKA_ID_VIDEOCOLOURSPACE:{
711 gst_ebml_read_binary (ebml, &id, &data,
712 &datalen)) != GST_FLOW_OK)
717 GST_WARNING_OBJECT (demux,
718 "Invalid TrackVideoColourSpace length %" G_GUINT64_FORMAT,
723 memcpy (&videocontext->fourcc, data, 4);
724 GST_DEBUG_OBJECT (demux,
725 "TrackVideoColourSpace: %" GST_FOURCC_FORMAT,
726 GST_FOURCC_ARGS (videocontext->fourcc));
732 GST_WARNING_OBJECT (demux,
733 "Unknown TrackVideo subelement 0x%x - ignoring", id);
735 case GST_MATROSKA_ID_VIDEOSTEREOMODE:
736 case GST_MATROSKA_ID_VIDEODISPLAYUNIT:
737 case GST_MATROSKA_ID_VIDEOPIXELCROPBOTTOM:
738 case GST_MATROSKA_ID_VIDEOPIXELCROPTOP:
739 case GST_MATROSKA_ID_VIDEOPIXELCROPLEFT:
740 case GST_MATROSKA_ID_VIDEOPIXELCROPRIGHT:
741 case GST_MATROSKA_ID_VIDEOGAMMAVALUE:
742 ret = gst_ebml_read_skip (ebml);
747 DEBUG_ELEMENT_STOP (demux, ebml, "TrackVideo", ret);
751 /* tracktype specific stuff for audio */
752 case GST_MATROSKA_ID_TRACKAUDIO:{
753 GstMatroskaTrackAudioContext *audiocontext;
755 DEBUG_ELEMENT_START (demux, ebml, "TrackAudio");
757 if (!gst_matroska_track_init_audio_context (&context)) {
758 GST_WARNING_OBJECT (demux,
759 "TrackAudio element in non-audio track - ignoring track");
760 ret = GST_FLOW_ERROR;
764 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
767 audiocontext = (GstMatroskaTrackAudioContext *) context;
768 g_ptr_array_index (demux->common.src, demux->common.num_streams - 1)
771 while (ret == GST_FLOW_OK &&
772 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
773 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
778 case GST_MATROSKA_ID_AUDIOSAMPLINGFREQ:{
781 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
786 GST_WARNING_OBJECT (demux,
787 "Invalid TrackAudioSamplingFrequency %lf", num);
791 GST_DEBUG_OBJECT (demux, "TrackAudioSamplingFrequency: %lf", num);
792 audiocontext->samplerate = num;
797 case GST_MATROSKA_ID_AUDIOBITDEPTH:{
800 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
804 GST_WARNING_OBJECT (demux, "Invalid TrackAudioBitDepth 0");
808 GST_DEBUG_OBJECT (demux, "TrackAudioBitDepth: %" G_GUINT64_FORMAT,
810 audiocontext->bitdepth = num;
815 case GST_MATROSKA_ID_AUDIOCHANNELS:{
818 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
822 GST_WARNING_OBJECT (demux, "Invalid TrackAudioChannels 0");
826 GST_DEBUG_OBJECT (demux, "TrackAudioChannels: %" G_GUINT64_FORMAT,
828 audiocontext->channels = num;
833 GST_WARNING_OBJECT (demux,
834 "Unknown TrackAudio subelement 0x%x - ignoring", id);
836 case GST_MATROSKA_ID_AUDIOCHANNELPOSITIONS:
837 case GST_MATROSKA_ID_AUDIOOUTPUTSAMPLINGFREQ:
838 ret = gst_ebml_read_skip (ebml);
843 DEBUG_ELEMENT_STOP (demux, ebml, "TrackAudio", ret);
848 /* codec identifier */
849 case GST_MATROSKA_ID_CODECID:{
852 if ((ret = gst_ebml_read_ascii (ebml, &id, &text)) != GST_FLOW_OK)
855 GST_DEBUG_OBJECT (demux, "CodecID: %s", GST_STR_NULL (text));
856 context->codec_id = text;
860 /* codec private data */
861 case GST_MATROSKA_ID_CODECPRIVATE:{
866 gst_ebml_read_binary (ebml, &id, &data, &size)) != GST_FLOW_OK)
869 context->codec_priv = data;
870 context->codec_priv_size = size;
872 GST_DEBUG_OBJECT (demux, "CodecPrivate of size %" G_GUINT64_FORMAT,
877 /* name of the codec */
878 case GST_MATROSKA_ID_CODECNAME:{
881 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
884 GST_DEBUG_OBJECT (demux, "CodecName: %s", GST_STR_NULL (text));
885 context->codec_name = text;
889 /* name of this track */
890 case GST_MATROSKA_ID_TRACKNAME:{
893 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
896 context->name = text;
897 GST_DEBUG_OBJECT (demux, "TrackName: %s", GST_STR_NULL (text));
901 /* language (matters for audio/subtitles, mostly) */
902 case GST_MATROSKA_ID_TRACKLANGUAGE:{
905 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
909 context->language = text;
912 if (strlen (context->language) >= 4 && context->language[3] == '-')
913 context->language[3] = '\0';
915 GST_DEBUG_OBJECT (demux, "TrackLanguage: %s",
916 GST_STR_NULL (context->language));
920 /* whether this is actually used */
921 case GST_MATROSKA_ID_TRACKFLAGENABLED:{
924 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
928 context->flags |= GST_MATROSKA_TRACK_ENABLED;
930 context->flags &= ~GST_MATROSKA_TRACK_ENABLED;
932 GST_DEBUG_OBJECT (demux, "TrackEnabled: %d",
933 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
937 /* whether it's the default for this track type */
938 case GST_MATROSKA_ID_TRACKFLAGDEFAULT:{
941 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
945 context->flags |= GST_MATROSKA_TRACK_DEFAULT;
947 context->flags &= ~GST_MATROSKA_TRACK_DEFAULT;
949 GST_DEBUG_OBJECT (demux, "TrackDefault: %d",
950 (context->flags & GST_MATROSKA_TRACK_DEFAULT) ? 1 : 0);
954 /* whether the track must be used during playback */
955 case GST_MATROSKA_ID_TRACKFLAGFORCED:{
958 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
962 context->flags |= GST_MATROSKA_TRACK_FORCED;
964 context->flags &= ~GST_MATROSKA_TRACK_FORCED;
966 GST_DEBUG_OBJECT (demux, "TrackForced: %d",
967 (context->flags & GST_MATROSKA_TRACK_FORCED) ? 1 : 0);
971 /* lacing (like MPEG, where blocks don't end/start on frame
973 case GST_MATROSKA_ID_TRACKFLAGLACING:{
976 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
980 context->flags |= GST_MATROSKA_TRACK_LACING;
982 context->flags &= ~GST_MATROSKA_TRACK_LACING;
984 GST_DEBUG_OBJECT (demux, "TrackLacing: %d",
985 (context->flags & GST_MATROSKA_TRACK_LACING) ? 1 : 0);
989 /* default length (in time) of one data block in this track */
990 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
993 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
998 GST_WARNING_OBJECT (demux, "Invalid TrackDefaultDuration 0");
1002 GST_DEBUG_OBJECT (demux, "TrackDefaultDuration: %" G_GUINT64_FORMAT,
1004 context->default_duration = num;
1008 case GST_MATROSKA_ID_CONTENTENCODINGS:{
1009 ret = gst_matroska_read_common_read_track_encodings (&demux->common,
1014 case GST_MATROSKA_ID_TRACKTIMECODESCALE:{
1017 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
1021 GST_WARNING_OBJECT (demux, "Invalid TrackTimeCodeScale %lf", num);
1025 GST_DEBUG_OBJECT (demux, "TrackTimeCodeScale: %lf", num);
1026 context->timecodescale = num;
1031 GST_WARNING ("Unknown TrackEntry subelement 0x%x - ignoring", id);
1034 /* we ignore these because they're nothing useful (i.e. crap)
1035 * or simply not implemented yet. */
1036 case GST_MATROSKA_ID_TRACKMINCACHE:
1037 case GST_MATROSKA_ID_TRACKMAXCACHE:
1038 case GST_MATROSKA_ID_MAXBLOCKADDITIONID:
1039 case GST_MATROSKA_ID_TRACKATTACHMENTLINK:
1040 case GST_MATROSKA_ID_TRACKOVERLAY:
1041 case GST_MATROSKA_ID_TRACKTRANSLATE:
1042 case GST_MATROSKA_ID_TRACKOFFSET:
1043 case GST_MATROSKA_ID_CODECSETTINGS:
1044 case GST_MATROSKA_ID_CODECINFOURL:
1045 case GST_MATROSKA_ID_CODECDOWNLOADURL:
1046 case GST_MATROSKA_ID_CODECDECODEALL:
1047 ret = gst_ebml_read_skip (ebml);
1052 DEBUG_ELEMENT_STOP (demux, ebml, "TrackEntry", ret);
1054 /* Decode codec private data if necessary */
1055 if (context->encodings && context->encodings->len > 0 && context->codec_priv
1056 && context->codec_priv_size > 0) {
1057 if (!gst_matroska_decode_data (context->encodings,
1058 &context->codec_priv, &context->codec_priv_size,
1059 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
1060 GST_WARNING_OBJECT (demux, "Decoding codec private data failed");
1061 ret = GST_FLOW_ERROR;
1065 if (context->type == 0 || context->codec_id == NULL || (ret != GST_FLOW_OK
1066 && ret != GST_FLOW_EOS)) {
1067 if (ret == GST_FLOW_OK || ret == GST_FLOW_EOS)
1068 GST_WARNING_OBJECT (ebml, "Unknown stream/codec in track entry header");
1070 demux->common.num_streams--;
1071 g_ptr_array_remove_index (demux->common.src, demux->common.num_streams);
1072 g_assert (demux->common.src->len == demux->common.num_streams);
1074 gst_matroska_track_free (context);
1080 /* now create the GStreamer connectivity */
1081 switch (context->type) {
1082 case GST_MATROSKA_TRACK_TYPE_VIDEO:{
1083 GstMatroskaTrackVideoContext *videocontext =
1084 (GstMatroskaTrackVideoContext *) context;
1086 padname = g_strdup_printf ("video_%u", demux->num_v_streams++);
1087 templ = gst_element_class_get_pad_template (klass, "video_%u");
1088 caps = gst_matroska_demux_video_caps (videocontext,
1089 context->codec_id, context->codec_priv,
1090 context->codec_priv_size, &codec, &riff_fourcc);
1093 list = gst_tag_list_new (GST_TAG_VIDEO_CODEC, codec, NULL);
1099 case GST_MATROSKA_TRACK_TYPE_AUDIO:{
1100 GstMatroskaTrackAudioContext *audiocontext =
1101 (GstMatroskaTrackAudioContext *) context;
1103 padname = g_strdup_printf ("audio_%u", demux->num_a_streams++);
1104 templ = gst_element_class_get_pad_template (klass, "audio_%u");
1105 caps = gst_matroska_demux_audio_caps (audiocontext,
1106 context->codec_id, context->codec_priv, context->codec_priv_size,
1107 &codec, &riff_audio_fmt);
1110 list = gst_tag_list_new (GST_TAG_AUDIO_CODEC, codec, NULL);
1116 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:{
1117 GstMatroskaTrackSubtitleContext *subtitlecontext =
1118 (GstMatroskaTrackSubtitleContext *) context;
1120 padname = g_strdup_printf ("subtitle_%u", demux->num_t_streams++);
1121 templ = gst_element_class_get_pad_template (klass, "subtitle_%u");
1122 caps = gst_matroska_demux_subtitle_caps (subtitlecontext,
1123 context->codec_id, context->codec_priv, context->codec_priv_size);
1127 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1128 case GST_MATROSKA_TRACK_TYPE_LOGO:
1129 case GST_MATROSKA_TRACK_TYPE_BUTTONS:
1130 case GST_MATROSKA_TRACK_TYPE_CONTROL:
1132 /* we should already have quit by now */
1133 g_assert_not_reached ();
1136 if ((context->language == NULL || *context->language == '\0') &&
1137 (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO ||
1138 context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
1139 GST_LOG ("stream %d: language=eng (assuming default)", context->index);
1140 context->language = g_strdup ("eng");
1143 if (context->language) {
1147 list = gst_tag_list_new_empty ();
1149 /* Matroska contains ISO 639-2B codes, we want ISO 639-1 */
1150 lang = gst_tag_get_language_code (context->language);
1151 gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
1152 GST_TAG_LANGUAGE_CODE, (lang) ? lang : context->language, NULL);
1156 GST_WARNING_OBJECT (demux, "could not determine caps for stream with "
1157 "codec_id='%s'", context->codec_id);
1158 switch (context->type) {
1159 case GST_MATROSKA_TRACK_TYPE_VIDEO:
1160 caps = gst_caps_new_empty_simple ("video/x-unknown");
1162 case GST_MATROSKA_TRACK_TYPE_AUDIO:
1163 caps = gst_caps_new_empty_simple ("audio/x-unknown");
1165 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
1166 caps = gst_caps_new_empty_simple ("application/x-subtitle-unknown");
1168 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1170 caps = gst_caps_new_empty_simple ("application/x-matroska-unknown");
1173 gst_caps_set_simple (caps, "codec-id", G_TYPE_STRING, context->codec_id,
1176 /* add any unrecognised riff fourcc / audio format, but after codec-id */
1177 if (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO && riff_audio_fmt != 0)
1178 gst_caps_set_simple (caps, "format", G_TYPE_INT, riff_audio_fmt, NULL);
1179 else if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO && riff_fourcc != 0) {
1180 gchar *fstr = g_strdup_printf ("%" GST_FOURCC_FORMAT,
1181 GST_FOURCC_ARGS (riff_fourcc));
1182 gst_caps_set_simple (caps, "fourcc", G_TYPE_STRING, fstr, NULL);
1185 } else if (context->stream_headers != NULL) {
1186 gst_matroska_demux_add_stream_headers_to_caps (demux,
1187 context->stream_headers, caps);
1190 /* the pad in here */
1191 context->pad = gst_pad_new_from_template (templ, padname);
1192 context->caps = caps;
1194 gst_pad_set_event_function (context->pad,
1195 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_event));
1196 gst_pad_set_query_function (context->pad,
1197 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_query));
1199 GST_INFO_OBJECT (demux, "Adding pad '%s' with caps %" GST_PTR_FORMAT,
1202 context->pending_tags = list;
1204 gst_pad_set_element_private (context->pad, context);
1206 gst_pad_use_fixed_caps (context->pad);
1207 gst_pad_set_active (context->pad, TRUE);
1210 gst_pad_create_stream_id_printf (context->pad, GST_ELEMENT_CAST (demux),
1211 "%03" G_GUINT64_FORMAT, context->uid);
1213 gst_pad_get_sticky_event (demux->common.sinkpad, GST_EVENT_STREAM_START,
1216 if (gst_event_parse_group_id (stream_start, &demux->group_id))
1217 demux->have_group_id = TRUE;
1219 demux->have_group_id = FALSE;
1220 gst_event_unref (stream_start);
1221 } else if (!demux->have_group_id) {
1222 demux->have_group_id = TRUE;
1223 demux->group_id = gst_util_group_id_next ();
1226 stream_start = gst_event_new_stream_start (stream_id);
1228 if (demux->have_group_id)
1229 gst_event_set_group_id (stream_start, demux->group_id);
1230 stream_flags = GST_STREAM_FLAG_NONE;
1231 if (context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)
1232 stream_flags |= GST_STREAM_FLAG_SPARSE;
1233 if (context->flags & GST_MATROSKA_TRACK_DEFAULT)
1234 stream_flags |= GST_STREAM_FLAG_SELECT;
1235 gst_event_set_stream_flags (stream_start, stream_flags);
1236 gst_pad_push_event (context->pad, stream_start);
1237 gst_pad_set_caps (context->pad, context->caps);
1239 gst_element_add_pad (GST_ELEMENT (demux), context->pad);
1240 gst_flow_combiner_add_pad (demux->flowcombiner, context->pad);
1249 gst_matroska_demux_query (GstMatroskaDemux * demux, GstPad * pad,
1252 gboolean res = FALSE;
1253 GstMatroskaTrackContext *context = NULL;
1256 context = gst_pad_get_element_private (pad);
1259 switch (GST_QUERY_TYPE (query)) {
1260 case GST_QUERY_POSITION:
1264 gst_query_parse_position (query, &format, NULL);
1267 if (format == GST_FORMAT_TIME) {
1268 GST_OBJECT_LOCK (demux);
1270 gst_query_set_position (query, GST_FORMAT_TIME,
1271 MAX (context->pos, demux->stream_start_time) -
1272 demux->stream_start_time);
1274 gst_query_set_position (query, GST_FORMAT_TIME,
1275 MAX (demux->common.segment.position, demux->stream_start_time) -
1276 demux->stream_start_time);
1277 GST_OBJECT_UNLOCK (demux);
1278 } else if (format == GST_FORMAT_DEFAULT && context
1279 && context->default_duration) {
1280 GST_OBJECT_LOCK (demux);
1281 gst_query_set_position (query, GST_FORMAT_DEFAULT,
1282 context->pos / context->default_duration);
1283 GST_OBJECT_UNLOCK (demux);
1285 GST_DEBUG_OBJECT (demux,
1286 "only position query in TIME and DEFAULT format is supported");
1292 case GST_QUERY_DURATION:
1296 gst_query_parse_duration (query, &format, NULL);
1299 if (format == GST_FORMAT_TIME) {
1300 GST_OBJECT_LOCK (demux);
1301 gst_query_set_duration (query, GST_FORMAT_TIME,
1302 demux->common.segment.duration);
1303 GST_OBJECT_UNLOCK (demux);
1304 } else if (format == GST_FORMAT_DEFAULT && context
1305 && context->default_duration) {
1306 GST_OBJECT_LOCK (demux);
1307 gst_query_set_duration (query, GST_FORMAT_DEFAULT,
1308 demux->common.segment.duration / context->default_duration);
1309 GST_OBJECT_UNLOCK (demux);
1311 GST_DEBUG_OBJECT (demux,
1312 "only duration query in TIME and DEFAULT format is supported");
1318 case GST_QUERY_SEEKING:
1322 gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
1323 GST_OBJECT_LOCK (demux);
1324 if (fmt == GST_FORMAT_TIME) {
1327 if (demux->streaming) {
1328 /* assuming we'll be able to get an index ... */
1329 seekable = demux->seekable;
1334 gst_query_set_seeking (query, GST_FORMAT_TIME, seekable,
1335 0, demux->common.segment.duration);
1338 GST_OBJECT_UNLOCK (demux);
1341 case GST_QUERY_SEGMENT:
1346 format = demux->common.segment.format;
1349 gst_segment_to_stream_time (&demux->common.segment, format,
1350 demux->common.segment.start);
1351 if ((stop = demux->common.segment.stop) == -1)
1352 stop = demux->common.segment.duration;
1355 gst_segment_to_stream_time (&demux->common.segment, format, stop);
1357 gst_query_set_segment (query, demux->common.segment.rate, format, start,
1364 res = gst_pad_query_default (pad, (GstObject *) demux, query);
1367 GST_ELEMENT_CLASS (parent_class)->query (GST_ELEMENT_CAST (demux),
1376 gst_matroska_demux_element_query (GstElement * element, GstQuery * query)
1378 return gst_matroska_demux_query (GST_MATROSKA_DEMUX (element), NULL, query);
1382 gst_matroska_demux_handle_src_query (GstPad * pad, GstObject * parent,
1385 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
1387 return gst_matroska_demux_query (demux, pad, query);
1390 /* returns FALSE if there are no pads to deliver event to,
1391 * otherwise TRUE (whatever the outcome of event sending),
1392 * takes ownership of the passed event! */
1394 gst_matroska_demux_send_event (GstMatroskaDemux * demux, GstEvent * event)
1396 gboolean is_segment;
1397 gboolean ret = FALSE;
1400 g_return_val_if_fail (event != NULL, FALSE);
1402 GST_DEBUG_OBJECT (demux, "Sending event of type %s to all source pads",
1403 GST_EVENT_TYPE_NAME (event));
1405 is_segment = (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT);
1407 g_assert (demux->common.src->len == demux->common.num_streams);
1408 for (i = 0; i < demux->common.src->len; i++) {
1409 GstMatroskaTrackContext *stream;
1411 stream = g_ptr_array_index (demux->common.src, i);
1412 gst_event_ref (event);
1413 gst_pad_push_event (stream->pad, event);
1416 /* FIXME: send global tags before stream tags */
1417 if (G_UNLIKELY (is_segment && stream->pending_tags != NULL)) {
1418 GST_DEBUG_OBJECT (demux, "Sending pending_tags %p for pad %s:%s : %"
1419 GST_PTR_FORMAT, stream->pending_tags,
1420 GST_DEBUG_PAD_NAME (stream->pad), stream->pending_tags);
1421 gst_pad_push_event (stream->pad,
1422 gst_event_new_tag (stream->pending_tags));
1423 stream->pending_tags = NULL;
1427 if (G_UNLIKELY (is_segment && demux->common.global_tags != NULL)) {
1428 GstEvent *tag_event;
1429 gst_tag_list_add (demux->common.global_tags, GST_TAG_MERGE_REPLACE,
1430 GST_TAG_CONTAINER_FORMAT, "Matroska", NULL);
1431 GST_DEBUG_OBJECT (demux, "Sending global_tags %p : %" GST_PTR_FORMAT,
1432 demux->common.global_tags, demux->common.global_tags);
1434 tag_event = gst_event_new_tag (demux->common.global_tags);
1436 for (i = 0; i < demux->common.src->len; i++) {
1437 GstMatroskaTrackContext *stream;
1439 stream = g_ptr_array_index (demux->common.src, i);
1440 gst_pad_push_event (stream->pad, gst_event_ref (tag_event));
1443 gst_event_unref (tag_event);
1444 demux->common.global_tags = NULL;
1447 gst_event_unref (event);
1452 gst_matroska_demux_element_send_event (GstElement * element, GstEvent * event)
1454 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
1457 g_return_val_if_fail (event != NULL, FALSE);
1459 if (GST_EVENT_TYPE (event) == GST_EVENT_SEEK) {
1460 res = gst_matroska_demux_handle_seek_event (demux, NULL, event);
1462 GST_WARNING_OBJECT (demux, "Unhandled event of type %s",
1463 GST_EVENT_TYPE_NAME (event));
1466 gst_event_unref (event);
1471 gst_matroska_demux_move_to_entry (GstMatroskaDemux * demux,
1472 GstMatroskaIndex * entry, gboolean reset, gboolean update)
1476 GST_OBJECT_LOCK (demux);
1479 /* seek (relative to matroska segment) */
1480 /* position might be invalid; will error when streaming resumes ... */
1481 demux->common.offset = entry->pos + demux->common.ebml_segment_start;
1482 demux->next_cluster_offset = 0;
1484 GST_DEBUG_OBJECT (demux,
1485 "Seeked to offset %" G_GUINT64_FORMAT ", block %d, " "time %"
1486 GST_TIME_FORMAT, entry->pos + demux->common.ebml_segment_start,
1487 entry->block, GST_TIME_ARGS (entry->time));
1489 /* update the time */
1490 gst_matroska_read_common_reset_streams (&demux->common, entry->time, TRUE);
1491 demux->common.segment.position = entry->time;
1492 demux->seek_block = entry->block;
1493 demux->seek_first = TRUE;
1494 demux->last_stop_end = GST_CLOCK_TIME_NONE;
1497 for (i = 0; i < demux->common.src->len; i++) {
1498 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
1501 stream->to_offset = G_MAXINT64;
1503 if (stream->from_offset != -1)
1504 stream->to_offset = stream->from_offset;
1506 stream->from_offset = -1;
1507 stream->from_time = GST_CLOCK_TIME_NONE;
1510 GST_OBJECT_UNLOCK (demux);
1516 gst_matroska_cluster_compare (gint64 * i1, gint64 * i2)
1526 /* searches for a cluster start from @pos,
1527 * return GST_FLOW_OK and cluster position in @pos if found */
1528 static GstFlowReturn
1529 gst_matroska_demux_search_cluster (GstMatroskaDemux * demux, gint64 * pos)
1531 gint64 newpos = *pos;
1533 GstFlowReturn ret = GST_FLOW_OK;
1534 const guint chunk = 64 * 1024;
1535 GstBuffer *buf = NULL;
1537 gpointer data = NULL;
1543 orig_offset = demux->common.offset;
1545 GST_LOG_OBJECT (demux, "searching cluster following offset %" G_GINT64_FORMAT,
1548 if (demux->clusters) {
1551 cpos = gst_util_array_binary_search (demux->clusters->data,
1552 demux->clusters->len, sizeof (gint64),
1553 (GCompareDataFunc) gst_matroska_cluster_compare,
1554 GST_SEARCH_MODE_AFTER, pos, NULL);
1557 GST_DEBUG_OBJECT (demux,
1558 "cluster reported at offset %" G_GINT64_FORMAT, *cpos);
1559 demux->common.offset = *cpos;
1560 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1561 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1562 if (ret == GST_FLOW_OK && id == GST_MATROSKA_ID_CLUSTER) {
1569 /* read in at newpos and scan for ebml cluster id */
1571 GstByteReader reader;
1575 gst_buffer_unmap (buf, &map);
1576 gst_buffer_unref (buf);
1579 ret = gst_pad_pull_range (demux->common.sinkpad, newpos, chunk, &buf);
1580 if (ret != GST_FLOW_OK)
1582 GST_DEBUG_OBJECT (demux,
1583 "read buffer size %" G_GSIZE_FORMAT " at offset %" G_GINT64_FORMAT,
1584 gst_buffer_get_size (buf), newpos);
1585 gst_buffer_map (buf, &map, GST_MAP_READ);
1588 gst_byte_reader_init (&reader, data, size);
1590 cluster_pos = gst_byte_reader_masked_scan_uint32 (&reader, 0xffffffff,
1591 GST_MATROSKA_ID_CLUSTER, 0, gst_byte_reader_get_remaining (&reader));
1592 if (cluster_pos >= 0) {
1593 newpos += cluster_pos;
1594 /* prepare resuming at next byte */
1595 if (!gst_byte_reader_skip (&reader, cluster_pos + 1)) {
1596 GST_DEBUG_OBJECT (demux, "Need more data -> continue");
1599 GST_DEBUG_OBJECT (demux,
1600 "found cluster ebml id at offset %" G_GINT64_FORMAT, newpos);
1601 /* extra checks whether we really sync'ed to a cluster:
1602 * - either it is the first and only cluster
1603 * - either there is a cluster after this one
1604 * - either cluster length is undefined
1606 /* ok if first cluster (there may not a subsequent one) */
1607 if (newpos == demux->first_cluster_offset) {
1608 GST_DEBUG_OBJECT (demux, "cluster is first cluster -> OK");
1611 demux->common.offset = newpos;
1612 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1613 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1614 if (ret != GST_FLOW_OK) {
1615 GST_DEBUG_OBJECT (demux, "need more data -> continue");
1618 g_assert (id == GST_MATROSKA_ID_CLUSTER);
1619 GST_DEBUG_OBJECT (demux, "cluster size %" G_GUINT64_FORMAT ", prefix %d",
1621 /* ok if undefined length or first cluster */
1622 if (length == GST_EBML_SIZE_UNKNOWN || length == G_MAXUINT64) {
1623 GST_DEBUG_OBJECT (demux, "cluster has undefined length -> OK");
1627 demux->common.offset += length + needed;
1628 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1629 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1630 if (ret != GST_FLOW_OK)
1632 GST_DEBUG_OBJECT (demux, "next element is %scluster",
1633 id == GST_MATROSKA_ID_CLUSTER ? "" : "not ");
1634 if (id == GST_MATROSKA_ID_CLUSTER)
1636 /* not ok, resume */
1639 /* partial cluster id may have been in tail of buffer */
1640 newpos += MAX (gst_byte_reader_get_remaining (&reader), 4) - 3;
1645 gst_buffer_unmap (buf, &map);
1646 gst_buffer_unref (buf);
1651 demux->common.offset = orig_offset;
1656 /* bisect and scan through file for cluster starting before @time,
1657 * returns fake index entry with corresponding info on cluster */
1658 static GstMatroskaIndex *
1659 gst_matroska_demux_search_pos (GstMatroskaDemux * demux, GstClockTime time)
1661 GstMatroskaIndex *entry = NULL;
1662 GstMatroskaReadState current_state;
1663 GstClockTime otime, prev_cluster_time, current_cluster_time, cluster_time;
1664 gint64 opos, newpos, startpos = 0, current_offset;
1665 gint64 prev_cluster_offset = -1, current_cluster_offset, cluster_offset;
1666 const guint chunk = 64 * 1024;
1672 /* (under)estimate new position, resync using cluster ebml id,
1673 * and scan forward to appropriate cluster
1674 * (and re-estimate if need to go backward) */
1676 prev_cluster_time = GST_CLOCK_TIME_NONE;
1678 /* store some current state */
1679 current_state = demux->common.state;
1680 g_return_val_if_fail (current_state == GST_MATROSKA_READ_STATE_DATA, NULL);
1682 current_cluster_offset = demux->cluster_offset;
1683 current_cluster_time = demux->cluster_time;
1684 current_offset = demux->common.offset;
1686 demux->common.state = GST_MATROSKA_READ_STATE_SCANNING;
1688 /* estimate using start and current position */
1689 GST_OBJECT_LOCK (demux);
1690 opos = demux->common.offset - demux->common.ebml_segment_start;
1691 otime = demux->common.segment.position;
1692 GST_OBJECT_UNLOCK (demux);
1695 time = MAX (time, demux->stream_start_time);
1697 /* avoid division by zero in first estimation below */
1698 if (otime <= demux->stream_start_time)
1702 GST_LOG_OBJECT (demux,
1703 "opos: %" G_GUINT64_FORMAT ", otime: %" GST_TIME_FORMAT ", %"
1704 GST_TIME_FORMAT " in stream time (start %" GST_TIME_FORMAT "), time %"
1705 GST_TIME_FORMAT, opos, GST_TIME_ARGS (otime),
1706 GST_TIME_ARGS (otime - demux->stream_start_time),
1707 GST_TIME_ARGS (demux->stream_start_time), GST_TIME_ARGS (time));
1709 if (otime <= demux->stream_start_time) {
1713 gst_util_uint64_scale (opos - demux->common.ebml_segment_start,
1714 time - demux->stream_start_time,
1715 otime - demux->stream_start_time) - chunk;
1719 /* favour undershoot */
1720 newpos = newpos * 90 / 100;
1721 newpos += demux->common.ebml_segment_start;
1723 GST_DEBUG_OBJECT (demux,
1724 "estimated offset for %" GST_TIME_FORMAT ": %" G_GINT64_FORMAT,
1725 GST_TIME_ARGS (time), newpos);
1727 /* and at least start scanning before previous scan start to avoid looping */
1728 startpos = startpos * 90 / 100;
1729 if (startpos && startpos < newpos)
1732 /* read in at newpos and scan for ebml cluster id */
1736 ret = gst_matroska_demux_search_cluster (demux, &newpos);
1737 if (ret == GST_FLOW_EOS) {
1738 /* heuristic HACK */
1739 newpos = startpos * 80 / 100;
1740 GST_DEBUG_OBJECT (demux, "EOS; "
1741 "new estimated offset for %" GST_TIME_FORMAT ": %" G_GINT64_FORMAT,
1742 GST_TIME_ARGS (time), newpos);
1745 } else if (ret != GST_FLOW_OK) {
1752 /* then start scanning and parsing for cluster time,
1753 * re-estimate if overshoot, otherwise next cluster and so on */
1754 demux->common.offset = newpos;
1755 demux->cluster_time = cluster_time = GST_CLOCK_TIME_NONE;
1757 guint64 cluster_size = 0;
1759 /* peek and parse some elements */
1760 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1761 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1762 if (ret != GST_FLOW_OK)
1764 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
1765 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
1767 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
1768 if (ret != GST_FLOW_OK)
1771 if (id == GST_MATROSKA_ID_CLUSTER) {
1772 cluster_time = GST_CLOCK_TIME_NONE;
1773 if (length == G_MAXUINT64)
1776 cluster_size = length + needed;
1778 if (demux->cluster_time != GST_CLOCK_TIME_NONE &&
1779 cluster_time == GST_CLOCK_TIME_NONE) {
1780 cluster_time = demux->cluster_time * demux->common.time_scale;
1781 cluster_offset = demux->cluster_offset;
1782 GST_DEBUG_OBJECT (demux, "found cluster at offset %" G_GINT64_FORMAT
1783 " with time %" GST_TIME_FORMAT, cluster_offset,
1784 GST_TIME_ARGS (cluster_time));
1785 if (cluster_time > time) {
1786 GST_DEBUG_OBJECT (demux, "overshot target");
1787 /* cluster overshoots */
1788 if (cluster_offset == demux->first_cluster_offset) {
1789 /* but no prev one */
1790 GST_DEBUG_OBJECT (demux, "but using first cluster anyway");
1791 prev_cluster_time = cluster_time;
1792 prev_cluster_offset = cluster_offset;
1795 if (prev_cluster_time != GST_CLOCK_TIME_NONE) {
1796 /* prev cluster did not overshoot, so prev cluster is target */
1799 /* re-estimate using this new position info */
1800 opos = cluster_offset;
1801 otime = cluster_time;
1805 /* cluster undershoots, goto next one */
1806 prev_cluster_time = cluster_time;
1807 prev_cluster_offset = cluster_offset;
1808 /* skip cluster if length is defined,
1809 * otherwise will be skippingly parsed into */
1811 GST_DEBUG_OBJECT (demux, "skipping to next cluster");
1812 demux->common.offset = cluster_offset + cluster_size;
1813 demux->cluster_time = GST_CLOCK_TIME_NONE;
1815 GST_DEBUG_OBJECT (demux, "parsing/skipping cluster elements");
1822 if (ret == GST_FLOW_EOS) {
1823 if (prev_cluster_time != GST_CLOCK_TIME_NONE)
1829 entry = g_new0 (GstMatroskaIndex, 1);
1830 entry->time = prev_cluster_time;
1831 entry->pos = prev_cluster_offset - demux->common.ebml_segment_start;
1832 GST_DEBUG_OBJECT (demux, "simulated index entry; time %" GST_TIME_FORMAT
1833 ", pos %" G_GUINT64_FORMAT, GST_TIME_ARGS (entry->time), entry->pos);
1837 /* restore some state */
1838 demux->cluster_offset = current_cluster_offset;
1839 demux->cluster_time = current_cluster_time;
1840 demux->common.offset = current_offset;
1841 demux->common.state = current_state;
1847 gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
1848 GstPad * pad, GstEvent * event)
1850 GstMatroskaIndex *entry = NULL;
1851 GstMatroskaIndex scan_entry;
1853 GstSeekType cur_type, stop_type;
1855 gboolean flush, keyunit, before, after, snap_next;
1858 GstMatroskaTrackContext *track = NULL;
1859 GstSegment seeksegment = { 0, };
1860 gboolean update = TRUE;
1861 gboolean pad_locked = FALSE;
1865 track = gst_pad_get_element_private (pad);
1867 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
1869 seqnum = gst_event_get_seqnum (event);
1871 /* we can only seek on time */
1872 if (format != GST_FORMAT_TIME) {
1873 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
1877 /* copy segment, we need this because we still need the old
1878 * segment when we close the current segment. */
1879 memcpy (&seeksegment, &demux->common.segment, sizeof (GstSegment));
1881 /* pull mode without index means that the actual duration is not known,
1882 * we might be playing a file that's still being recorded
1883 * so, invalidate our current duration, which is only a moving target,
1884 * and should not be used to clamp anything */
1885 if (!demux->streaming && !demux->common.index && demux->invalid_duration) {
1886 seeksegment.duration = GST_CLOCK_TIME_NONE;
1890 GST_DEBUG_OBJECT (demux, "configuring seek");
1891 gst_segment_do_seek (&seeksegment, rate, format, flags,
1892 cur_type, cur, stop_type, stop, &update);
1893 /* compensate for clip start time, but only for SET seeks,
1894 * otherwise it is already part of the segments */
1895 if (GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
1896 if (cur_type == GST_SEEK_TYPE_SET) {
1898 seeksegment.position += demux->stream_start_time;
1899 seeksegment.start += demux->stream_start_time;
1901 if (stop_type == GST_SEEK_TYPE_SET
1902 && GST_CLOCK_TIME_IS_VALID (seeksegment.stop)) {
1904 seeksegment.position += demux->stream_start_time;
1905 seeksegment.stop += demux->stream_start_time;
1910 /* restore segment duration (if any effect),
1911 * would be determined again when parsing, but anyway ... */
1912 seeksegment.duration = demux->common.segment.duration;
1914 flush = ! !(flags & GST_SEEK_FLAG_FLUSH);
1915 keyunit = ! !(flags & GST_SEEK_FLAG_KEY_UNIT);
1916 after = ! !(flags & GST_SEEK_FLAG_SNAP_AFTER);
1917 before = ! !(flags & GST_SEEK_FLAG_SNAP_BEFORE);
1919 /* always do full update if flushing,
1920 * otherwise problems might arise downstream with missing keyframes etc */
1921 update = update || flush;
1923 GST_DEBUG_OBJECT (demux, "New segment %" GST_SEGMENT_FORMAT, &seeksegment);
1925 /* check sanity before we start flushing and all that */
1926 snap_next = after && !before;
1927 if (seeksegment.rate < 0)
1928 snap_next = !snap_next;
1929 GST_OBJECT_LOCK (demux);
1930 track = gst_matroska_read_common_get_seek_track (&demux->common, track);
1931 if ((entry = gst_matroska_read_common_do_index_seek (&demux->common, track,
1932 seeksegment.position, &demux->seek_index, &demux->seek_entry,
1933 snap_next)) == NULL) {
1934 /* pull mode without index can scan later on */
1935 if (demux->streaming) {
1936 GST_DEBUG_OBJECT (demux, "No matching seek entry in index");
1937 GST_OBJECT_UNLOCK (demux);
1939 } else if (rate < 0.0) {
1940 /* FIXME: We should build an index during playback or when scanning
1941 * that can be used here. The reverse playback code requires seek_index
1942 * and seek_entry to be set!
1944 GST_DEBUG_OBJECT (demux,
1945 "No matching seek entry in index, needed for reverse playback");
1946 GST_OBJECT_UNLOCK (demux);
1950 GST_DEBUG_OBJECT (demux, "Seek position looks sane");
1951 GST_OBJECT_UNLOCK (demux);
1954 /* only have to update some segment,
1955 * but also still have to honour flush and so on */
1956 GST_DEBUG_OBJECT (demux, "... no update");
1957 /* bad goto, bad ... */
1961 if (demux->streaming)
1966 GstEvent *flush_event = gst_event_new_flush_start ();
1967 gst_event_set_seqnum (flush_event, seqnum);
1968 GST_DEBUG_OBJECT (demux, "Starting flush");
1969 gst_pad_push_event (demux->common.sinkpad, gst_event_ref (flush_event));
1970 gst_matroska_demux_send_event (demux, flush_event);
1972 GST_DEBUG_OBJECT (demux, "Non-flushing seek, pausing task");
1973 gst_pad_pause_task (demux->common.sinkpad);
1977 GST_PAD_STREAM_LOCK (demux->common.sinkpad);
1982 /* now grab the stream lock so that streaming cannot continue, for
1983 * non flushing seeks when the element is in PAUSED this could block
1985 GST_DEBUG_OBJECT (demux, "Waiting for streaming to stop");
1986 GST_PAD_STREAM_LOCK (demux->common.sinkpad);
1989 /* pull mode without index can do some scanning */
1990 if (!demux->streaming && !entry) {
1991 GstEvent *flush_event;
1993 /* need to stop flushing upstream as we need it next */
1995 flush_event = gst_event_new_flush_stop (TRUE);
1996 gst_event_set_seqnum (flush_event, seqnum);
1997 gst_pad_push_event (demux->common.sinkpad, flush_event);
1999 entry = gst_matroska_demux_search_pos (demux, seeksegment.position);
2000 /* keep local copy */
2002 scan_entry = *entry;
2004 entry = &scan_entry;
2006 GST_DEBUG_OBJECT (demux, "Scan failed to find matching position");
2008 flush_event = gst_event_new_flush_stop (TRUE);
2009 gst_event_set_seqnum (flush_event, seqnum);
2010 gst_matroska_demux_send_event (demux, flush_event);
2018 GST_DEBUG_OBJECT (demux, "seek to key unit, adjusting segment start from %"
2019 GST_TIME_FORMAT " to %" GST_TIME_FORMAT,
2020 GST_TIME_ARGS (seeksegment.start), GST_TIME_ARGS (entry->time));
2021 seeksegment.start = MAX (entry->time, demux->stream_start_time);
2022 seeksegment.position = seeksegment.start;
2023 seeksegment.time = seeksegment.start - demux->stream_start_time;
2026 if (demux->streaming) {
2027 GST_OBJECT_LOCK (demux);
2028 /* track real position we should start at */
2029 GST_DEBUG_OBJECT (demux, "storing segment start");
2030 demux->requested_seek_time = seeksegment.position;
2031 demux->seek_offset = entry->pos + demux->common.ebml_segment_start;
2032 GST_OBJECT_UNLOCK (demux);
2033 /* need to seek to cluster start to pick up cluster time */
2034 /* upstream takes care of flushing and all that
2035 * ... and newsegment event handling takes care of the rest */
2036 return perform_seek_to_offset (demux, rate,
2037 entry->pos + demux->common.ebml_segment_start, seqnum);
2042 GstEvent *flush_event = gst_event_new_flush_stop (TRUE);
2043 gst_event_set_seqnum (flush_event, seqnum);
2044 GST_DEBUG_OBJECT (demux, "Stopping flush");
2045 gst_pad_push_event (demux->common.sinkpad, gst_event_ref (flush_event));
2046 gst_matroska_demux_send_event (demux, flush_event);
2049 GST_OBJECT_LOCK (demux);
2050 /* now update the real segment info */
2051 GST_DEBUG_OBJECT (demux, "Committing new seek segment");
2052 memcpy (&demux->common.segment, &seeksegment, sizeof (GstSegment));
2053 GST_OBJECT_UNLOCK (demux);
2055 /* update some (segment) state */
2056 if (!gst_matroska_demux_move_to_entry (demux, entry, TRUE, update))
2059 /* notify start of new segment */
2060 if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
2063 msg = gst_message_new_segment_start (GST_OBJECT (demux),
2064 GST_FORMAT_TIME, demux->common.segment.start);
2065 gst_message_set_seqnum (msg, seqnum);
2066 gst_element_post_message (GST_ELEMENT (demux), msg);
2069 GST_OBJECT_LOCK (demux);
2070 if (demux->new_segment)
2071 gst_event_unref (demux->new_segment);
2073 /* On port from 0.10, discarded !update (for segment.update) here, FIXME? */
2074 demux->new_segment = gst_event_new_segment (&demux->common.segment);
2075 gst_event_set_seqnum (demux->new_segment, seqnum);
2076 if (demux->common.segment.rate < 0 && demux->common.segment.stop == -1)
2077 demux->to_time = demux->common.segment.position;
2079 demux->to_time = GST_CLOCK_TIME_NONE;
2080 GST_OBJECT_UNLOCK (demux);
2082 /* restart our task since it might have been stopped when we did the
2084 gst_pad_start_task (demux->common.sinkpad,
2085 (GstTaskFunction) gst_matroska_demux_loop, demux->common.sinkpad, NULL);
2087 /* streaming can continue now */
2089 GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
2097 GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
2099 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Got a seek error"));
2105 * Handle whether we can perform the seek event or if we have to let the chain
2106 * function handle seeks to build the seek indexes first.
2109 gst_matroska_demux_handle_seek_push (GstMatroskaDemux * demux, GstPad * pad,
2113 GstSeekType cur_type, stop_type;
2118 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
2123 /* we can only seek on time */
2124 if (format != GST_FORMAT_TIME) {
2125 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
2129 if (stop_type != GST_SEEK_TYPE_NONE && stop != GST_CLOCK_TIME_NONE) {
2130 GST_DEBUG_OBJECT (demux, "Seek end-time not supported in streaming mode");
2134 if (!(flags & GST_SEEK_FLAG_FLUSH)) {
2135 GST_DEBUG_OBJECT (demux,
2136 "Non-flushing seek not supported in streaming mode");
2140 if (flags & GST_SEEK_FLAG_SEGMENT) {
2141 GST_DEBUG_OBJECT (demux, "Segment seek not supported in streaming mode");
2145 /* check for having parsed index already */
2146 if (!demux->common.index_parsed) {
2147 gboolean building_index;
2150 if (!demux->index_offset) {
2151 GST_DEBUG_OBJECT (demux, "no index (location); no seek in push mode");
2155 GST_OBJECT_LOCK (demux);
2156 /* handle the seek event in the chain function */
2157 demux->common.state = GST_MATROSKA_READ_STATE_SEEK;
2158 /* no more seek can be issued until state reset to _DATA */
2160 /* copy the event */
2161 if (demux->seek_event)
2162 gst_event_unref (demux->seek_event);
2163 demux->seek_event = gst_event_ref (event);
2165 /* set the building_index flag so that only one thread can setup the
2166 * structures for index seeking. */
2167 building_index = demux->building_index;
2168 if (!building_index) {
2169 demux->building_index = TRUE;
2170 offset = demux->index_offset;
2172 GST_OBJECT_UNLOCK (demux);
2174 if (!building_index) {
2175 /* seek to the first subindex or legacy index */
2176 GST_INFO_OBJECT (demux, "Seeking to Cues at %" G_GUINT64_FORMAT, offset);
2177 return perform_seek_to_offset (demux, rate, offset,
2178 gst_event_get_seqnum (event));
2181 /* well, we are handling it already */
2185 /* delegate to tweaked regular seek */
2186 return gst_matroska_demux_handle_seek_event (demux, pad, event);
2190 gst_matroska_demux_handle_src_event (GstPad * pad, GstObject * parent,
2193 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
2194 gboolean res = TRUE;
2196 switch (GST_EVENT_TYPE (event)) {
2197 case GST_EVENT_SEEK:
2198 /* no seeking until we are (safely) ready */
2199 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
2200 GST_DEBUG_OBJECT (demux, "not ready for seeking yet");
2203 if (!demux->streaming)
2204 res = gst_matroska_demux_handle_seek_event (demux, pad, event);
2206 res = gst_matroska_demux_handle_seek_push (demux, pad, event);
2207 gst_event_unref (event);
2212 GstMatroskaTrackContext *context = gst_pad_get_element_private (pad);
2213 if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
2214 GstMatroskaTrackVideoContext *videocontext =
2215 (GstMatroskaTrackVideoContext *) context;
2217 GstClockTimeDiff diff;
2218 GstClockTime timestamp;
2220 gst_event_parse_qos (event, NULL, &proportion, &diff, ×tamp);
2222 GST_OBJECT_LOCK (demux);
2223 videocontext->earliest_time = timestamp + diff;
2224 GST_OBJECT_UNLOCK (demux);
2227 gst_event_unref (event);
2231 case GST_EVENT_TOC_SELECT:
2234 GstTocEntry *entry = NULL;
2235 GstEvent *seek_event;
2238 if (!demux->common.toc) {
2239 GST_DEBUG_OBJECT (demux, "no TOC to select");
2242 gst_event_parse_toc_select (event, &uid);
2244 GST_OBJECT_LOCK (demux);
2245 entry = gst_toc_find_entry (demux->common.toc, uid);
2246 if (entry == NULL) {
2247 GST_OBJECT_UNLOCK (demux);
2248 GST_WARNING_OBJECT (demux, "no TOC entry with given UID: %s", uid);
2251 gst_toc_entry_get_start_stop_times (entry, &start_pos, NULL);
2252 GST_OBJECT_UNLOCK (demux);
2253 seek_event = gst_event_new_seek (1.0,
2255 GST_SEEK_FLAG_FLUSH,
2256 GST_SEEK_TYPE_SET, start_pos, GST_SEEK_TYPE_SET, -1);
2257 res = gst_matroska_demux_handle_seek_event (demux, pad, seek_event);
2258 gst_event_unref (seek_event);
2262 GST_WARNING_OBJECT (demux, "received empty TOC select event");
2266 gst_event_unref (event);
2270 /* events we don't need to handle */
2271 case GST_EVENT_NAVIGATION:
2272 gst_event_unref (event);
2276 case GST_EVENT_LATENCY:
2278 res = gst_pad_push_event (demux->common.sinkpad, event);
2285 static GstFlowReturn
2286 gst_matroska_demux_seek_to_previous_keyframe (GstMatroskaDemux * demux)
2288 GstFlowReturn ret = GST_FLOW_EOS;
2289 gboolean done = TRUE;
2292 g_return_val_if_fail (demux->seek_index, GST_FLOW_EOS);
2293 g_return_val_if_fail (demux->seek_entry < demux->seek_index->len,
2296 GST_DEBUG_OBJECT (demux, "locating previous keyframe");
2298 if (!demux->seek_entry) {
2299 GST_DEBUG_OBJECT (demux, "no earlier index entry");
2303 for (i = 0; i < demux->common.src->len; i++) {
2304 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
2306 GST_DEBUG_OBJECT (demux, "segment start %" GST_TIME_FORMAT
2307 ", stream %d at %" GST_TIME_FORMAT,
2308 GST_TIME_ARGS (demux->common.segment.start), stream->index,
2309 GST_TIME_ARGS (stream->from_time));
2310 if (GST_CLOCK_TIME_IS_VALID (stream->from_time)) {
2311 if (stream->from_time > demux->common.segment.start) {
2312 GST_DEBUG_OBJECT (demux, "stream %d not finished yet", stream->index);
2316 /* nothing pushed for this stream;
2317 * likely seek entry did not start at keyframe, so all was skipped.
2318 * So we need an earlier entry */
2324 GstMatroskaIndex *entry;
2326 entry = &g_array_index (demux->seek_index, GstMatroskaIndex,
2327 --demux->seek_entry);
2328 if (!gst_matroska_demux_move_to_entry (demux, entry, FALSE, TRUE))
2338 static GstFlowReturn
2339 gst_matroska_demux_parse_tracks (GstMatroskaDemux * demux, GstEbmlRead * ebml)
2341 GstFlowReturn ret = GST_FLOW_OK;
2344 DEBUG_ELEMENT_START (demux, ebml, "Tracks");
2346 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2347 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
2351 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
2352 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
2356 /* one track within the "all-tracks" header */
2357 case GST_MATROSKA_ID_TRACKENTRY:
2358 ret = gst_matroska_demux_add_stream (demux, ebml);
2362 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
2367 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
2369 demux->tracks_parsed = TRUE;
2375 * Read signed/unsigned "EBML" numbers.
2376 * Return: number of bytes processed.
2380 gst_matroska_ebmlnum_uint (guint8 * data, guint size, guint64 * num)
2382 gint len_mask = 0x80, read = 1, n = 1, num_ffs = 0;
2390 while (read <= 8 && !(total & len_mask)) {
2397 if ((total &= (len_mask - 1)) == len_mask - 1)
2402 if (data[n] == 0xff)
2404 total = (total << 8) | data[n];
2408 if (read == num_ffs && total != 0)
2417 gst_matroska_ebmlnum_sint (guint8 * data, guint size, gint64 * num)
2422 /* read as unsigned number first */
2423 if ((res = gst_matroska_ebmlnum_uint (data, size, &unum)) < 0)
2427 if (unum == G_MAXUINT64)
2430 *num = unum - ((1 << ((7 * res) - 1)) - 1);
2436 * Mostly used for subtitles. We add void filler data for each
2437 * lagging stream to make sure we don't deadlock.
2441 gst_matroska_demux_sync_streams (GstMatroskaDemux * demux)
2445 GST_OBJECT_LOCK (demux);
2447 GST_LOG_OBJECT (demux, "Sync to %" GST_TIME_FORMAT,
2448 GST_TIME_ARGS (demux->common.segment.position));
2450 g_assert (demux->common.num_streams == demux->common.src->len);
2451 for (stream_nr = 0; stream_nr < demux->common.src->len; stream_nr++) {
2452 GstMatroskaTrackContext *context;
2454 context = g_ptr_array_index (demux->common.src, stream_nr);
2456 GST_LOG_OBJECT (demux,
2457 "Checking for resync on stream %d (%" GST_TIME_FORMAT ")", stream_nr,
2458 GST_TIME_ARGS (context->pos));
2460 if (G_LIKELY (context->type != GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
2461 GST_LOG_OBJECT (demux, "Skipping sync on non-subtitle stream");
2465 /* does it lag? 0.5 seconds is a random threshold...
2466 * lag need only be considered if we have advanced into requested segment */
2467 if (GST_CLOCK_TIME_IS_VALID (context->pos) &&
2468 GST_CLOCK_TIME_IS_VALID (demux->common.segment.position) &&
2469 demux->common.segment.position > demux->common.segment.start &&
2470 context->pos + (GST_SECOND / 2) < demux->common.segment.position) {
2473 guint64 start = context->pos;
2474 guint64 stop = demux->common.segment.position - (GST_SECOND / 2);
2476 GST_DEBUG_OBJECT (demux,
2477 "Synchronizing stream %d with other by advancing time from %"
2478 GST_TIME_FORMAT " to %" GST_TIME_FORMAT, stream_nr,
2479 GST_TIME_ARGS (start), GST_TIME_ARGS (stop));
2481 context->pos = stop;
2483 event = gst_event_new_gap (start, stop - start);
2484 GST_OBJECT_UNLOCK (demux);
2485 gst_pad_push_event (context->pad, event);
2486 GST_OBJECT_LOCK (demux);
2490 GST_OBJECT_UNLOCK (demux);
2493 static GstFlowReturn
2494 gst_matroska_demux_push_stream_headers (GstMatroskaDemux * demux,
2495 GstMatroskaTrackContext * stream)
2497 GstFlowReturn ret = GST_FLOW_OK;
2500 num = gst_buffer_list_length (stream->stream_headers);
2501 for (i = 0; i < num; ++i) {
2504 buf = gst_buffer_list_get (stream->stream_headers, i);
2505 buf = gst_buffer_copy (buf);
2507 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
2509 if (stream->set_discont) {
2510 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
2511 stream->set_discont = FALSE;
2513 GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DISCONT);
2516 /* push out all headers in one go and use last flow return */
2517 ret = gst_pad_push (stream->pad, buf);
2520 /* don't need these any longer */
2521 gst_buffer_list_unref (stream->stream_headers);
2522 stream->stream_headers = NULL;
2525 ret = gst_flow_combiner_update_flow (demux->flowcombiner, ret);
2531 gst_matroska_demux_push_dvd_clut_change_event (GstMatroskaDemux * demux,
2532 GstMatroskaTrackContext * stream)
2536 g_assert (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB));
2538 if (!stream->codec_priv)
2541 /* ideally, VobSub private data should be parsed and stored more convenient
2542 * elsewhere, but for now, only interested in a small part */
2544 /* make sure we have terminating 0 */
2545 buf = g_strndup (stream->codec_priv, stream->codec_priv_size);
2547 /* just locate and parse palette part */
2548 start = strstr (buf, "palette:");
2553 guint8 r, g, b, y, u, v;
2556 while (g_ascii_isspace (*start))
2558 for (i = 0; i < 16; i++) {
2559 if (sscanf (start, "%06x", &col) != 1)
2562 while ((*start == ',') || g_ascii_isspace (*start))
2564 /* sigh, need to convert this from vobsub pseudo-RGB to YUV */
2565 r = (col >> 16) & 0xff;
2566 g = (col >> 8) & 0xff;
2568 y = CLAMP ((0.1494 * r + 0.6061 * g + 0.2445 * b) * 219 / 255 + 16, 0,
2570 u = CLAMP (0.6066 * r - 0.4322 * g - 0.1744 * b + 128, 0, 255);
2571 v = CLAMP (-0.08435 * r - 0.3422 * g + 0.4266 * b + 128, 0, 255);
2572 clut[i] = (y << 16) | (u << 8) | v;
2575 /* got them all without problems; build and send event */
2579 s = gst_structure_new ("application/x-gst-dvd", "event", G_TYPE_STRING,
2580 "dvd-spu-clut-change", "clut00", G_TYPE_INT, clut[0], "clut01",
2581 G_TYPE_INT, clut[1], "clut02", G_TYPE_INT, clut[2], "clut03",
2582 G_TYPE_INT, clut[3], "clut04", G_TYPE_INT, clut[4], "clut05",
2583 G_TYPE_INT, clut[5], "clut06", G_TYPE_INT, clut[6], "clut07",
2584 G_TYPE_INT, clut[7], "clut08", G_TYPE_INT, clut[8], "clut09",
2585 G_TYPE_INT, clut[9], "clut10", G_TYPE_INT, clut[10], "clut11",
2586 G_TYPE_INT, clut[11], "clut12", G_TYPE_INT, clut[12], "clut13",
2587 G_TYPE_INT, clut[13], "clut14", G_TYPE_INT, clut[14], "clut15",
2588 G_TYPE_INT, clut[15], NULL);
2590 gst_pad_push_event (stream->pad,
2591 gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM_STICKY, s));
2598 gst_matroska_demux_push_codec_data_all (GstMatroskaDemux * demux)
2602 GST_OBJECT_LOCK (demux);
2604 g_assert (demux->common.num_streams == demux->common.src->len);
2605 for (stream_nr = 0; stream_nr < demux->common.src->len; stream_nr++) {
2606 GstMatroskaTrackContext *stream;
2608 stream = g_ptr_array_index (demux->common.src, stream_nr);
2610 if (stream->send_stream_headers) {
2611 if (stream->stream_headers != NULL) {
2612 gst_matroska_demux_push_stream_headers (demux, stream);
2614 /* FIXME: perhaps we can just disable and skip this stream then */
2615 GST_ELEMENT_ERROR (demux, STREAM, DECODE, (NULL),
2616 ("Failed to extract stream headers from codec private data"));
2618 stream->send_stream_headers = FALSE;
2621 if (stream->send_dvd_event) {
2622 gst_matroska_demux_push_dvd_clut_change_event (demux, stream);
2623 /* FIXME: should we send this event again after (flushing) seek ? */
2624 stream->send_dvd_event = FALSE;
2628 GST_OBJECT_UNLOCK (demux);
2631 static GstFlowReturn
2632 gst_matroska_demux_add_mpeg_seq_header (GstElement * element,
2633 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2636 guint seq_header_len;
2637 guint32 header, tmp;
2639 if (stream->codec_state) {
2640 seq_header = stream->codec_state;
2641 seq_header_len = stream->codec_state_size;
2642 } else if (stream->codec_priv) {
2643 seq_header = stream->codec_priv;
2644 seq_header_len = stream->codec_priv_size;
2649 /* Sequence header only needed for keyframes */
2650 if (GST_BUFFER_FLAG_IS_SET (*buf, GST_BUFFER_FLAG_DELTA_UNIT))
2653 if (gst_buffer_get_size (*buf) < 4)
2656 gst_buffer_extract (*buf, 0, &tmp, sizeof (guint32));
2657 header = GUINT32_FROM_BE (tmp);
2659 /* Sequence start code, if not found prepend */
2660 if (header != 0x000001b3) {
2663 GST_DEBUG_OBJECT (element, "Prepending MPEG sequence header");
2665 newbuf = gst_buffer_new_wrapped (g_memdup (seq_header, seq_header_len),
2668 gst_buffer_copy_into (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
2669 GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_MEMORY, 0,
2670 gst_buffer_get_size (*buf));
2672 gst_buffer_unref (*buf);
2679 static GstFlowReturn
2680 gst_matroska_demux_add_wvpk_header (GstElement * element,
2681 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2683 GstMatroskaTrackAudioContext *audiocontext =
2684 (GstMatroskaTrackAudioContext *) stream;
2685 GstBuffer *newbuf = NULL;
2686 GstMapInfo map, outmap;
2687 guint8 *buf_data, *data;
2695 wvh.version = GST_READ_UINT16_LE (stream->codec_priv);
2698 wvh.total_samples = -1;
2699 wvh.block_index = audiocontext->wvpk_block_index;
2701 if (audiocontext->channels <= 2) {
2702 guint32 block_samples, tmp;
2703 gsize size = gst_buffer_get_size (*buf);
2705 gst_buffer_extract (*buf, 0, &tmp, sizeof (guint32));
2706 block_samples = GUINT32_FROM_LE (tmp);
2707 /* we need to reconstruct the header of the wavpack block */
2709 /* -20 because ck_size is the size of the wavpack block -8
2710 * and lace_size is the size of the wavpack block + 12
2711 * (the three guint32 of the header that already are in the buffer) */
2712 wvh.ck_size = size + sizeof (Wavpack4Header) - 20;
2714 /* block_samples, flags and crc are already in the buffer */
2715 newbuf = gst_buffer_new_allocate (NULL, sizeof (Wavpack4Header) - 12, NULL);
2717 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2723 GST_WRITE_UINT32_LE (data + 4, wvh.ck_size);
2724 GST_WRITE_UINT16_LE (data + 8, wvh.version);
2725 GST_WRITE_UINT8 (data + 10, wvh.track_no);
2726 GST_WRITE_UINT8 (data + 11, wvh.index_no);
2727 GST_WRITE_UINT32_LE (data + 12, wvh.total_samples);
2728 GST_WRITE_UINT32_LE (data + 16, wvh.block_index);
2730 /* Append data from buf: */
2731 gst_buffer_copy_into (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
2732 GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_MEMORY, 0, size);
2734 gst_buffer_unref (*buf);
2736 audiocontext->wvpk_block_index += block_samples;
2738 guint8 *outdata = NULL;
2740 gsize buf_size, size, out_size = 0;
2741 guint32 block_samples, flags, crc, blocksize;
2743 gst_buffer_map (*buf, &map, GST_MAP_READ);
2744 buf_data = map.data;
2745 buf_size = map.size;
2748 GST_ERROR_OBJECT (element, "Too small wavpack buffer");
2749 gst_buffer_unmap (*buf, &map);
2750 return GST_FLOW_ERROR;
2756 block_samples = GST_READ_UINT32_LE (data);
2761 flags = GST_READ_UINT32_LE (data);
2764 crc = GST_READ_UINT32_LE (data);
2767 blocksize = GST_READ_UINT32_LE (data);
2771 if (blocksize == 0 || size < blocksize)
2774 g_assert ((newbuf == NULL) == (outdata == NULL));
2776 if (newbuf == NULL) {
2777 out_size = sizeof (Wavpack4Header) + blocksize;
2778 newbuf = gst_buffer_new_allocate (NULL, out_size, NULL);
2780 gst_buffer_copy_into (newbuf, *buf,
2781 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS, 0, -1);
2784 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2785 outdata = outmap.data;
2787 gst_buffer_unmap (newbuf, &outmap);
2788 out_size += sizeof (Wavpack4Header) + blocksize;
2789 gst_buffer_set_size (newbuf, out_size);
2790 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2791 outdata = outmap.data;
2794 outdata[outpos] = 'w';
2795 outdata[outpos + 1] = 'v';
2796 outdata[outpos + 2] = 'p';
2797 outdata[outpos + 3] = 'k';
2800 GST_WRITE_UINT32_LE (outdata + outpos,
2801 blocksize + sizeof (Wavpack4Header) - 8);
2802 GST_WRITE_UINT16_LE (outdata + outpos + 4, wvh.version);
2803 GST_WRITE_UINT8 (outdata + outpos + 6, wvh.track_no);
2804 GST_WRITE_UINT8 (outdata + outpos + 7, wvh.index_no);
2805 GST_WRITE_UINT32_LE (outdata + outpos + 8, wvh.total_samples);
2806 GST_WRITE_UINT32_LE (outdata + outpos + 12, wvh.block_index);
2807 GST_WRITE_UINT32_LE (outdata + outpos + 16, block_samples);
2808 GST_WRITE_UINT32_LE (outdata + outpos + 20, flags);
2809 GST_WRITE_UINT32_LE (outdata + outpos + 24, crc);
2812 memmove (outdata + outpos, data, blocksize);
2813 outpos += blocksize;
2817 gst_buffer_unmap (*buf, &map);
2818 gst_buffer_unref (*buf);
2821 gst_buffer_unmap (newbuf, &outmap);
2824 audiocontext->wvpk_block_index += block_samples;
2830 /* @text must be null-terminated */
2832 gst_matroska_demux_subtitle_chunk_has_tag (GstElement * element,
2837 g_return_val_if_fail (text != NULL, FALSE);
2839 /* yes, this might all lead to false positives ... */
2840 tag = (gchar *) text;
2841 while ((tag = strchr (tag, '<'))) {
2843 if (*tag != '\0' && *(tag + 1) == '>') {
2844 /* some common convenience ones */
2845 /* maybe any character will do here ? */
2858 if (strstr (text, "<span"))
2864 static GstFlowReturn
2865 gst_matroska_demux_check_subtitle_buffer (GstElement * element,
2866 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2868 GstMatroskaTrackSubtitleContext *sub_stream;
2869 const gchar *encoding;
2874 gboolean needs_unmap = TRUE;
2876 sub_stream = (GstMatroskaTrackSubtitleContext *) stream;
2878 if (!gst_buffer_get_size (*buf) || !gst_buffer_map (*buf, &map, GST_MAP_READ))
2881 /* Need \0-terminator at the end */
2882 if (map.data[map.size - 1] != '\0') {
2883 newbuf = gst_buffer_new_and_alloc (map.size + 1);
2885 /* Copy old buffer and add a 0 at the end */
2886 gst_buffer_fill (newbuf, 0, map.data, map.size);
2887 gst_buffer_memset (newbuf, map.size, 0, 1);
2888 gst_buffer_unmap (*buf, &map);
2890 gst_buffer_copy_into (newbuf, *buf,
2891 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS |
2892 GST_BUFFER_COPY_META, 0, -1);
2893 gst_buffer_unref (*buf);
2895 gst_buffer_map (*buf, &map, GST_MAP_READ);
2898 if (!sub_stream->invalid_utf8) {
2899 if (g_utf8_validate ((gchar *) map.data, map.size - 1, NULL)) {
2902 GST_WARNING_OBJECT (element, "subtitle stream %" G_GUINT64_FORMAT
2903 " is not valid UTF-8, this is broken according to the matroska"
2904 " specification", stream->num);
2905 sub_stream->invalid_utf8 = TRUE;
2908 /* file with broken non-UTF8 subtitle, do the best we can do to fix it */
2909 encoding = g_getenv ("GST_SUBTITLE_ENCODING");
2910 if (encoding == NULL || *encoding == '\0') {
2911 /* if local encoding is UTF-8 and no encoding specified
2912 * via the environment variable, assume ISO-8859-15 */
2913 if (g_get_charset (&encoding)) {
2914 encoding = "ISO-8859-15";
2919 g_convert_with_fallback ((gchar *) map.data, map.size, "UTF-8", encoding,
2920 (char *) "*", NULL, NULL, &err);
2923 GST_LOG_OBJECT (element, "could not convert string from '%s' to UTF-8: %s",
2924 encoding, err->message);
2928 /* invalid input encoding, fall back to ISO-8859-15 (always succeeds) */
2929 encoding = "ISO-8859-15";
2931 g_convert_with_fallback ((gchar *) map.data, map.size, "UTF-8",
2932 encoding, (char *) "*", NULL, NULL, NULL);
2935 GST_LOG_OBJECT (element, "converted subtitle text from %s to UTF-8 %s",
2936 encoding, (err) ? "(using ISO-8859-15 as fallback)" : "");
2939 utf8 = g_strdup ("invalid subtitle");
2941 newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
2942 gst_buffer_unmap (*buf, &map);
2943 gst_buffer_copy_into (newbuf, *buf,
2944 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_META,
2946 gst_buffer_unref (*buf);
2949 gst_buffer_map (*buf, &map, GST_MAP_READ);
2953 if (sub_stream->check_markup) {
2954 /* caps claim markup text, so we need to escape text,
2955 * except if text is already markup and then needs no further escaping */
2956 sub_stream->seen_markup_tag = sub_stream->seen_markup_tag ||
2957 gst_matroska_demux_subtitle_chunk_has_tag (element, (gchar *) map.data);
2959 if (!sub_stream->seen_markup_tag) {
2960 utf8 = g_markup_escape_text ((gchar *) map.data, map.size);
2962 newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
2963 gst_buffer_unmap (*buf, &map);
2964 gst_buffer_copy_into (newbuf, *buf,
2965 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS |
2966 GST_BUFFER_COPY_META, 0, -1);
2967 gst_buffer_unref (*buf);
2970 needs_unmap = FALSE;
2975 gst_buffer_unmap (*buf, &map);
2980 static GstFlowReturn
2981 gst_matroska_demux_check_aac (GstElement * element,
2982 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2987 gst_buffer_extract (*buf, 0, data, 2);
2988 size = gst_buffer_get_size (*buf);
2990 if (size > 2 && data[0] == 0xff && (data[1] >> 4 == 0x0f)) {
2993 /* tss, ADTS data, remove codec_data
2994 * still assume it is at least parsed */
2995 stream->caps = gst_caps_make_writable (stream->caps);
2996 s = gst_caps_get_structure (stream->caps, 0);
2998 gst_structure_remove_field (s, "codec_data");
2999 gst_pad_set_caps (stream->pad, stream->caps);
3000 GST_DEBUG_OBJECT (element, "ADTS AAC audio data; removing codec-data, "
3001 "new caps: %" GST_PTR_FORMAT, stream->caps);
3004 /* disable subsequent checking */
3005 stream->postprocess_frame = NULL;
3011 gst_matroska_demux_align_buffer (GstMatroskaDemux * demux,
3012 GstBuffer * buffer, gsize alignment)
3016 gst_buffer_map (buffer, &map, GST_MAP_READ);
3018 if (map.size < sizeof (guintptr)) {
3019 gst_buffer_unmap (buffer, &map);
3023 if (((guintptr) map.data) & (alignment - 1)) {
3024 GstBuffer *new_buffer;
3025 GstAllocationParams params = { 0, alignment - 1, 0, 0, };
3027 new_buffer = gst_buffer_new_allocate (NULL,
3028 gst_buffer_get_size (buffer), ¶ms);
3030 /* Copy data "by hand", so ensure alignment is kept: */
3031 gst_buffer_fill (new_buffer, 0, map.data, map.size);
3033 gst_buffer_copy_into (new_buffer, buffer, GST_BUFFER_COPY_METADATA, 0, -1);
3034 GST_DEBUG_OBJECT (demux,
3035 "We want output aligned on %" G_GSIZE_FORMAT ", reallocated",
3038 gst_buffer_unmap (buffer, &map);
3039 gst_buffer_unref (buffer);
3044 gst_buffer_unmap (buffer, &map);
3048 static GstFlowReturn
3049 gst_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux,
3050 GstEbmlRead * ebml, guint64 cluster_time, guint64 cluster_offset,
3051 gboolean is_simpleblock)
3053 GstMatroskaTrackContext *stream = NULL;
3054 GstFlowReturn ret = GST_FLOW_OK;
3055 gboolean readblock = FALSE;
3057 guint64 block_duration = -1;
3058 GstBuffer *buf = NULL;
3060 gint stream_num = -1, n, laces = 0;
3062 gint *lace_size = NULL;
3065 gint64 referenceblock = 0;
3068 offset = gst_ebml_read_get_offset (ebml);
3070 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3071 if (!is_simpleblock) {
3072 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK) {
3076 id = GST_MATROSKA_ID_SIMPLEBLOCK;
3080 /* one block inside the group. Note, block parsing is one
3081 * of the harder things, so this code is a bit complicated.
3082 * See http://www.matroska.org/ for documentation. */
3083 case GST_MATROSKA_ID_SIMPLEBLOCK:
3084 case GST_MATROSKA_ID_BLOCK:
3090 gst_buffer_unmap (buf, &map);
3091 gst_buffer_unref (buf);
3094 if ((ret = gst_ebml_read_buffer (ebml, &id, &buf)) != GST_FLOW_OK)
3097 gst_buffer_map (buf, &map, GST_MAP_READ);
3101 /* first byte(s): blocknum */
3102 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
3107 /* fetch stream from num */
3108 stream_num = gst_matroska_read_common_stream_from_num (&demux->common,
3110 if (G_UNLIKELY (size < 3)) {
3111 GST_WARNING_OBJECT (demux, "Invalid size %u", size);
3112 /* non-fatal, try next block(group) */
3115 } else if (G_UNLIKELY (stream_num < 0 ||
3116 stream_num >= demux->common.num_streams)) {
3117 /* let's not give up on a stray invalid track number */
3118 GST_WARNING_OBJECT (demux,
3119 "Invalid stream %d for track number %" G_GUINT64_FORMAT
3120 "; ignoring block", stream_num, num);
3124 stream = g_ptr_array_index (demux->common.src, stream_num);
3126 /* time (relative to cluster time) */
3127 time = ((gint16) GST_READ_UINT16_BE (data));
3130 flags = GST_READ_UINT8 (data);
3134 GST_LOG_OBJECT (demux, "time %" G_GUINT64_FORMAT ", flags %d", time,
3137 switch ((flags & 0x06) >> 1) {
3138 case 0x0: /* no lacing */
3140 lace_size = g_new (gint, 1);
3141 lace_size[0] = size;
3144 case 0x1: /* xiph lacing */
3145 case 0x2: /* fixed-size lacing */
3146 case 0x3: /* EBML lacing */
3148 goto invalid_lacing;
3149 laces = GST_READ_UINT8 (data) + 1;
3152 lace_size = g_new0 (gint, laces);
3154 switch ((flags & 0x06) >> 1) {
3155 case 0x1: /* xiph lacing */ {
3156 guint temp, total = 0;
3158 for (n = 0; ret == GST_FLOW_OK && n < laces - 1; n++) {
3161 goto invalid_lacing;
3162 temp = GST_READ_UINT8 (data);
3163 lace_size[n] += temp;
3169 total += lace_size[n];
3171 lace_size[n] = size - total;
3175 case 0x2: /* fixed-size lacing */
3176 for (n = 0; n < laces; n++)
3177 lace_size[n] = size / laces;
3180 case 0x3: /* EBML lacing */ {
3183 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
3187 total = lace_size[0] = num;
3188 for (n = 1; ret == GST_FLOW_OK && n < laces - 1; n++) {
3192 if ((r = gst_matroska_ebmlnum_sint (data, size, &snum)) < 0)
3196 lace_size[n] = lace_size[n - 1] + snum;
3197 total += lace_size[n];
3200 lace_size[n] = size - total;
3207 if (ret != GST_FLOW_OK)
3214 case GST_MATROSKA_ID_BLOCKDURATION:{
3215 ret = gst_ebml_read_uint (ebml, &id, &block_duration);
3216 GST_DEBUG_OBJECT (demux, "BlockDuration: %" G_GUINT64_FORMAT,
3221 case GST_MATROSKA_ID_REFERENCEBLOCK:{
3222 ret = gst_ebml_read_sint (ebml, &id, &referenceblock);
3223 GST_DEBUG_OBJECT (demux, "ReferenceBlock: %" G_GINT64_FORMAT,
3228 case GST_MATROSKA_ID_CODECSTATE:{
3230 guint64 data_len = 0;
3233 gst_ebml_read_binary (ebml, &id, &data,
3234 &data_len)) != GST_FLOW_OK)
3237 if (G_UNLIKELY (stream == NULL)) {
3238 GST_WARNING_OBJECT (demux,
3239 "Unexpected CodecState subelement - ignoring");
3243 g_free (stream->codec_state);
3244 stream->codec_state = data;
3245 stream->codec_state_size = data_len;
3247 /* Decode if necessary */
3248 if (stream->encodings && stream->encodings->len > 0
3249 && stream->codec_state && stream->codec_state_size > 0) {
3250 if (!gst_matroska_decode_data (stream->encodings,
3251 &stream->codec_state, &stream->codec_state_size,
3252 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
3253 GST_WARNING_OBJECT (demux, "Decoding codec state failed");
3257 GST_DEBUG_OBJECT (demux, "CodecState of %" G_GSIZE_FORMAT " bytes",
3258 stream->codec_state_size);
3263 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3267 case GST_MATROSKA_ID_BLOCKVIRTUAL:
3268 case GST_MATROSKA_ID_BLOCKADDITIONS:
3269 case GST_MATROSKA_ID_REFERENCEPRIORITY:
3270 case GST_MATROSKA_ID_REFERENCEVIRTUAL:
3271 case GST_MATROSKA_ID_SLICES:
3272 GST_DEBUG_OBJECT (demux,
3273 "Skipping BlockGroup subelement 0x%x - ignoring", id);
3274 ret = gst_ebml_read_skip (ebml);
3282 /* reading a number or so could have failed */
3283 if (ret != GST_FLOW_OK)
3286 if (ret == GST_FLOW_OK && readblock) {
3287 gboolean invisible_frame = FALSE;
3288 gboolean delta_unit = FALSE;
3289 guint64 duration = 0;
3290 gint64 lace_time = 0;
3292 stream = g_ptr_array_index (demux->common.src, stream_num);
3294 if (cluster_time != GST_CLOCK_TIME_NONE) {
3295 /* FIXME: What to do with negative timestamps? Give timestamp 0 or -1?
3296 * Drop unless the lace contains timestamp 0? */
3297 if (time < 0 && (-time) > cluster_time) {
3300 if (stream->timecodescale == 1.0)
3301 lace_time = (cluster_time + time) * demux->common.time_scale;
3304 gst_util_guint64_to_gdouble ((cluster_time + time) *
3305 demux->common.time_scale) * stream->timecodescale;
3308 lace_time = GST_CLOCK_TIME_NONE;
3311 /* need to refresh segment info ASAP */
3312 if (GST_CLOCK_TIME_IS_VALID (lace_time) && demux->need_segment) {
3313 GstSegment *segment = &demux->common.segment;
3315 GstEvent *segment_event;
3317 if (!GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
3318 demux->stream_start_time = lace_time;
3319 GST_DEBUG_OBJECT (demux,
3320 "Setting stream start time to %" GST_TIME_FORMAT,
3321 GST_TIME_ARGS (lace_time));
3323 clace_time = MAX (lace_time, demux->stream_start_time);
3324 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.position) &&
3325 demux->common.segment.position != 0) {
3326 GST_DEBUG_OBJECT (demux,
3327 "using stored seek position %" GST_TIME_FORMAT,
3328 GST_TIME_ARGS (demux->common.segment.position));
3329 clace_time = demux->common.segment.position + demux->stream_start_time;
3330 segment->position = GST_CLOCK_TIME_NONE;
3332 segment->start = clace_time;
3333 segment->stop = GST_CLOCK_TIME_NONE;
3334 segment->time = segment->start - demux->stream_start_time;
3335 segment->position = segment->start - demux->stream_start_time;
3336 GST_DEBUG_OBJECT (demux,
3337 "generated segment starting at %" GST_TIME_FORMAT ": %"
3338 GST_SEGMENT_FORMAT, GST_TIME_ARGS (lace_time), segment);
3339 /* now convey our segment notion downstream */
3340 segment_event = gst_event_new_segment (segment);
3341 if (demux->segment_seqnum)
3342 gst_event_set_seqnum (segment_event, demux->segment_seqnum);
3343 gst_matroska_demux_send_event (demux, segment_event);
3344 demux->need_segment = FALSE;
3345 demux->segment_seqnum = 0;
3348 /* send pending codec data headers for all streams,
3349 * before we perform sync across all streams */
3350 gst_matroska_demux_push_codec_data_all (demux);
3352 if (block_duration != -1) {
3353 if (stream->timecodescale == 1.0)
3354 duration = gst_util_uint64_scale (block_duration,
3355 demux->common.time_scale, 1);
3358 gst_util_gdouble_to_guint64 (gst_util_guint64_to_gdouble
3359 (gst_util_uint64_scale (block_duration, demux->common.time_scale,
3360 1)) * stream->timecodescale);
3361 } else if (stream->default_duration) {
3362 duration = stream->default_duration * laces;
3364 /* else duration is diff between timecode of this and next block */
3366 /* For SimpleBlock, look at the keyframe bit in flags. Otherwise,
3367 a ReferenceBlock implies that this is not a keyframe. In either
3368 case, it only makes sense for video streams. */
3369 if (stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
3370 if ((is_simpleblock && !(flags & 0x80)) || referenceblock) {
3372 invisible_frame = ((flags & 0x08)) &&
3373 (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8) ||
3374 !strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP9));
3378 for (n = 0; n < laces; n++) {
3381 if (G_UNLIKELY (lace_size[n] > size)) {
3382 GST_WARNING_OBJECT (demux, "Invalid lace size");
3386 /* QoS for video track with an index. the assumption is that
3387 index entries point to keyframes, but if that is not true we
3388 will instad skip until the next keyframe. */
3389 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
3390 stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
3391 stream->index_table && demux->common.segment.rate > 0.0) {
3392 GstMatroskaTrackVideoContext *videocontext =
3393 (GstMatroskaTrackVideoContext *) stream;
3394 GstClockTime earliest_time;
3395 GstClockTime earliest_stream_time;
3397 GST_OBJECT_LOCK (demux);
3398 earliest_time = videocontext->earliest_time;
3399 GST_OBJECT_UNLOCK (demux);
3400 earliest_stream_time = gst_segment_to_position (&demux->common.segment,
3401 GST_FORMAT_TIME, earliest_time);
3403 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
3404 GST_CLOCK_TIME_IS_VALID (earliest_stream_time) &&
3405 lace_time <= earliest_stream_time) {
3406 /* find index entry (keyframe) <= earliest_stream_time */
3407 GstMatroskaIndex *entry =
3408 gst_util_array_binary_search (stream->index_table->data,
3409 stream->index_table->len, sizeof (GstMatroskaIndex),
3410 (GCompareDataFunc) gst_matroska_index_seek_find,
3411 GST_SEARCH_MODE_BEFORE, &earliest_stream_time, NULL);
3413 /* if that entry (keyframe) is after the current the current
3414 buffer, we can skip pushing (and thus decoding) all
3415 buffers until that keyframe. */
3416 if (entry && GST_CLOCK_TIME_IS_VALID (entry->time) &&
3417 entry->time > lace_time) {
3418 GST_LOG_OBJECT (demux, "Skipping lace before late keyframe");
3419 stream->set_discont = TRUE;
3425 sub = gst_buffer_copy_region (buf, GST_BUFFER_COPY_ALL,
3426 gst_buffer_get_size (buf) - size, lace_size[n]);
3427 GST_DEBUG_OBJECT (demux, "created subbuffer %p", sub);
3430 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
3432 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
3434 if (invisible_frame)
3435 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DECODE_ONLY);
3437 if (stream->encodings != NULL && stream->encodings->len > 0)
3438 sub = gst_matroska_decode_buffer (stream, sub);
3441 GST_WARNING_OBJECT (demux, "Decoding buffer failed");
3445 GST_BUFFER_TIMESTAMP (sub) = lace_time;
3447 if (GST_CLOCK_TIME_IS_VALID (lace_time)) {
3448 GstClockTime last_stop_end;
3450 /* Check if this stream is after segment stop */
3451 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop) &&
3452 lace_time >= demux->common.segment.stop) {
3453 GST_DEBUG_OBJECT (demux,
3454 "Stream %d after segment stop %" GST_TIME_FORMAT, stream->index,
3455 GST_TIME_ARGS (demux->common.segment.stop));
3456 gst_buffer_unref (sub);
3459 if (offset >= stream->to_offset
3460 || (GST_CLOCK_TIME_IS_VALID (demux->to_time)
3461 && lace_time > demux->to_time)) {
3462 GST_DEBUG_OBJECT (demux, "Stream %d after playback section",
3464 gst_buffer_unref (sub);
3468 /* handle gaps, e.g. non-zero start-time, or an cue index entry
3469 * that landed us with timestamps not quite intended */
3470 GST_OBJECT_LOCK (demux);
3471 if (demux->max_gap_time &&
3472 GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) &&
3473 demux->common.segment.rate > 0.0) {
3474 GstClockTimeDiff diff;
3476 /* only send segments with increasing start times,
3477 * otherwise if these go back and forth downstream (sinks) increase
3478 * accumulated time and running_time */
3479 diff = GST_CLOCK_DIFF (demux->last_stop_end, lace_time);
3480 if (diff > 0 && diff > demux->max_gap_time
3481 && lace_time > demux->common.segment.start
3482 && (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop)
3483 || lace_time < demux->common.segment.stop)) {
3485 GST_DEBUG_OBJECT (demux,
3486 "Gap of %" G_GINT64_FORMAT " ns detected in"
3487 "stream %d (%" GST_TIME_FORMAT " -> %" GST_TIME_FORMAT "). "
3488 "Sending updated SEGMENT events", diff,
3489 stream->index, GST_TIME_ARGS (stream->pos),
3490 GST_TIME_ARGS (lace_time));
3492 event = gst_event_new_gap (demux->last_stop_end, diff);
3493 GST_OBJECT_UNLOCK (demux);
3494 gst_pad_push_event (stream->pad, event);
3495 GST_OBJECT_LOCK (demux);
3499 if (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.position)
3500 || demux->common.segment.position < lace_time) {
3501 demux->common.segment.position = lace_time;
3503 GST_OBJECT_UNLOCK (demux);
3505 last_stop_end = lace_time;
3507 GST_BUFFER_DURATION (sub) = duration / laces;
3508 last_stop_end += GST_BUFFER_DURATION (sub);
3511 if (!GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) ||
3512 demux->last_stop_end < last_stop_end)
3513 demux->last_stop_end = last_stop_end;
3515 GST_OBJECT_LOCK (demux);
3516 if (demux->common.segment.duration == -1 ||
3517 demux->stream_start_time + demux->common.segment.duration <
3519 demux->common.segment.duration =
3520 last_stop_end - demux->stream_start_time;
3521 GST_OBJECT_UNLOCK (demux);
3522 if (!demux->invalid_duration) {
3523 gst_element_post_message (GST_ELEMENT_CAST (demux),
3524 gst_message_new_duration_changed (GST_OBJECT_CAST (demux)));
3525 demux->invalid_duration = TRUE;
3528 GST_OBJECT_UNLOCK (demux);
3532 stream->pos = lace_time;
3534 gst_matroska_demux_sync_streams (demux);
3536 if (stream->set_discont) {
3537 GST_DEBUG_OBJECT (demux, "marking DISCONT");
3538 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DISCONT);
3539 stream->set_discont = FALSE;
3541 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DISCONT);
3544 /* reverse playback book-keeping */
3545 if (!GST_CLOCK_TIME_IS_VALID (stream->from_time))
3546 stream->from_time = lace_time;
3547 if (stream->from_offset == -1)
3548 stream->from_offset = offset;
3550 GST_DEBUG_OBJECT (demux,
3551 "Pushing lace %d, data of size %" G_GSIZE_FORMAT
3552 " for stream %d, time=%" GST_TIME_FORMAT " and duration=%"
3553 GST_TIME_FORMAT, n, gst_buffer_get_size (sub), stream_num,
3554 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (sub)),
3555 GST_TIME_ARGS (GST_BUFFER_DURATION (sub)));
3558 if (demux->common.element_index) {
3559 if (stream->index_writer_id == -1)
3560 gst_index_get_writer_id (demux->common.element_index,
3561 GST_OBJECT (stream->pad), &stream->index_writer_id);
3563 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
3564 G_GUINT64_FORMAT " for writer id %d",
3565 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (sub)), cluster_offset,
3566 stream->index_writer_id);
3567 gst_index_add_association (demux->common.element_index,
3568 stream->index_writer_id, GST_BUFFER_FLAG_IS_SET (sub,
3569 GST_BUFFER_FLAG_DELTA_UNIT) ? 0 : GST_ASSOCIATION_FLAG_KEY_UNIT,
3570 GST_FORMAT_TIME, GST_BUFFER_TIMESTAMP (sub), GST_FORMAT_BYTES,
3571 cluster_offset, NULL);
3575 /* Postprocess the buffers depending on the codec used */
3576 if (stream->postprocess_frame) {
3577 GST_LOG_OBJECT (demux, "running post process");
3578 ret = stream->postprocess_frame (GST_ELEMENT (demux), stream, &sub);
3581 /* At this point, we have a sub-buffer pointing at data within a larger
3582 buffer. This data might not be aligned with anything. If the data is
3583 raw samples though, we want it aligned to the raw type (eg, 4 bytes
3584 for 32 bit samples, etc), or bad things will happen downstream as
3585 elements typically assume minimal alignment.
3586 Therefore, create an aligned copy if necessary. */
3587 g_assert (stream->alignment <= G_MEM_ALIGN);
3588 sub = gst_matroska_demux_align_buffer (demux, sub, stream->alignment);
3590 if (GST_BUFFER_PTS_IS_VALID (sub)) {
3591 stream->pos = GST_BUFFER_PTS (sub);
3592 if (GST_BUFFER_DURATION_IS_VALID (sub))
3593 stream->pos += GST_BUFFER_DURATION (sub);
3596 ret = gst_pad_push (stream->pad, sub);
3598 if (demux->common.segment.rate < 0) {
3599 if (lace_time > demux->common.segment.stop && ret == GST_FLOW_EOS) {
3600 /* In reverse playback we can get a GST_FLOW_EOS when
3601 * we are at the end of the segment, so we just need to jump
3602 * back to the previous section. */
3603 GST_DEBUG_OBJECT (demux, "downstream has reached end of segment");
3608 ret = gst_flow_combiner_update_flow (demux->flowcombiner, ret);
3611 size -= lace_size[n];
3612 if (lace_time != GST_CLOCK_TIME_NONE && duration)
3613 lace_time += duration / laces;
3615 lace_time = GST_CLOCK_TIME_NONE;
3621 gst_buffer_unmap (buf, &map);
3622 gst_buffer_unref (buf);
3634 ret = gst_flow_combiner_update_flow (demux->flowcombiner, ret);
3639 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Invalid lacing size"));
3640 /* non-fatal, try next block(group) */
3646 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Data error"));
3647 /* non-fatal, try next block(group) */
3653 /* return FALSE if block(group) should be skipped (due to a seek) */
3654 static inline gboolean
3655 gst_matroska_demux_seek_block (GstMatroskaDemux * demux)
3657 if (G_UNLIKELY (demux->seek_block)) {
3658 if (!(--demux->seek_block)) {
3661 GST_LOG_OBJECT (demux, "should skip block due to seek");
3669 static GstFlowReturn
3670 gst_matroska_demux_parse_contents_seekentry (GstMatroskaDemux * demux,
3674 guint64 seek_pos = (guint64) - 1;
3675 guint32 seek_id = 0;
3678 DEBUG_ELEMENT_START (demux, ebml, "Seek");
3680 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3681 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
3685 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3686 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3690 case GST_MATROSKA_ID_SEEKID:
3694 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
3697 GST_DEBUG_OBJECT (demux, "SeekID: %" G_GUINT64_FORMAT, t);
3702 case GST_MATROSKA_ID_SEEKPOSITION:
3706 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
3709 if (t > G_MAXINT64) {
3710 GST_WARNING_OBJECT (demux,
3711 "Too large SeekPosition %" G_GUINT64_FORMAT, t);
3715 GST_DEBUG_OBJECT (demux, "SeekPosition: %" G_GUINT64_FORMAT, t);
3721 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3727 if (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)
3730 if (!seek_id || seek_pos == (guint64) - 1) {
3731 GST_WARNING_OBJECT (demux, "Incomplete seekhead entry (0x%x/%"
3732 G_GUINT64_FORMAT ")", seek_id, seek_pos);
3737 case GST_MATROSKA_ID_SEEKHEAD:
3740 case GST_MATROSKA_ID_CUES:
3741 case GST_MATROSKA_ID_TAGS:
3742 case GST_MATROSKA_ID_TRACKS:
3743 case GST_MATROSKA_ID_SEGMENTINFO:
3744 case GST_MATROSKA_ID_ATTACHMENTS:
3745 case GST_MATROSKA_ID_CHAPTERS:
3747 guint64 before_pos, length;
3751 length = gst_matroska_read_common_get_length (&demux->common);
3752 before_pos = demux->common.offset;
3754 if (length == (guint64) - 1) {
3755 GST_DEBUG_OBJECT (demux, "no upstream length, skipping SeakHead entry");
3759 /* check for validity */
3760 if (seek_pos + demux->common.ebml_segment_start + 12 >= length) {
3761 GST_WARNING_OBJECT (demux,
3762 "SeekHead reference lies outside file!" " (%"
3763 G_GUINT64_FORMAT "+%" G_GUINT64_FORMAT "+12 >= %"
3764 G_GUINT64_FORMAT ")", seek_pos, demux->common.ebml_segment_start,
3769 /* only pick up index location when streaming */
3770 if (demux->streaming) {
3771 if (seek_id == GST_MATROSKA_ID_CUES) {
3772 demux->index_offset = seek_pos + demux->common.ebml_segment_start;
3773 GST_DEBUG_OBJECT (demux, "Cues located at offset %" G_GUINT64_FORMAT,
3774 demux->index_offset);
3780 demux->common.offset = seek_pos + demux->common.ebml_segment_start;
3783 if ((ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
3784 GST_ELEMENT_CAST (demux), &id, &length, &needed)) !=
3788 if (id != seek_id) {
3789 GST_WARNING_OBJECT (demux,
3790 "We looked for ID=0x%x but got ID=0x%x (pos=%" G_GUINT64_FORMAT ")",
3791 seek_id, id, seek_pos + demux->common.ebml_segment_start);
3794 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
3799 demux->common.offset = before_pos;
3803 case GST_MATROSKA_ID_CLUSTER:
3805 guint64 pos = seek_pos + demux->common.ebml_segment_start;
3807 GST_LOG_OBJECT (demux, "Cluster position");
3808 if (G_UNLIKELY (!demux->clusters))
3809 demux->clusters = g_array_sized_new (TRUE, TRUE, sizeof (guint64), 100);
3810 g_array_append_val (demux->clusters, pos);
3815 GST_DEBUG_OBJECT (demux, "Ignoring Seek entry for ID=0x%x", seek_id);
3818 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
3823 static GstFlowReturn
3824 gst_matroska_demux_parse_contents (GstMatroskaDemux * demux, GstEbmlRead * ebml)
3826 GstFlowReturn ret = GST_FLOW_OK;
3829 DEBUG_ELEMENT_START (demux, ebml, "SeekHead");
3831 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3832 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
3836 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3837 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3841 case GST_MATROSKA_ID_SEEKENTRY:
3843 ret = gst_matroska_demux_parse_contents_seekentry (demux, ebml);
3844 /* Ignore EOS and errors here */
3845 if (ret != GST_FLOW_OK) {
3846 GST_DEBUG_OBJECT (demux, "Ignoring %s", gst_flow_get_name (ret));
3853 ret = gst_matroska_read_common_parse_skip (&demux->common,
3854 ebml, "SeekHead", id);
3859 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
3861 /* Sort clusters by position for easier searching */
3862 if (demux->clusters)
3863 g_array_sort (demux->clusters, (GCompareFunc) gst_matroska_cluster_compare);
3868 #define GST_FLOW_OVERFLOW GST_FLOW_CUSTOM_ERROR
3870 #define MAX_BLOCK_SIZE (15 * 1024 * 1024)
3872 static inline GstFlowReturn
3873 gst_matroska_demux_check_read_size (GstMatroskaDemux * demux, guint64 bytes)
3875 if (G_UNLIKELY (bytes > MAX_BLOCK_SIZE)) {
3876 /* only a few blocks are expected/allowed to be large,
3877 * and will be recursed into, whereas others will be read and must fit */
3878 if (demux->streaming) {
3879 /* fatal in streaming case, as we can't step over easily */
3880 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
3881 ("reading large block of size %" G_GUINT64_FORMAT " not supported; "
3882 "file might be corrupt.", bytes));
3883 return GST_FLOW_ERROR;
3885 /* indicate higher level to quietly give up */
3886 GST_DEBUG_OBJECT (demux,
3887 "too large block of size %" G_GUINT64_FORMAT, bytes);
3888 return GST_FLOW_ERROR;
3895 /* returns TRUE if we truely are in error state, and should give up */
3896 static inline GstFlowReturn
3897 gst_matroska_demux_check_parse_error (GstMatroskaDemux * demux)
3899 if (!demux->streaming && demux->next_cluster_offset > 0) {
3900 /* just repositioning to where next cluster should be and try from there */
3901 GST_WARNING_OBJECT (demux, "parse error, trying next cluster expected at %"
3902 G_GUINT64_FORMAT, demux->next_cluster_offset);
3903 demux->common.offset = demux->next_cluster_offset;
3904 demux->next_cluster_offset = 0;
3910 /* sigh, one last attempt above and beyond call of duty ...;
3911 * search for cluster mark following current pos */
3912 pos = demux->common.offset;
3913 GST_WARNING_OBJECT (demux, "parse error, looking for next cluster");
3914 if ((ret = gst_matroska_demux_search_cluster (demux, &pos)) != GST_FLOW_OK) {
3915 /* did not work, give up */
3918 GST_DEBUG_OBJECT (demux, "... found at %" G_GUINT64_FORMAT, pos);
3919 /* try that position */
3920 demux->common.offset = pos;
3926 static inline GstFlowReturn
3927 gst_matroska_demux_flush (GstMatroskaDemux * demux, guint flush)
3929 GST_LOG_OBJECT (demux, "skipping %d bytes", flush);
3930 demux->common.offset += flush;
3931 if (demux->streaming) {
3934 /* hard to skip large blocks when streaming */
3935 ret = gst_matroska_demux_check_read_size (demux, flush);
3936 if (ret != GST_FLOW_OK)
3938 if (flush <= gst_adapter_available (demux->common.adapter))
3939 gst_adapter_flush (demux->common.adapter, flush);
3941 return GST_FLOW_EOS;
3946 /* initializes @ebml with @bytes from input stream at current offset.
3947 * Returns EOS if insufficient available,
3948 * ERROR if too much was attempted to read. */
3949 static inline GstFlowReturn
3950 gst_matroska_demux_take (GstMatroskaDemux * demux, guint64 bytes,
3953 GstBuffer *buffer = NULL;
3954 GstFlowReturn ret = GST_FLOW_OK;
3956 GST_LOG_OBJECT (demux, "taking %" G_GUINT64_FORMAT " bytes for parsing",
3958 ret = gst_matroska_demux_check_read_size (demux, bytes);
3959 if (G_UNLIKELY (ret != GST_FLOW_OK)) {
3960 if (!demux->streaming) {
3961 /* in pull mode, we can skip */
3962 if ((ret = gst_matroska_demux_flush (demux, bytes)) == GST_FLOW_OK)
3963 ret = GST_FLOW_OVERFLOW;
3965 /* otherwise fatal */
3966 ret = GST_FLOW_ERROR;
3970 if (demux->streaming) {
3971 if (gst_adapter_available (demux->common.adapter) >= bytes)
3972 buffer = gst_adapter_take_buffer (demux->common.adapter, bytes);
3976 ret = gst_matroska_read_common_peek_bytes (&demux->common,
3977 demux->common.offset, bytes, &buffer, NULL);
3978 if (G_LIKELY (buffer)) {
3979 gst_ebml_read_init (ebml, GST_ELEMENT_CAST (demux), buffer,
3980 demux->common.offset);
3981 demux->common.offset += bytes;
3988 gst_matroska_demux_check_seekability (GstMatroskaDemux * demux)
3991 gboolean seekable = FALSE;
3992 gint64 start = -1, stop = -1;
3994 query = gst_query_new_seeking (GST_FORMAT_BYTES);
3995 if (!gst_pad_peer_query (demux->common.sinkpad, query)) {
3996 GST_DEBUG_OBJECT (demux, "seeking query failed");
4000 gst_query_parse_seeking (query, NULL, &seekable, &start, &stop);
4002 /* try harder to query upstream size if we didn't get it the first time */
4003 if (seekable && stop == -1) {
4004 GST_DEBUG_OBJECT (demux, "doing duration query to fix up unset stop");
4005 gst_pad_peer_query_duration (demux->common.sinkpad, GST_FORMAT_BYTES,
4009 /* if upstream doesn't know the size, it's likely that it's not seekable in
4010 * practice even if it technically may be seekable */
4011 if (seekable && (start != 0 || stop <= start)) {
4012 GST_DEBUG_OBJECT (demux, "seekable but unknown start/stop -> disable");
4017 GST_INFO_OBJECT (demux, "seekable: %d (%" G_GUINT64_FORMAT " - %"
4018 G_GUINT64_FORMAT ")", seekable, start, stop);
4019 demux->seekable = seekable;
4021 gst_query_unref (query);
4024 static GstFlowReturn
4025 gst_matroska_demux_find_tracks (GstMatroskaDemux * demux)
4031 GstFlowReturn ret = GST_FLOW_OK;
4033 GST_WARNING_OBJECT (demux,
4034 "Found Cluster element before Tracks, searching Tracks");
4037 before_pos = demux->common.offset;
4039 /* Search Tracks element */
4041 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4042 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4043 if (ret != GST_FLOW_OK)
4046 if (id != GST_MATROSKA_ID_TRACKS) {
4047 /* we may be skipping large cluster here, so forego size check etc */
4048 /* ... but we can't skip undefined size; force error */
4049 if (length == G_MAXUINT64) {
4050 ret = gst_matroska_demux_check_read_size (demux, length);
4053 demux->common.offset += needed;
4054 demux->common.offset += length;
4059 /* will lead to track parsing ... */
4060 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4065 demux->common.offset = before_pos;
4070 #define GST_READ_CHECK(stmt) \
4072 if (G_UNLIKELY ((ret = (stmt)) != GST_FLOW_OK)) { \
4073 if (ret == GST_FLOW_OVERFLOW) { \
4074 ret = GST_FLOW_OK; \
4080 static GstFlowReturn
4081 gst_matroska_demux_parse_id (GstMatroskaDemux * demux, guint32 id,
4082 guint64 length, guint needed)
4084 GstEbmlRead ebml = { 0, };
4085 GstFlowReturn ret = GST_FLOW_OK;
4088 GST_LOG_OBJECT (demux, "Parsing Element id 0x%x, "
4089 "size %" G_GUINT64_FORMAT ", prefix %d", id, length, needed);
4091 /* if we plan to read and parse this element, we need prefix (id + length)
4092 * and the contents */
4093 /* mind about overflow wrap-around when dealing with undefined size */
4095 if (G_LIKELY (length != G_MAXUINT64))
4098 switch (demux->common.state) {
4099 case GST_MATROSKA_READ_STATE_START:
4101 case GST_EBML_ID_HEADER:
4102 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4103 ret = gst_matroska_read_common_parse_header (&demux->common, &ebml);
4104 if (ret != GST_FLOW_OK)
4106 demux->common.state = GST_MATROSKA_READ_STATE_SEGMENT;
4107 gst_matroska_demux_check_seekability (demux);
4110 goto invalid_header;
4114 case GST_MATROSKA_READ_STATE_SEGMENT:
4116 case GST_MATROSKA_ID_SEGMENT:
4117 /* eat segment prefix */
4118 GST_READ_CHECK (gst_matroska_demux_flush (demux, needed));
4119 GST_DEBUG_OBJECT (demux,
4120 "Found Segment start at offset %" G_GUINT64_FORMAT " with size %"
4121 G_GUINT64_FORMAT, demux->common.offset, length);
4122 /* seeks are from the beginning of the segment,
4123 * after the segment ID/length */
4124 demux->common.ebml_segment_start = demux->common.offset;
4126 length = G_MAXUINT64;
4127 demux->common.ebml_segment_length = length;
4128 demux->common.state = GST_MATROSKA_READ_STATE_HEADER;
4131 GST_WARNING_OBJECT (demux,
4132 "Expected a Segment ID (0x%x), but received 0x%x!",
4133 GST_MATROSKA_ID_SEGMENT, id);
4134 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4138 case GST_MATROSKA_READ_STATE_SCANNING:
4139 if (id != GST_MATROSKA_ID_CLUSTER &&
4140 id != GST_MATROSKA_ID_CLUSTERTIMECODE)
4143 case GST_MATROSKA_READ_STATE_HEADER:
4144 case GST_MATROSKA_READ_STATE_DATA:
4145 case GST_MATROSKA_READ_STATE_SEEK:
4147 case GST_MATROSKA_ID_SEGMENTINFO:
4148 if (!demux->common.segmentinfo_parsed) {
4149 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4150 ret = gst_matroska_read_common_parse_info (&demux->common,
4151 GST_ELEMENT_CAST (demux), &ebml);
4153 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4156 case GST_MATROSKA_ID_TRACKS:
4157 if (!demux->tracks_parsed) {
4158 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4159 ret = gst_matroska_demux_parse_tracks (demux, &ebml);
4161 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4164 case GST_MATROSKA_ID_CLUSTER:
4165 if (G_UNLIKELY (!demux->tracks_parsed)) {
4166 if (demux->streaming) {
4167 GST_DEBUG_OBJECT (demux, "Cluster before Track");
4168 goto not_streamable;
4170 ret = gst_matroska_demux_find_tracks (demux);
4171 if (!demux->tracks_parsed)
4175 if (G_UNLIKELY (demux->common.state
4176 == GST_MATROSKA_READ_STATE_HEADER)) {
4177 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
4178 demux->first_cluster_offset = demux->common.offset;
4179 GST_DEBUG_OBJECT (demux, "signaling no more pads");
4180 gst_element_no_more_pads (GST_ELEMENT (demux));
4181 /* send initial segment - we wait till we know the first
4182 incoming timestamp, so we can properly set the start of
4184 demux->need_segment = TRUE;
4186 demux->cluster_time = GST_CLOCK_TIME_NONE;
4187 demux->cluster_offset = demux->common.offset;
4188 if (G_UNLIKELY (!demux->seek_first && demux->seek_block)) {
4189 GST_DEBUG_OBJECT (demux, "seek target block %" G_GUINT64_FORMAT
4190 " not found in Cluster, trying next Cluster's first block instead",
4192 demux->seek_block = 0;
4194 demux->seek_first = FALSE;
4195 /* record next cluster for recovery */
4196 if (read != G_MAXUINT64)
4197 demux->next_cluster_offset = demux->cluster_offset + read;
4198 /* eat cluster prefix */
4199 gst_matroska_demux_flush (demux, needed);
4201 case GST_MATROSKA_ID_CLUSTERTIMECODE:
4205 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4206 if ((ret = gst_ebml_read_uint (&ebml, &id, &num)) != GST_FLOW_OK)
4208 GST_DEBUG_OBJECT (demux, "ClusterTimeCode: %" G_GUINT64_FORMAT, num);
4209 demux->cluster_time = num;
4211 if (demux->common.element_index) {
4212 if (demux->common.element_index_writer_id == -1)
4213 gst_index_get_writer_id (demux->common.element_index,
4214 GST_OBJECT (demux), &demux->common.element_index_writer_id);
4215 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
4216 G_GUINT64_FORMAT " for writer id %d",
4217 GST_TIME_ARGS (demux->cluster_time), demux->cluster_offset,
4218 demux->common.element_index_writer_id);
4219 gst_index_add_association (demux->common.element_index,
4220 demux->common.element_index_writer_id,
4221 GST_ASSOCIATION_FLAG_KEY_UNIT,
4222 GST_FORMAT_TIME, demux->cluster_time,
4223 GST_FORMAT_BYTES, demux->cluster_offset, NULL);
4228 case GST_MATROSKA_ID_BLOCKGROUP:
4229 if (!gst_matroska_demux_seek_block (demux))
4231 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4232 DEBUG_ELEMENT_START (demux, &ebml, "BlockGroup");
4233 if ((ret = gst_ebml_read_master (&ebml, &id)) == GST_FLOW_OK) {
4234 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4235 &ebml, demux->cluster_time, demux->cluster_offset, FALSE);
4237 DEBUG_ELEMENT_STOP (demux, &ebml, "BlockGroup", ret);
4239 case GST_MATROSKA_ID_SIMPLEBLOCK:
4240 if (!gst_matroska_demux_seek_block (demux))
4242 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4243 DEBUG_ELEMENT_START (demux, &ebml, "SimpleBlock");
4244 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4245 &ebml, demux->cluster_time, demux->cluster_offset, TRUE);
4246 DEBUG_ELEMENT_STOP (demux, &ebml, "SimpleBlock", ret);
4248 case GST_MATROSKA_ID_ATTACHMENTS:
4249 if (!demux->common.attachments_parsed) {
4250 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4251 ret = gst_matroska_read_common_parse_attachments (&demux->common,
4252 GST_ELEMENT_CAST (demux), &ebml);
4254 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4257 case GST_MATROSKA_ID_TAGS:
4258 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4259 ret = gst_matroska_read_common_parse_metadata (&demux->common,
4260 GST_ELEMENT_CAST (demux), &ebml);
4262 case GST_MATROSKA_ID_CHAPTERS:
4263 if (!demux->common.chapters_parsed) {
4264 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4266 gst_matroska_read_common_parse_chapters (&demux->common, &ebml);
4268 if (demux->common.toc) {
4269 gst_matroska_demux_send_event (demux,
4270 gst_event_new_toc (demux->common.toc, FALSE));
4273 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4275 case GST_MATROSKA_ID_SEEKHEAD:
4276 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4277 ret = gst_matroska_demux_parse_contents (demux, &ebml);
4279 case GST_MATROSKA_ID_CUES:
4280 if (demux->common.index_parsed) {
4281 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4284 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4285 ret = gst_matroska_read_common_parse_index (&demux->common, &ebml);
4286 /* only push based; delayed index building */
4287 if (ret == GST_FLOW_OK
4288 && demux->common.state == GST_MATROSKA_READ_STATE_SEEK) {
4291 GST_OBJECT_LOCK (demux);
4292 event = demux->seek_event;
4293 demux->seek_event = NULL;
4294 GST_OBJECT_UNLOCK (demux);
4297 /* unlikely to fail, since we managed to seek to this point */
4298 if (!gst_matroska_demux_handle_seek_event (demux, NULL, event))
4300 /* resume data handling, main thread clear to seek again */
4301 GST_OBJECT_LOCK (demux);
4302 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
4303 GST_OBJECT_UNLOCK (demux);
4306 case GST_MATROSKA_ID_POSITION:
4307 case GST_MATROSKA_ID_PREVSIZE:
4308 case GST_MATROSKA_ID_ENCRYPTEDBLOCK:
4309 case GST_MATROSKA_ID_SILENTTRACKS:
4310 GST_DEBUG_OBJECT (demux,
4311 "Skipping Cluster subelement 0x%x - ignoring", id);
4315 GST_DEBUG_OBJECT (demux, "skipping Element 0x%x", id);
4316 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4322 if (ret == GST_FLOW_PARSE)
4326 gst_ebml_read_clear (&ebml);
4332 /* simply exit, maybe not enough data yet */
4333 /* no ebml to clear if read error */
4338 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4339 ("Failed to parse Element 0x%x", id));
4340 ret = GST_FLOW_ERROR;
4345 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4346 ("File layout does not permit streaming"));
4347 ret = GST_FLOW_ERROR;
4352 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4353 ("No Tracks element found"));
4354 ret = GST_FLOW_ERROR;
4359 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Invalid header"));
4360 ret = GST_FLOW_ERROR;
4365 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Failed to seek"));
4366 ret = GST_FLOW_ERROR;
4372 gst_matroska_demux_loop (GstPad * pad)
4374 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (pad));
4380 /* If we have to close a segment, send a new segment to do this now */
4381 if (G_LIKELY (demux->common.state == GST_MATROSKA_READ_STATE_DATA)) {
4382 if (G_UNLIKELY (demux->new_segment)) {
4383 gst_matroska_demux_send_event (demux, demux->new_segment);
4384 demux->new_segment = NULL;
4388 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4389 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4390 if (ret == GST_FLOW_EOS) {
4392 } else if (ret == GST_FLOW_FLUSHING) {
4394 } else if (ret != GST_FLOW_OK) {
4395 ret = gst_matroska_demux_check_parse_error (demux);
4397 /* Only handle EOS as no error if we're outside the segment already */
4398 if (ret == GST_FLOW_EOS && (demux->common.ebml_segment_length != G_MAXUINT64
4399 && demux->common.offset >=
4400 demux->common.ebml_segment_start +
4401 demux->common.ebml_segment_length))
4403 else if (ret != GST_FLOW_OK)
4409 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
4410 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
4413 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4414 if (ret == GST_FLOW_EOS)
4416 if (ret != GST_FLOW_OK)
4419 /* check if we're at the end of a configured segment */
4420 if (G_LIKELY (demux->common.src->len)) {
4423 g_assert (demux->common.num_streams == demux->common.src->len);
4424 for (i = 0; i < demux->common.src->len; i++) {
4425 GstMatroskaTrackContext *context = g_ptr_array_index (demux->common.src,
4427 GST_DEBUG_OBJECT (context->pad, "pos %" GST_TIME_FORMAT,
4428 GST_TIME_ARGS (context->pos));
4429 if (context->eos == FALSE)
4433 GST_INFO_OBJECT (demux, "All streams are EOS");
4439 if (G_UNLIKELY (demux->common.offset ==
4440 gst_matroska_read_common_get_length (&demux->common))) {
4441 GST_LOG_OBJECT (demux, "Reached end of stream");
4451 if (demux->common.segment.rate < 0.0) {
4452 ret = gst_matroska_demux_seek_to_previous_keyframe (demux);
4453 if (ret == GST_FLOW_OK)
4460 const gchar *reason = gst_flow_get_name (ret);
4461 gboolean push_eos = FALSE;
4463 GST_LOG_OBJECT (demux, "pausing task, reason %s", reason);
4464 gst_pad_pause_task (demux->common.sinkpad);
4466 if (ret == GST_FLOW_EOS) {
4467 /* perform EOS logic */
4469 /* If we were in the headers, make sure we send no-more-pads.
4470 This will ensure decodebin2 does not get stuck thinking
4471 the chain is not complete yet, and waiting indefinitely. */
4472 if (G_UNLIKELY (demux->common.state == GST_MATROSKA_READ_STATE_HEADER)) {
4473 if (demux->common.src->len == 0) {
4474 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
4475 ("No pads created"));
4477 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL),
4478 ("Failed to finish reading headers"));
4480 gst_element_no_more_pads (GST_ELEMENT (demux));
4483 if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
4486 /* for segment playback we need to post when (in stream time)
4487 * we stopped, this is either stop (when set) or the duration. */
4488 if ((stop = demux->common.segment.stop) == -1)
4489 stop = demux->last_stop_end;
4491 GST_LOG_OBJECT (demux, "Sending segment done, at end of segment");
4492 gst_element_post_message (GST_ELEMENT (demux),
4493 gst_message_new_segment_done (GST_OBJECT (demux), GST_FORMAT_TIME,
4495 gst_matroska_demux_send_event (demux,
4496 gst_event_new_segment_done (GST_FORMAT_TIME, stop));
4500 } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS) {
4501 /* for fatal errors we post an error message */
4502 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
4503 ("stream stopped, reason %s", reason));
4507 /* send EOS, and prevent hanging if no streams yet */
4508 GST_LOG_OBJECT (demux, "Sending EOS, at end of stream");
4509 if (!gst_matroska_demux_send_event (demux, gst_event_new_eos ()) &&
4510 (ret == GST_FLOW_EOS)) {
4511 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4512 (NULL), ("got eos but no streams (yet)"));
4520 * Create and push a flushing seek event upstream
4523 perform_seek_to_offset (GstMatroskaDemux * demux, gdouble rate, guint64 offset,
4529 GST_DEBUG_OBJECT (demux, "Seeking to %" G_GUINT64_FORMAT, offset);
4532 gst_event_new_seek (rate, GST_FORMAT_BYTES,
4533 GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, GST_SEEK_TYPE_SET, offset,
4534 GST_SEEK_TYPE_NONE, -1);
4535 gst_event_set_seqnum (event, seqnum);
4537 res = gst_pad_push_event (demux->common.sinkpad, event);
4539 /* segment event will update offset */
4543 static GstFlowReturn
4544 gst_matroska_demux_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
4546 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4548 GstFlowReturn ret = GST_FLOW_OK;
4553 if (G_UNLIKELY (GST_BUFFER_IS_DISCONT (buffer))) {
4554 GST_DEBUG_OBJECT (demux, "got DISCONT");
4555 gst_adapter_clear (demux->common.adapter);
4556 GST_OBJECT_LOCK (demux);
4557 gst_matroska_read_common_reset_streams (&demux->common,
4558 GST_CLOCK_TIME_NONE, FALSE);
4559 GST_OBJECT_UNLOCK (demux);
4562 gst_adapter_push (demux->common.adapter, buffer);
4566 available = gst_adapter_available (demux->common.adapter);
4568 ret = gst_matroska_read_common_peek_id_length_push (&demux->common,
4569 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4570 if (G_UNLIKELY (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)) {
4571 if (demux->common.ebml_segment_length != G_MAXUINT64
4572 && demux->common.offset >=
4573 demux->common.ebml_segment_start + demux->common.ebml_segment_length)
4578 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
4579 "size %" G_GUINT64_FORMAT ", needed %d, available %d",
4580 demux->common.offset, id, length, needed, available);
4582 if (needed > available)
4585 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4586 if (ret == GST_FLOW_EOS) {
4587 /* need more data */
4589 } else if (ret != GST_FLOW_OK) {
4596 gst_matroska_demux_handle_sink_event (GstPad * pad, GstObject * parent,
4599 gboolean res = TRUE;
4600 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4602 GST_DEBUG_OBJECT (demux,
4603 "have event type %s: %p on sink pad", GST_EVENT_TYPE_NAME (event), event);
4605 switch (GST_EVENT_TYPE (event)) {
4606 case GST_EVENT_SEGMENT:
4608 const GstSegment *segment;
4610 /* some debug output */
4611 gst_event_parse_segment (event, &segment);
4612 /* FIXME: do we need to update segment base here (like accum in 0.10)? */
4613 GST_DEBUG_OBJECT (demux,
4614 "received format %d segment %" GST_SEGMENT_FORMAT, segment->format,
4617 if (demux->common.state < GST_MATROSKA_READ_STATE_DATA) {
4618 GST_DEBUG_OBJECT (demux, "still starting");
4622 /* we only expect a BYTE segment, e.g. following a seek */
4623 if (segment->format != GST_FORMAT_BYTES) {
4624 GST_DEBUG_OBJECT (demux, "unsupported segment format, ignoring");
4628 GST_DEBUG_OBJECT (demux, "clearing segment state");
4629 GST_OBJECT_LOCK (demux);
4630 /* clear current segment leftover */
4631 gst_adapter_clear (demux->common.adapter);
4632 /* and some streaming setup */
4633 demux->common.offset = segment->start;
4634 /* accumulate base based on current position */
4635 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.position))
4636 demux->common.segment.base +=
4637 (MAX (demux->common.segment.position, demux->stream_start_time)
4638 - demux->stream_start_time) / fabs (demux->common.segment.rate);
4639 /* do not know where we are;
4640 * need to come across a cluster and generate segment */
4641 demux->common.segment.position = GST_CLOCK_TIME_NONE;
4642 demux->cluster_time = GST_CLOCK_TIME_NONE;
4643 demux->cluster_offset = 0;
4644 demux->need_segment = TRUE;
4645 demux->segment_seqnum = gst_event_get_seqnum (event);
4646 /* but keep some of the upstream segment */
4647 demux->common.segment.rate = segment->rate;
4648 /* also check if need to keep some of the requested seek position */
4649 if (demux->seek_offset == segment->start) {
4650 GST_DEBUG_OBJECT (demux, "position matches requested seek");
4651 demux->common.segment.position = demux->requested_seek_time;
4653 GST_DEBUG_OBJECT (demux, "unexpected segment position");
4655 demux->requested_seek_time = GST_CLOCK_TIME_NONE;
4656 demux->seek_offset = -1;
4657 GST_OBJECT_UNLOCK (demux);
4659 /* chain will send initial segment after pads have been added,
4660 * or otherwise come up with one */
4661 GST_DEBUG_OBJECT (demux, "eating event");
4662 gst_event_unref (event);
4668 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
4669 gst_event_unref (event);
4670 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4671 (NULL), ("got eos and didn't receive a complete header object"));
4672 } else if (demux->common.num_streams == 0) {
4673 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4674 (NULL), ("got eos but no streams (yet)"));
4676 gst_matroska_demux_send_event (demux, event);
4680 case GST_EVENT_FLUSH_STOP:
4684 gst_adapter_clear (demux->common.adapter);
4685 GST_OBJECT_LOCK (demux);
4686 gst_matroska_read_common_reset_streams (&demux->common,
4687 GST_CLOCK_TIME_NONE, TRUE);
4688 dur = demux->common.segment.duration;
4689 gst_segment_init (&demux->common.segment, GST_FORMAT_TIME);
4690 demux->common.segment.duration = dur;
4691 demux->cluster_time = GST_CLOCK_TIME_NONE;
4692 demux->cluster_offset = 0;
4693 GST_OBJECT_UNLOCK (demux);
4697 res = gst_pad_event_default (pad, parent, event);
4705 gst_matroska_demux_sink_activate (GstPad * sinkpad, GstObject * parent)
4707 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4709 gboolean pull_mode = FALSE;
4711 query = gst_query_new_scheduling ();
4713 if (gst_pad_peer_query (sinkpad, query))
4714 pull_mode = gst_query_has_scheduling_mode_with_flags (query,
4715 GST_PAD_MODE_PULL, GST_SCHEDULING_FLAG_SEEKABLE);
4717 gst_query_unref (query);
4720 GST_DEBUG ("going to pull mode");
4721 demux->streaming = FALSE;
4722 return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PULL, TRUE);
4724 GST_DEBUG ("going to push (streaming) mode");
4725 demux->streaming = TRUE;
4726 return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PUSH, TRUE);
4731 gst_matroska_demux_sink_activate_mode (GstPad * sinkpad, GstObject * parent,
4732 GstPadMode mode, gboolean active)
4735 case GST_PAD_MODE_PULL:
4737 /* if we have a scheduler we can start the task */
4738 gst_pad_start_task (sinkpad, (GstTaskFunction) gst_matroska_demux_loop,
4741 gst_pad_stop_task (sinkpad);
4744 case GST_PAD_MODE_PUSH:
4752 gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext *
4753 videocontext, const gchar * codec_id, guint8 * data, guint size,
4754 gchar ** codec_name, guint32 * riff_fourcc)
4756 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) videocontext;
4757 GstCaps *caps = NULL;
4759 g_assert (videocontext != NULL);
4760 g_assert (codec_name != NULL);
4765 /* TODO: check if we have all codec types from matroska-ids.h
4766 * check if we have to do more special things with codec_private
4769 * GST_MATROSKA_CODEC_ID_VIDEO_QUICKTIME
4770 * GST_MATROSKA_CODEC_ID_VIDEO_SNOW
4773 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VFW_FOURCC)) {
4774 gst_riff_strf_vids *vids = NULL;
4777 GstBuffer *buf = NULL;
4779 vids = (gst_riff_strf_vids *) data;
4781 /* assure size is big enough */
4783 GST_WARNING ("Too small BITMAPINFOHEADER (%d bytes)", size);
4786 if (size < sizeof (gst_riff_strf_vids)) {
4787 vids = g_new (gst_riff_strf_vids, 1);
4788 memcpy (vids, data, size);
4791 /* little-endian -> byte-order */
4792 vids->size = GUINT32_FROM_LE (vids->size);
4793 vids->width = GUINT32_FROM_LE (vids->width);
4794 vids->height = GUINT32_FROM_LE (vids->height);
4795 vids->planes = GUINT16_FROM_LE (vids->planes);
4796 vids->bit_cnt = GUINT16_FROM_LE (vids->bit_cnt);
4797 vids->compression = GUINT32_FROM_LE (vids->compression);
4798 vids->image_size = GUINT32_FROM_LE (vids->image_size);
4799 vids->xpels_meter = GUINT32_FROM_LE (vids->xpels_meter);
4800 vids->ypels_meter = GUINT32_FROM_LE (vids->ypels_meter);
4801 vids->num_colors = GUINT32_FROM_LE (vids->num_colors);
4802 vids->imp_colors = GUINT32_FROM_LE (vids->imp_colors);
4804 if (size > sizeof (gst_riff_strf_vids)) { /* some extra_data */
4805 gsize offset = sizeof (gst_riff_strf_vids);
4808 gst_buffer_new_wrapped (g_memdup ((guint8 *) vids + offset,
4809 size - offset), size - offset);
4813 *riff_fourcc = vids->compression;
4815 caps = gst_riff_create_video_caps (vids->compression, NULL, vids,
4816 buf, NULL, codec_name);
4819 GST_WARNING ("Unhandled RIFF fourcc %" GST_FOURCC_FORMAT,
4820 GST_FOURCC_ARGS (vids->compression));
4824 gst_buffer_unref (buf);
4826 if (vids != (gst_riff_strf_vids *) data)
4829 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_UNCOMPRESSED)) {
4831 GstVideoFormat format;
4833 gst_video_info_init (&info);
4834 switch (videocontext->fourcc) {
4835 case GST_MAKE_FOURCC ('I', '4', '2', '0'):
4836 format = GST_VIDEO_FORMAT_I420;
4838 case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
4839 format = GST_VIDEO_FORMAT_YUY2;
4841 case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
4842 format = GST_VIDEO_FORMAT_YV12;
4844 case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
4845 format = GST_VIDEO_FORMAT_UYVY;
4847 case GST_MAKE_FOURCC ('A', 'Y', 'U', 'V'):
4848 format = GST_VIDEO_FORMAT_AYUV;
4850 case GST_MAKE_FOURCC ('Y', '8', '0', '0'):
4851 case GST_MAKE_FOURCC ('Y', '8', ' ', ' '):
4852 format = GST_VIDEO_FORMAT_GRAY8;
4854 case GST_MAKE_FOURCC ('R', 'G', 'B', 24):
4855 format = GST_VIDEO_FORMAT_RGB;
4857 case GST_MAKE_FOURCC ('B', 'G', 'R', 24):
4858 format = GST_VIDEO_FORMAT_BGR;
4861 GST_DEBUG ("Unknown fourcc %" GST_FOURCC_FORMAT,
4862 GST_FOURCC_ARGS (videocontext->fourcc));
4866 gst_video_info_set_format (&info, format, videocontext->pixel_width,
4867 videocontext->pixel_height);
4868 caps = gst_video_info_to_caps (&info);
4869 *codec_name = gst_pb_utils_get_codec_description (caps);
4870 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_SP)) {
4871 caps = gst_caps_new_simple ("video/x-divx",
4872 "divxversion", G_TYPE_INT, 4, NULL);
4873 *codec_name = g_strdup ("MPEG-4 simple profile");
4874 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP) ||
4875 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AP)) {
4876 caps = gst_caps_new_simple ("video/mpeg",
4877 "mpegversion", G_TYPE_INT, 4,
4878 "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
4882 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
4883 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
4884 gst_buffer_unref (priv);
4886 gst_codec_utils_mpeg4video_caps_set_level_and_profile (caps, data, size);
4888 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP))
4889 *codec_name = g_strdup ("MPEG-4 advanced simple profile");
4891 *codec_name = g_strdup ("MPEG-4 advanced profile");
4892 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MSMPEG4V3)) {
4894 caps = gst_caps_new_full (gst_structure_new ("video/x-divx",
4895 "divxversion", G_TYPE_INT, 3, NULL),
4896 gst_structure_new ("video/x-msmpeg",
4897 "msmpegversion", G_TYPE_INT, 43, NULL), NULL);
4899 caps = gst_caps_new_simple ("video/x-msmpeg",
4900 "msmpegversion", G_TYPE_INT, 43, NULL);
4901 *codec_name = g_strdup ("Microsoft MPEG-4 v.3");
4902 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1) ||
4903 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG2)) {
4906 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1))
4911 caps = gst_caps_new_simple ("video/mpeg",
4912 "systemstream", G_TYPE_BOOLEAN, FALSE,
4913 "mpegversion", G_TYPE_INT, mpegversion, NULL);
4914 *codec_name = g_strdup_printf ("MPEG-%d video", mpegversion);
4915 context->postprocess_frame = gst_matroska_demux_add_mpeg_seq_header;
4916 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MJPEG)) {
4917 caps = gst_caps_new_empty_simple ("image/jpeg");
4918 *codec_name = g_strdup ("Motion-JPEG");
4919 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AVC)) {
4920 caps = gst_caps_new_empty_simple ("video/x-h264");
4924 /* First byte is the version, second is the profile indication, and third
4925 * is the 5 contraint_set_flags and 3 reserved bits. Fourth byte is the
4926 * level indication. */
4927 gst_codec_utils_h264_caps_set_level_and_profile (caps, data + 1,
4930 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
4931 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
4932 gst_buffer_unref (priv);
4934 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "avc",
4935 "alignment", G_TYPE_STRING, "au", NULL);
4937 GST_WARNING ("No codec data found, assuming output is byte-stream");
4938 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
4941 *codec_name = g_strdup ("H264");
4942 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEGH_HEVC)) {
4943 caps = gst_caps_new_empty_simple ("video/x-h265");
4947 gst_codec_utils_h265_caps_set_level_tier_and_profile (caps, data + 1,
4950 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
4951 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
4952 gst_buffer_unref (priv);
4954 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "hvc1",
4955 "alignment", G_TYPE_STRING, "au", NULL);
4957 GST_WARNING ("No codec data found, assuming output is byte-stream");
4958 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
4961 *codec_name = g_strdup ("HEVC");
4962 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1)) ||
4963 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2)) ||
4964 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3)) ||
4965 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))) {
4966 gint rmversion = -1;
4968 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1))
4970 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2))
4972 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3))
4974 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))
4977 caps = gst_caps_new_simple ("video/x-pn-realvideo",
4978 "rmversion", G_TYPE_INT, rmversion, NULL);
4979 GST_DEBUG ("data:%p, size:0x%x", data, size);
4980 /* We need to extract the extradata ! */
4981 if (data && (size >= 0x22)) {
4986 subformat = GST_READ_UINT32_BE (data + 0x1a);
4987 rformat = GST_READ_UINT32_BE (data + 0x1e);
4990 gst_buffer_new_wrapped (g_memdup (data + 0x1a, size - 0x1a),
4992 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, "format",
4993 G_TYPE_INT, rformat, "subformat", G_TYPE_INT, subformat, NULL);
4994 gst_buffer_unref (priv);
4997 *codec_name = g_strdup_printf ("RealVideo %d.0", rmversion);
4998 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_THEORA)) {
4999 caps = gst_caps_new_empty_simple ("video/x-theora");
5000 context->stream_headers =
5001 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
5002 context->codec_priv_size);
5003 /* FIXME: mark stream as broken and skip if there are no stream headers */
5004 context->send_stream_headers = TRUE;
5005 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_DIRAC)) {
5006 caps = gst_caps_new_empty_simple ("video/x-dirac");
5007 *codec_name = g_strdup_printf ("Dirac");
5008 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8)) {
5009 caps = gst_caps_new_empty_simple ("video/x-vp8");
5010 *codec_name = g_strdup_printf ("On2 VP8");
5011 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP9)) {
5012 caps = gst_caps_new_empty_simple ("video/x-vp9");
5013 *codec_name = g_strdup_printf ("On2 VP9");
5015 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
5021 GstStructure *structure;
5023 for (i = 0; i < gst_caps_get_size (caps); i++) {
5024 structure = gst_caps_get_structure (caps, i);
5026 /* FIXME: use the real unit here! */
5027 GST_DEBUG ("video size %dx%d, target display size %dx%d (any unit)",
5028 videocontext->pixel_width,
5029 videocontext->pixel_height,
5030 videocontext->display_width, videocontext->display_height);
5032 /* pixel width and height are the w and h of the video in pixels */
5033 if (videocontext->pixel_width > 0 && videocontext->pixel_height > 0) {
5034 gint w = videocontext->pixel_width;
5035 gint h = videocontext->pixel_height;
5037 gst_structure_set (structure,
5038 "width", G_TYPE_INT, w, "height", G_TYPE_INT, h, NULL);
5041 if (videocontext->display_width > 0 || videocontext->display_height > 0) {
5044 if (videocontext->display_width <= 0)
5045 videocontext->display_width = videocontext->pixel_width;
5046 if (videocontext->display_height <= 0)
5047 videocontext->display_height = videocontext->pixel_height;
5049 /* calculate the pixel aspect ratio using the display and pixel w/h */
5050 n = videocontext->display_width * videocontext->pixel_height;
5051 d = videocontext->display_height * videocontext->pixel_width;
5052 GST_DEBUG ("setting PAR to %d/%d", n, d);
5053 gst_structure_set (structure, "pixel-aspect-ratio",
5055 videocontext->display_width * videocontext->pixel_height,
5056 videocontext->display_height * videocontext->pixel_width, NULL);
5059 if (videocontext->default_fps > 0.0) {
5062 gst_util_double_to_fraction (videocontext->default_fps, &fps_n, &fps_d);
5064 GST_DEBUG ("using default fps %d/%d", fps_n, fps_d);
5066 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION, fps_n,
5068 } else if (context->default_duration > 0) {
5071 gst_video_guess_framerate (context->default_duration, &fps_n, &fps_d);
5073 GST_INFO ("using default duration %" G_GUINT64_FORMAT
5074 " framerate %d/%d", context->default_duration, fps_n, fps_d);
5076 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
5077 fps_n, fps_d, NULL);
5079 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
5083 if (videocontext->parent.flags & GST_MATROSKA_VIDEOTRACK_INTERLACED)
5084 gst_structure_set (structure, "interlace-mode", G_TYPE_STRING,
5088 caps = gst_caps_simplify (caps);
5095 * Some AAC specific code... *sigh*
5096 * FIXME: maybe we should use '15' and code the sample rate explicitly
5097 * if the sample rate doesn't match the predefined rates exactly? (tpm)
5101 aac_rate_idx (gint rate)
5105 else if (75132 <= rate)
5107 else if (55426 <= rate)
5109 else if (46009 <= rate)
5111 else if (37566 <= rate)
5113 else if (27713 <= rate)
5115 else if (23004 <= rate)
5117 else if (18783 <= rate)
5119 else if (13856 <= rate)
5121 else if (11502 <= rate)
5123 else if (9391 <= rate)
5130 aac_profile_idx (const gchar * codec_id)
5134 if (strlen (codec_id) <= 12)
5136 else if (!strncmp (&codec_id[12], "MAIN", 4))
5138 else if (!strncmp (&codec_id[12], "LC", 2))
5140 else if (!strncmp (&codec_id[12], "SSR", 3))
5149 round_up_pow2 (guint n)
5160 #define AAC_SYNC_EXTENSION_TYPE 0x02b7
5163 gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext *
5164 audiocontext, const gchar * codec_id, guint8 * data, guint size,
5165 gchar ** codec_name, guint16 * riff_audio_fmt)
5167 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) audiocontext;
5168 GstCaps *caps = NULL;
5170 g_assert (audiocontext != NULL);
5171 g_assert (codec_name != NULL);
5174 *riff_audio_fmt = 0;
5176 /* TODO: check if we have all codec types from matroska-ids.h
5177 * check if we have to do more special things with codec_private
5178 * check if we need bitdepth in different places too
5179 * implement channel position magic
5181 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID9
5182 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID10
5183 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDMC
5184 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDM2
5187 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1) ||
5188 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2) ||
5189 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L3)) {
5192 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1))
5194 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2))
5199 caps = gst_caps_new_simple ("audio/mpeg",
5200 "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, layer, NULL);
5201 *codec_name = g_strdup_printf ("MPEG-1 layer %d", layer);
5202 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE) ||
5203 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_LE)) {
5206 GstAudioFormat format;
5208 sign = (audiocontext->bitdepth != 8);
5209 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE))
5210 endianness = G_BIG_ENDIAN;
5212 endianness = G_LITTLE_ENDIAN;
5214 format = gst_audio_format_build_integer (sign, endianness,
5215 audiocontext->bitdepth, audiocontext->bitdepth);
5217 /* FIXME: Channel mask and reordering */
5218 caps = gst_caps_new_simple ("audio/x-raw",
5219 "format", G_TYPE_STRING, gst_audio_format_to_string (format),
5220 "layout", G_TYPE_STRING, "interleaved", NULL);
5222 *codec_name = g_strdup_printf ("Raw %d-bit PCM audio",
5223 audiocontext->bitdepth);
5224 context->alignment = GST_ROUND_UP_8 (audiocontext->bitdepth) / 8;
5225 context->alignment = round_up_pow2 (context->alignment);
5226 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_FLOAT)) {
5227 const gchar *format;
5228 if (audiocontext->bitdepth == 32)
5232 /* FIXME: Channel mask and reordering */
5233 caps = gst_caps_new_simple ("audio/x-raw",
5234 "format", G_TYPE_STRING, format,
5235 "layout", G_TYPE_STRING, "interleaved", NULL);
5236 *codec_name = g_strdup_printf ("Raw %d-bit floating-point audio",
5237 audiocontext->bitdepth);
5238 context->alignment = audiocontext->bitdepth / 8;
5239 context->alignment = round_up_pow2 (context->alignment);
5240 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AC3,
5241 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AC3))) {
5242 caps = gst_caps_new_simple ("audio/x-ac3",
5243 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5244 *codec_name = g_strdup ("AC-3 audio");
5245 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_EAC3,
5246 strlen (GST_MATROSKA_CODEC_ID_AUDIO_EAC3))) {
5247 caps = gst_caps_new_simple ("audio/x-eac3",
5248 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5249 *codec_name = g_strdup ("E-AC-3 audio");
5250 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TRUEHD,
5251 strlen (GST_MATROSKA_CODEC_ID_AUDIO_TRUEHD))) {
5252 caps = gst_caps_new_empty_simple ("audio/x-true-hd");
5253 *codec_name = g_strdup ("Dolby TrueHD");
5254 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_DTS)) {
5255 caps = gst_caps_new_empty_simple ("audio/x-dts");
5256 *codec_name = g_strdup ("DTS audio");
5257 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_VORBIS)) {
5258 caps = gst_caps_new_empty_simple ("audio/x-vorbis");
5259 context->stream_headers =
5260 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
5261 context->codec_priv_size);
5262 /* FIXME: mark stream as broken and skip if there are no stream headers */
5263 context->send_stream_headers = TRUE;
5264 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_FLAC)) {
5265 caps = gst_caps_new_empty_simple ("audio/x-flac");
5266 context->stream_headers =
5267 gst_matroska_parse_flac_stream_headers (context->codec_priv,
5268 context->codec_priv_size);
5269 /* FIXME: mark stream as broken and skip if there are no stream headers */
5270 context->send_stream_headers = TRUE;
5271 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_SPEEX)) {
5272 caps = gst_caps_new_empty_simple ("audio/x-speex");
5273 context->stream_headers =
5274 gst_matroska_parse_speex_stream_headers (context->codec_priv,
5275 context->codec_priv_size);
5276 /* FIXME: mark stream as broken and skip if there are no stream headers */
5277 context->send_stream_headers = TRUE;
5278 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_OPUS)) {
5279 caps = gst_caps_new_empty_simple ("audio/x-opus");
5280 *codec_name = g_strdup ("Opus");
5281 context->stream_headers =
5282 gst_matroska_parse_opus_stream_headers (context->codec_priv,
5283 context->codec_priv_size);
5284 if (context->stream_headers) {
5285 /* There was a valid header. Multistream headers are more than
5286 * 19 bytes, as they include an extra channel mapping table. */
5287 gboolean multistream = (context->codec_priv_size > 19);
5288 gst_caps_set_simple (caps, "multistream", G_TYPE_BOOLEAN, multistream,
5291 /* FIXME: mark stream as broken and skip if there are no stream headers */
5292 context->send_stream_headers = TRUE;
5293 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_ACM)) {
5294 gst_riff_strf_auds auds;
5296 if (data && size >= 18) {
5297 GstBuffer *codec_data = NULL;
5299 /* little-endian -> byte-order */
5300 auds.format = GST_READ_UINT16_LE (data);
5301 auds.channels = GST_READ_UINT16_LE (data + 2);
5302 auds.rate = GST_READ_UINT32_LE (data + 4);
5303 auds.av_bps = GST_READ_UINT32_LE (data + 8);
5304 auds.blockalign = GST_READ_UINT16_LE (data + 12);
5305 auds.bits_per_sample = GST_READ_UINT16_LE (data + 16);
5307 /* 18 is the waveformatex size */
5309 codec_data = gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY,
5310 data + 18, size - 18, 0, size - 18, NULL, NULL);
5314 *riff_audio_fmt = auds.format;
5316 /* FIXME: Handle reorder map */
5317 caps = gst_riff_create_audio_caps (auds.format, NULL, &auds, NULL,
5318 codec_data, codec_name, NULL);
5320 gst_buffer_unref (codec_data);
5323 GST_WARNING ("Unhandled RIFF audio format 0x%02x", auds.format);
5326 GST_WARNING ("Invalid codec data size (%d expected, got %d)", 18, size);
5328 } else if (g_str_has_prefix (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC)) {
5329 GstBuffer *priv = NULL;
5331 gint rate_idx, profile;
5332 guint8 *data = NULL;
5334 /* unspecified AAC profile with opaque private codec data */
5335 if (strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC) == 0) {
5336 if (context->codec_priv_size >= 2) {
5337 guint obj_type, freq_index, explicit_freq_bytes = 0;
5339 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
5341 freq_index = (GST_READ_UINT16_BE (context->codec_priv) & 0x780) >> 7;
5342 obj_type = (GST_READ_UINT16_BE (context->codec_priv) & 0xF800) >> 11;
5343 if (freq_index == 15)
5344 explicit_freq_bytes = 3;
5345 GST_DEBUG ("obj_type = %u, freq_index = %u", obj_type, freq_index);
5346 priv = gst_buffer_new_wrapped (g_memdup (context->codec_priv,
5347 context->codec_priv_size), context->codec_priv_size);
5348 /* assume SBR if samplerate <= 24kHz */
5349 if (obj_type == 5 || (freq_index >= 6 && freq_index != 15) ||
5350 (context->codec_priv_size == (5 + explicit_freq_bytes))) {
5351 audiocontext->samplerate *= 2;
5354 GST_WARNING ("Opaque A_AAC codec ID, but no codec private data");
5355 /* this is pretty broken;
5356 * maybe we need to make up some default private,
5357 * or maybe ADTS data got dumped in.
5358 * Let's set up some private data now, and check actual data later */
5359 /* just try this and see what happens ... */
5360 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
5361 context->postprocess_frame = gst_matroska_demux_check_aac;
5365 /* make up decoder-specific data if it is not supplied */
5369 priv = gst_buffer_new_allocate (NULL, 5, NULL);
5370 gst_buffer_map (priv, &map, GST_MAP_WRITE);
5372 rate_idx = aac_rate_idx (audiocontext->samplerate);
5373 profile = aac_profile_idx (codec_id);
5375 data[0] = ((profile + 1) << 3) | ((rate_idx & 0xE) >> 1);
5376 data[1] = ((rate_idx & 0x1) << 7) | (audiocontext->channels << 3);
5378 if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2,
5379 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2))) {
5381 gst_buffer_unmap (priv, &map);
5382 gst_buffer_set_size (priv, 2);
5383 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4,
5384 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4))) {
5387 if (g_strrstr (codec_id, "SBR")) {
5388 /* HE-AAC (aka SBR AAC) */
5389 audiocontext->samplerate *= 2;
5390 rate_idx = aac_rate_idx (audiocontext->samplerate);
5391 data[2] = AAC_SYNC_EXTENSION_TYPE >> 3;
5392 data[3] = ((AAC_SYNC_EXTENSION_TYPE & 0x07) << 5) | 5;
5393 data[4] = (1 << 7) | (rate_idx << 3);
5394 gst_buffer_unmap (priv, &map);
5396 gst_buffer_unmap (priv, &map);
5397 gst_buffer_set_size (priv, 2);
5400 gst_buffer_unmap (priv, &map);
5401 gst_buffer_unref (priv);
5403 GST_ERROR ("Unknown AAC profile and no codec private data");
5408 caps = gst_caps_new_simple ("audio/mpeg",
5409 "mpegversion", G_TYPE_INT, mpegversion,
5410 "framed", G_TYPE_BOOLEAN, TRUE,
5411 "stream-format", G_TYPE_STRING, "raw", NULL);
5412 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5413 if (context->codec_priv && context->codec_priv_size > 0)
5414 gst_codec_utils_aac_caps_set_level_and_profile (caps,
5415 context->codec_priv, context->codec_priv_size);
5416 *codec_name = g_strdup_printf ("MPEG-%d AAC audio", mpegversion);
5417 gst_buffer_unref (priv);
5419 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TTA)) {
5420 caps = gst_caps_new_simple ("audio/x-tta",
5421 "width", G_TYPE_INT, audiocontext->bitdepth, NULL);
5422 *codec_name = g_strdup ("TTA audio");
5423 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_WAVPACK4)) {
5424 caps = gst_caps_new_simple ("audio/x-wavpack",
5425 "width", G_TYPE_INT, audiocontext->bitdepth,
5426 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5427 *codec_name = g_strdup ("Wavpack audio");
5428 context->postprocess_frame = gst_matroska_demux_add_wvpk_header;
5429 audiocontext->wvpk_block_index = 0;
5430 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4)) ||
5431 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_28_8)) ||
5432 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))) {
5433 gint raversion = -1;
5435 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4))
5437 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))
5442 caps = gst_caps_new_simple ("audio/x-pn-realaudio",
5443 "raversion", G_TYPE_INT, raversion, NULL);
5444 /* Extract extra information from caps, mapping varies based on codec */
5445 if (data && (size >= 0x50)) {
5452 guint extra_data_size;
5454 GST_ERROR ("real audio raversion:%d", raversion);
5455 if (raversion == 8) {
5457 flavor = GST_READ_UINT16_BE (data + 22);
5458 packet_size = GST_READ_UINT32_BE (data + 24);
5459 height = GST_READ_UINT16_BE (data + 40);
5460 leaf_size = GST_READ_UINT16_BE (data + 44);
5461 sample_width = GST_READ_UINT16_BE (data + 58);
5462 extra_data_size = GST_READ_UINT32_BE (data + 74);
5465 ("flavor:%d, packet_size:%d, height:%d, leaf_size:%d, sample_width:%d, extra_data_size:%d",
5466 flavor, packet_size, height, leaf_size, sample_width,
5468 gst_caps_set_simple (caps, "flavor", G_TYPE_INT, flavor, "packet_size",
5469 G_TYPE_INT, packet_size, "height", G_TYPE_INT, height, "leaf_size",
5470 G_TYPE_INT, leaf_size, "width", G_TYPE_INT, sample_width, NULL);
5472 if ((size - 78) >= extra_data_size) {
5473 priv = gst_buffer_new_wrapped (g_memdup (data + 78, extra_data_size),
5475 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5476 gst_buffer_unref (priv);
5481 *codec_name = g_strdup_printf ("RealAudio %d.0", raversion);
5482 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_SIPR)) {
5483 caps = gst_caps_new_empty_simple ("audio/x-sipro");
5484 *codec_name = g_strdup ("Sipro/ACELP.NET Voice Codec");
5485 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_RALF)) {
5486 caps = gst_caps_new_empty_simple ("audio/x-ralf-mpeg4-generic");
5487 *codec_name = g_strdup ("Real Audio Lossless");
5488 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_ATRC)) {
5489 caps = gst_caps_new_empty_simple ("audio/x-vnd.sony.atrac3");
5490 *codec_name = g_strdup ("Sony ATRAC3");
5492 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
5497 if (audiocontext->samplerate > 0 && audiocontext->channels > 0) {
5500 for (i = 0; i < gst_caps_get_size (caps); i++) {
5501 gst_structure_set (gst_caps_get_structure (caps, i),
5502 "channels", G_TYPE_INT, audiocontext->channels,
5503 "rate", G_TYPE_INT, audiocontext->samplerate, NULL);
5507 caps = gst_caps_simplify (caps);
5514 gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
5515 subtitlecontext, const gchar * codec_id, gpointer data, guint size)
5517 GstCaps *caps = NULL;
5518 GstMatroskaTrackContext *context =
5519 (GstMatroskaTrackContext *) subtitlecontext;
5521 /* for backwards compatibility */
5522 if (!g_ascii_strcasecmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASCII))
5523 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8;
5524 else if (!g_ascii_strcasecmp (codec_id, "S_SSA"))
5525 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_SSA;
5526 else if (!g_ascii_strcasecmp (codec_id, "S_ASS"))
5527 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_ASS;
5528 else if (!g_ascii_strcasecmp (codec_id, "S_USF"))
5529 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_USF;
5531 /* TODO: Add GST_MATROSKA_CODEC_ID_SUBTITLE_BMP support
5532 * Check if we have to do something with codec_private */
5533 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8)) {
5534 /* well, plain text simply does not have a lot of markup ... */
5535 caps = gst_caps_new_simple ("text/x-raw", "format", G_TYPE_STRING,
5536 "pango-markup", NULL);
5537 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5538 subtitlecontext->check_markup = TRUE;
5539 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_SSA)) {
5540 caps = gst_caps_new_empty_simple ("application/x-ssa");
5541 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5542 subtitlecontext->check_markup = FALSE;
5543 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASS)) {
5544 caps = gst_caps_new_empty_simple ("application/x-ass");
5545 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5546 subtitlecontext->check_markup = FALSE;
5547 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_USF)) {
5548 caps = gst_caps_new_empty_simple ("application/x-usf");
5549 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5550 subtitlecontext->check_markup = FALSE;
5551 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB)) {
5552 caps = gst_caps_new_empty_simple ("subpicture/x-dvd");
5553 ((GstMatroskaTrackContext *) subtitlecontext)->send_dvd_event = TRUE;
5554 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_HDMVPGS)) {
5555 caps = gst_caps_new_empty_simple ("subpicture/x-pgs");
5556 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_KATE)) {
5557 caps = gst_caps_new_empty_simple ("subtitle/x-kate");
5558 context->stream_headers =
5559 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
5560 context->codec_priv_size);
5561 /* FIXME: mark stream as broken and skip if there are no stream headers */
5562 context->send_stream_headers = TRUE;
5564 GST_DEBUG ("Unknown subtitle stream: codec_id='%s'", codec_id);
5565 caps = gst_caps_new_empty_simple ("application/x-subtitle-unknown");
5568 if (data != NULL && size > 0) {
5571 buf = gst_buffer_new_wrapped (g_memdup (data, size), size);
5572 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, buf, NULL);
5573 gst_buffer_unref (buf);
5581 gst_matroska_demux_set_index (GstElement * element, GstIndex * index)
5583 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5585 GST_OBJECT_LOCK (demux);
5586 if (demux->common.element_index)
5587 gst_object_unref (demux->common.element_index);
5588 demux->common.element_index = index ? gst_object_ref (index) : NULL;
5589 GST_OBJECT_UNLOCK (demux);
5590 GST_DEBUG_OBJECT (demux, "Set index %" GST_PTR_FORMAT,
5591 demux->common.element_index);
5595 gst_matroska_demux_get_index (GstElement * element)
5597 GstIndex *result = NULL;
5598 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5600 GST_OBJECT_LOCK (demux);
5601 if (demux->common.element_index)
5602 result = gst_object_ref (demux->common.element_index);
5603 GST_OBJECT_UNLOCK (demux);
5605 GST_DEBUG_OBJECT (demux, "Returning index %" GST_PTR_FORMAT, result);
5611 static GstStateChangeReturn
5612 gst_matroska_demux_change_state (GstElement * element,
5613 GstStateChange transition)
5615 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5616 GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
5618 /* handle upwards state changes here */
5619 switch (transition) {
5624 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
5626 /* handle downwards state changes */
5627 switch (transition) {
5628 case GST_STATE_CHANGE_PAUSED_TO_READY:
5629 gst_matroska_demux_reset (GST_ELEMENT (demux));
5639 gst_matroska_demux_set_property (GObject * object,
5640 guint prop_id, const GValue * value, GParamSpec * pspec)
5642 GstMatroskaDemux *demux;
5644 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
5645 demux = GST_MATROSKA_DEMUX (object);
5648 case ARG_MAX_GAP_TIME:
5649 GST_OBJECT_LOCK (demux);
5650 demux->max_gap_time = g_value_get_uint64 (value);
5651 GST_OBJECT_UNLOCK (demux);
5654 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
5660 gst_matroska_demux_get_property (GObject * object,
5661 guint prop_id, 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 g_value_set_uint64 (value, demux->max_gap_time);
5672 GST_OBJECT_UNLOCK (demux);
5675 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
5681 gst_matroska_demux_plugin_init (GstPlugin * plugin)
5685 /* parser helper separate debug */
5686 GST_DEBUG_CATEGORY_INIT (ebmlread_debug, "ebmlread",
5687 0, "EBML stream helper class");
5689 /* create an elementfactory for the matroska_demux element */
5690 if (!gst_element_register (plugin, "matroskademux",
5691 GST_RANK_PRIMARY, GST_TYPE_MATROSKA_DEMUX))