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 demux->cached_length = G_MAXUINT64;
334 gst_flow_combiner_clear (demux->flowcombiner);
338 gst_matroska_decode_buffer (GstMatroskaTrackContext * context, GstBuffer * buf)
344 g_return_val_if_fail (GST_IS_BUFFER (buf), NULL);
346 GST_DEBUG ("decoding buffer %p", buf);
348 gst_buffer_map (buf, &map, GST_MAP_READ);
352 g_return_val_if_fail (size > 0, buf);
354 if (gst_matroska_decode_data (context->encodings, &data, &size,
355 GST_MATROSKA_TRACK_ENCODING_SCOPE_FRAME, FALSE)) {
356 gst_buffer_unmap (buf, &map);
357 gst_buffer_unref (buf);
358 return gst_buffer_new_wrapped (data, size);
360 GST_DEBUG ("decode data failed");
361 gst_buffer_unmap (buf, &map);
362 gst_buffer_unref (buf);
368 gst_matroska_demux_add_stream_headers_to_caps (GstMatroskaDemux * demux,
369 GstBufferList * list, GstCaps * caps)
372 GValue arr_val = G_VALUE_INIT;
373 GValue buf_val = G_VALUE_INIT;
376 g_assert (gst_caps_is_writable (caps));
378 g_value_init (&arr_val, GST_TYPE_ARRAY);
379 g_value_init (&buf_val, GST_TYPE_BUFFER);
381 num = gst_buffer_list_length (list);
382 for (i = 0; i < num; ++i) {
383 g_value_set_boxed (&buf_val, gst_buffer_list_get (list, i));
384 gst_value_array_append_value (&arr_val, &buf_val);
387 s = gst_caps_get_structure (caps, 0);
388 gst_structure_take_value (s, "streamheader", &arr_val);
389 g_value_unset (&buf_val);
393 gst_matroska_demux_add_stream (GstMatroskaDemux * demux, GstEbmlRead * ebml)
395 GstElementClass *klass = GST_ELEMENT_GET_CLASS (demux);
396 GstMatroskaTrackContext *context;
397 GstPadTemplate *templ = NULL;
398 GstStreamFlags stream_flags;
399 GstCaps *caps = NULL;
400 gchar *padname = NULL;
402 guint32 id, riff_fourcc = 0;
403 guint16 riff_audio_fmt = 0;
404 GstTagList *list = NULL;
405 GstEvent *stream_start;
409 DEBUG_ELEMENT_START (demux, ebml, "TrackEntry");
411 /* start with the master */
412 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
413 DEBUG_ELEMENT_STOP (demux, ebml, "TrackEntry", ret);
417 /* allocate generic... if we know the type, we'll g_renew()
418 * with the precise type */
419 context = g_new0 (GstMatroskaTrackContext, 1);
420 g_ptr_array_add (demux->common.src, context);
421 context->index = demux->common.num_streams;
422 context->index_writer_id = -1;
423 context->type = 0; /* no type yet */
424 context->default_duration = 0;
426 context->set_discont = TRUE;
427 context->timecodescale = 1.0;
429 GST_MATROSKA_TRACK_ENABLED | GST_MATROSKA_TRACK_DEFAULT |
430 GST_MATROSKA_TRACK_LACING;
431 context->from_time = GST_CLOCK_TIME_NONE;
432 context->from_offset = -1;
433 context->to_offset = G_MAXINT64;
434 context->alignment = 1;
435 demux->common.num_streams++;
436 g_assert (demux->common.src->len == demux->common.num_streams);
438 GST_DEBUG_OBJECT (demux, "Stream number %d", context->index);
440 /* try reading the trackentry headers */
441 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
442 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
446 /* track number (unique stream ID) */
447 case GST_MATROSKA_ID_TRACKNUMBER:{
450 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
454 GST_ERROR_OBJECT (demux, "Invalid TrackNumber 0");
455 ret = GST_FLOW_ERROR;
457 } else if (!gst_matroska_read_common_tracknumber_unique (&demux->common,
459 GST_ERROR_OBJECT (demux, "TrackNumber %" G_GUINT64_FORMAT
460 " is not unique", num);
461 ret = GST_FLOW_ERROR;
465 GST_DEBUG_OBJECT (demux, "TrackNumber: %" G_GUINT64_FORMAT, num);
469 /* track UID (unique identifier) */
470 case GST_MATROSKA_ID_TRACKUID:{
473 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
477 GST_ERROR_OBJECT (demux, "Invalid TrackUID 0");
478 ret = GST_FLOW_ERROR;
482 GST_DEBUG_OBJECT (demux, "TrackUID: %" G_GUINT64_FORMAT, num);
487 /* track type (video, audio, combined, subtitle, etc.) */
488 case GST_MATROSKA_ID_TRACKTYPE:{
491 if ((ret = gst_ebml_read_uint (ebml, &id, &track_type)) != GST_FLOW_OK) {
495 if (context->type != 0 && context->type != track_type) {
496 GST_WARNING_OBJECT (demux,
497 "More than one tracktype defined in a TrackEntry - skipping");
499 } else if (track_type < 1 || track_type > 254) {
500 GST_WARNING_OBJECT (demux, "Invalid TrackType %" G_GUINT64_FORMAT,
505 GST_DEBUG_OBJECT (demux, "TrackType: %" G_GUINT64_FORMAT, track_type);
507 /* ok, so we're actually going to reallocate this thing */
508 switch (track_type) {
509 case GST_MATROSKA_TRACK_TYPE_VIDEO:
510 gst_matroska_track_init_video_context (&context);
512 case GST_MATROSKA_TRACK_TYPE_AUDIO:
513 gst_matroska_track_init_audio_context (&context);
515 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
516 gst_matroska_track_init_subtitle_context (&context);
518 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
519 case GST_MATROSKA_TRACK_TYPE_LOGO:
520 case GST_MATROSKA_TRACK_TYPE_BUTTONS:
521 case GST_MATROSKA_TRACK_TYPE_CONTROL:
523 GST_WARNING_OBJECT (demux,
524 "Unknown or unsupported TrackType %" G_GUINT64_FORMAT,
529 g_ptr_array_index (demux->common.src, demux->common.num_streams - 1)
534 /* tracktype specific stuff for video */
535 case GST_MATROSKA_ID_TRACKVIDEO:{
536 GstMatroskaTrackVideoContext *videocontext;
538 DEBUG_ELEMENT_START (demux, ebml, "TrackVideo");
540 if (!gst_matroska_track_init_video_context (&context)) {
541 GST_WARNING_OBJECT (demux,
542 "TrackVideo element in non-video track - ignoring track");
543 ret = GST_FLOW_ERROR;
545 } else if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
548 videocontext = (GstMatroskaTrackVideoContext *) context;
549 g_ptr_array_index (demux->common.src, demux->common.num_streams - 1)
552 while (ret == GST_FLOW_OK &&
553 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
554 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
558 /* Should be one level up but some broken muxers write it here. */
559 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
562 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
566 GST_WARNING_OBJECT (demux, "Invalid TrackDefaultDuration 0");
570 GST_DEBUG_OBJECT (demux,
571 "TrackDefaultDuration: %" G_GUINT64_FORMAT, num);
572 context->default_duration = num;
576 /* video framerate */
577 /* NOTE: This one is here only for backward compatibility.
578 * Use _TRACKDEFAULDURATION one level up. */
579 case GST_MATROSKA_ID_VIDEOFRAMERATE:{
582 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
586 GST_WARNING_OBJECT (demux, "Invalid TrackVideoFPS %lf", num);
590 GST_DEBUG_OBJECT (demux, "TrackVideoFrameRate: %lf", num);
591 if (context->default_duration == 0)
592 context->default_duration =
593 gst_gdouble_to_guint64 ((gdouble) GST_SECOND * (1.0 / num));
594 videocontext->default_fps = num;
598 /* width of the size to display the video at */
599 case GST_MATROSKA_ID_VIDEODISPLAYWIDTH:{
602 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
606 GST_WARNING_OBJECT (demux, "Invalid TrackVideoDisplayWidth 0");
610 GST_DEBUG_OBJECT (demux,
611 "TrackVideoDisplayWidth: %" G_GUINT64_FORMAT, num);
612 videocontext->display_width = num;
616 /* height of the size to display the video at */
617 case GST_MATROSKA_ID_VIDEODISPLAYHEIGHT:{
620 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
624 GST_WARNING_OBJECT (demux, "Invalid TrackVideoDisplayHeight 0");
628 GST_DEBUG_OBJECT (demux,
629 "TrackVideoDisplayHeight: %" G_GUINT64_FORMAT, num);
630 videocontext->display_height = num;
634 /* width of the video in the file */
635 case GST_MATROSKA_ID_VIDEOPIXELWIDTH:{
638 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
642 GST_WARNING_OBJECT (demux, "Invalid TrackVideoPixelWidth 0");
646 GST_DEBUG_OBJECT (demux,
647 "TrackVideoPixelWidth: %" G_GUINT64_FORMAT, num);
648 videocontext->pixel_width = num;
652 /* height of the video in the file */
653 case GST_MATROSKA_ID_VIDEOPIXELHEIGHT:{
656 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
660 GST_WARNING_OBJECT (demux, "Invalid TrackVideoPixelHeight 0");
664 GST_DEBUG_OBJECT (demux,
665 "TrackVideoPixelHeight: %" G_GUINT64_FORMAT, num);
666 videocontext->pixel_height = num;
670 /* whether the video is interlaced */
671 case GST_MATROSKA_ID_VIDEOFLAGINTERLACED:{
674 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
678 context->flags |= GST_MATROSKA_VIDEOTRACK_INTERLACED;
680 context->flags &= ~GST_MATROSKA_VIDEOTRACK_INTERLACED;
681 GST_DEBUG_OBJECT (demux, "TrackVideoInterlaced: %d",
682 (context->flags & GST_MATROSKA_VIDEOTRACK_INTERLACED) ? 1 :
687 /* aspect ratio behaviour */
688 case GST_MATROSKA_ID_VIDEOASPECTRATIOTYPE:{
691 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
694 if (num != GST_MATROSKA_ASPECT_RATIO_MODE_FREE &&
695 num != GST_MATROSKA_ASPECT_RATIO_MODE_KEEP &&
696 num != GST_MATROSKA_ASPECT_RATIO_MODE_FIXED) {
697 GST_WARNING_OBJECT (demux,
698 "Unknown TrackVideoAspectRatioType 0x%x", (guint) num);
701 GST_DEBUG_OBJECT (demux,
702 "TrackVideoAspectRatioType: %" G_GUINT64_FORMAT, num);
703 videocontext->asr_mode = num;
707 /* colourspace (only matters for raw video) fourcc */
708 case GST_MATROSKA_ID_VIDEOCOLOURSPACE:{
713 gst_ebml_read_binary (ebml, &id, &data,
714 &datalen)) != GST_FLOW_OK)
719 GST_WARNING_OBJECT (demux,
720 "Invalid TrackVideoColourSpace length %" G_GUINT64_FORMAT,
725 memcpy (&videocontext->fourcc, data, 4);
726 GST_DEBUG_OBJECT (demux,
727 "TrackVideoColourSpace: %" GST_FOURCC_FORMAT,
728 GST_FOURCC_ARGS (videocontext->fourcc));
734 GST_WARNING_OBJECT (demux,
735 "Unknown TrackVideo subelement 0x%x - ignoring", id);
737 case GST_MATROSKA_ID_VIDEOSTEREOMODE:
738 case GST_MATROSKA_ID_VIDEODISPLAYUNIT:
739 case GST_MATROSKA_ID_VIDEOPIXELCROPBOTTOM:
740 case GST_MATROSKA_ID_VIDEOPIXELCROPTOP:
741 case GST_MATROSKA_ID_VIDEOPIXELCROPLEFT:
742 case GST_MATROSKA_ID_VIDEOPIXELCROPRIGHT:
743 case GST_MATROSKA_ID_VIDEOGAMMAVALUE:
744 ret = gst_ebml_read_skip (ebml);
749 DEBUG_ELEMENT_STOP (demux, ebml, "TrackVideo", ret);
753 /* tracktype specific stuff for audio */
754 case GST_MATROSKA_ID_TRACKAUDIO:{
755 GstMatroskaTrackAudioContext *audiocontext;
757 DEBUG_ELEMENT_START (demux, ebml, "TrackAudio");
759 if (!gst_matroska_track_init_audio_context (&context)) {
760 GST_WARNING_OBJECT (demux,
761 "TrackAudio element in non-audio track - ignoring track");
762 ret = GST_FLOW_ERROR;
766 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
769 audiocontext = (GstMatroskaTrackAudioContext *) context;
770 g_ptr_array_index (demux->common.src, demux->common.num_streams - 1)
773 while (ret == GST_FLOW_OK &&
774 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
775 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
780 case GST_MATROSKA_ID_AUDIOSAMPLINGFREQ:{
783 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
788 GST_WARNING_OBJECT (demux,
789 "Invalid TrackAudioSamplingFrequency %lf", num);
793 GST_DEBUG_OBJECT (demux, "TrackAudioSamplingFrequency: %lf", num);
794 audiocontext->samplerate = num;
799 case GST_MATROSKA_ID_AUDIOBITDEPTH:{
802 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
806 GST_WARNING_OBJECT (demux, "Invalid TrackAudioBitDepth 0");
810 GST_DEBUG_OBJECT (demux, "TrackAudioBitDepth: %" G_GUINT64_FORMAT,
812 audiocontext->bitdepth = num;
817 case GST_MATROSKA_ID_AUDIOCHANNELS:{
820 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
824 GST_WARNING_OBJECT (demux, "Invalid TrackAudioChannels 0");
828 GST_DEBUG_OBJECT (demux, "TrackAudioChannels: %" G_GUINT64_FORMAT,
830 audiocontext->channels = num;
835 GST_WARNING_OBJECT (demux,
836 "Unknown TrackAudio subelement 0x%x - ignoring", id);
838 case GST_MATROSKA_ID_AUDIOCHANNELPOSITIONS:
839 case GST_MATROSKA_ID_AUDIOOUTPUTSAMPLINGFREQ:
840 ret = gst_ebml_read_skip (ebml);
845 DEBUG_ELEMENT_STOP (demux, ebml, "TrackAudio", ret);
850 /* codec identifier */
851 case GST_MATROSKA_ID_CODECID:{
854 if ((ret = gst_ebml_read_ascii (ebml, &id, &text)) != GST_FLOW_OK)
857 GST_DEBUG_OBJECT (demux, "CodecID: %s", GST_STR_NULL (text));
858 context->codec_id = text;
862 /* codec private data */
863 case GST_MATROSKA_ID_CODECPRIVATE:{
868 gst_ebml_read_binary (ebml, &id, &data, &size)) != GST_FLOW_OK)
871 context->codec_priv = data;
872 context->codec_priv_size = size;
874 GST_DEBUG_OBJECT (demux, "CodecPrivate of size %" G_GUINT64_FORMAT,
879 /* name of the codec */
880 case GST_MATROSKA_ID_CODECNAME:{
883 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
886 GST_DEBUG_OBJECT (demux, "CodecName: %s", GST_STR_NULL (text));
887 context->codec_name = text;
891 /* name of this track */
892 case GST_MATROSKA_ID_TRACKNAME:{
895 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
898 context->name = text;
899 GST_DEBUG_OBJECT (demux, "TrackName: %s", GST_STR_NULL (text));
903 /* language (matters for audio/subtitles, mostly) */
904 case GST_MATROSKA_ID_TRACKLANGUAGE:{
907 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
911 context->language = text;
914 if (strlen (context->language) >= 4 && context->language[3] == '-')
915 context->language[3] = '\0';
917 GST_DEBUG_OBJECT (demux, "TrackLanguage: %s",
918 GST_STR_NULL (context->language));
922 /* whether this is actually used */
923 case GST_MATROSKA_ID_TRACKFLAGENABLED:{
926 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
930 context->flags |= GST_MATROSKA_TRACK_ENABLED;
932 context->flags &= ~GST_MATROSKA_TRACK_ENABLED;
934 GST_DEBUG_OBJECT (demux, "TrackEnabled: %d",
935 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
939 /* whether it's the default for this track type */
940 case GST_MATROSKA_ID_TRACKFLAGDEFAULT:{
943 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
947 context->flags |= GST_MATROSKA_TRACK_DEFAULT;
949 context->flags &= ~GST_MATROSKA_TRACK_DEFAULT;
951 GST_DEBUG_OBJECT (demux, "TrackDefault: %d",
952 (context->flags & GST_MATROSKA_TRACK_DEFAULT) ? 1 : 0);
956 /* whether the track must be used during playback */
957 case GST_MATROSKA_ID_TRACKFLAGFORCED:{
960 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
964 context->flags |= GST_MATROSKA_TRACK_FORCED;
966 context->flags &= ~GST_MATROSKA_TRACK_FORCED;
968 GST_DEBUG_OBJECT (demux, "TrackForced: %d",
969 (context->flags & GST_MATROSKA_TRACK_FORCED) ? 1 : 0);
973 /* lacing (like MPEG, where blocks don't end/start on frame
975 case GST_MATROSKA_ID_TRACKFLAGLACING:{
978 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
982 context->flags |= GST_MATROSKA_TRACK_LACING;
984 context->flags &= ~GST_MATROSKA_TRACK_LACING;
986 GST_DEBUG_OBJECT (demux, "TrackLacing: %d",
987 (context->flags & GST_MATROSKA_TRACK_LACING) ? 1 : 0);
991 /* default length (in time) of one data block in this track */
992 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
995 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1000 GST_WARNING_OBJECT (demux, "Invalid TrackDefaultDuration 0");
1004 GST_DEBUG_OBJECT (demux, "TrackDefaultDuration: %" G_GUINT64_FORMAT,
1006 context->default_duration = num;
1010 case GST_MATROSKA_ID_CONTENTENCODINGS:{
1011 ret = gst_matroska_read_common_read_track_encodings (&demux->common,
1016 case GST_MATROSKA_ID_TRACKTIMECODESCALE:{
1019 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
1023 GST_WARNING_OBJECT (demux, "Invalid TrackTimeCodeScale %lf", num);
1027 GST_DEBUG_OBJECT (demux, "TrackTimeCodeScale: %lf", num);
1028 context->timecodescale = num;
1033 GST_WARNING ("Unknown TrackEntry subelement 0x%x - ignoring", id);
1036 /* we ignore these because they're nothing useful (i.e. crap)
1037 * or simply not implemented yet. */
1038 case GST_MATROSKA_ID_TRACKMINCACHE:
1039 case GST_MATROSKA_ID_TRACKMAXCACHE:
1040 case GST_MATROSKA_ID_MAXBLOCKADDITIONID:
1041 case GST_MATROSKA_ID_TRACKATTACHMENTLINK:
1042 case GST_MATROSKA_ID_TRACKOVERLAY:
1043 case GST_MATROSKA_ID_TRACKTRANSLATE:
1044 case GST_MATROSKA_ID_TRACKOFFSET:
1045 case GST_MATROSKA_ID_CODECSETTINGS:
1046 case GST_MATROSKA_ID_CODECINFOURL:
1047 case GST_MATROSKA_ID_CODECDOWNLOADURL:
1048 case GST_MATROSKA_ID_CODECDECODEALL:
1049 ret = gst_ebml_read_skip (ebml);
1054 DEBUG_ELEMENT_STOP (demux, ebml, "TrackEntry", ret);
1056 /* Decode codec private data if necessary */
1057 if (context->encodings && context->encodings->len > 0 && context->codec_priv
1058 && context->codec_priv_size > 0) {
1059 if (!gst_matroska_decode_data (context->encodings,
1060 &context->codec_priv, &context->codec_priv_size,
1061 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
1062 GST_WARNING_OBJECT (demux, "Decoding codec private data failed");
1063 ret = GST_FLOW_ERROR;
1067 if (context->type == 0 || context->codec_id == NULL || (ret != GST_FLOW_OK
1068 && ret != GST_FLOW_EOS)) {
1069 if (ret == GST_FLOW_OK || ret == GST_FLOW_EOS)
1070 GST_WARNING_OBJECT (ebml, "Unknown stream/codec in track entry header");
1072 demux->common.num_streams--;
1073 g_ptr_array_remove_index (demux->common.src, demux->common.num_streams);
1074 g_assert (demux->common.src->len == demux->common.num_streams);
1076 gst_matroska_track_free (context);
1082 /* now create the GStreamer connectivity */
1083 switch (context->type) {
1084 case GST_MATROSKA_TRACK_TYPE_VIDEO:{
1085 GstMatroskaTrackVideoContext *videocontext =
1086 (GstMatroskaTrackVideoContext *) context;
1088 padname = g_strdup_printf ("video_%u", demux->num_v_streams++);
1089 templ = gst_element_class_get_pad_template (klass, "video_%u");
1090 caps = gst_matroska_demux_video_caps (videocontext,
1091 context->codec_id, context->codec_priv,
1092 context->codec_priv_size, &codec, &riff_fourcc);
1095 list = gst_tag_list_new (GST_TAG_VIDEO_CODEC, codec, NULL);
1101 case GST_MATROSKA_TRACK_TYPE_AUDIO:{
1102 GstMatroskaTrackAudioContext *audiocontext =
1103 (GstMatroskaTrackAudioContext *) context;
1105 padname = g_strdup_printf ("audio_%u", demux->num_a_streams++);
1106 templ = gst_element_class_get_pad_template (klass, "audio_%u");
1107 caps = gst_matroska_demux_audio_caps (audiocontext,
1108 context->codec_id, context->codec_priv, context->codec_priv_size,
1109 &codec, &riff_audio_fmt);
1112 list = gst_tag_list_new (GST_TAG_AUDIO_CODEC, codec, NULL);
1118 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:{
1119 GstMatroskaTrackSubtitleContext *subtitlecontext =
1120 (GstMatroskaTrackSubtitleContext *) context;
1122 padname = g_strdup_printf ("subtitle_%u", demux->num_t_streams++);
1123 templ = gst_element_class_get_pad_template (klass, "subtitle_%u");
1124 caps = gst_matroska_demux_subtitle_caps (subtitlecontext,
1125 context->codec_id, context->codec_priv, context->codec_priv_size);
1129 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1130 case GST_MATROSKA_TRACK_TYPE_LOGO:
1131 case GST_MATROSKA_TRACK_TYPE_BUTTONS:
1132 case GST_MATROSKA_TRACK_TYPE_CONTROL:
1134 /* we should already have quit by now */
1135 g_assert_not_reached ();
1138 if ((context->language == NULL || *context->language == '\0') &&
1139 (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO ||
1140 context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
1141 GST_LOG ("stream %d: language=eng (assuming default)", context->index);
1142 context->language = g_strdup ("eng");
1145 if (context->language) {
1149 list = gst_tag_list_new_empty ();
1151 /* Matroska contains ISO 639-2B codes, we want ISO 639-1 */
1152 lang = gst_tag_get_language_code (context->language);
1153 gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
1154 GST_TAG_LANGUAGE_CODE, (lang) ? lang : context->language, NULL);
1158 GST_WARNING_OBJECT (demux, "could not determine caps for stream with "
1159 "codec_id='%s'", context->codec_id);
1160 switch (context->type) {
1161 case GST_MATROSKA_TRACK_TYPE_VIDEO:
1162 caps = gst_caps_new_empty_simple ("video/x-unknown");
1164 case GST_MATROSKA_TRACK_TYPE_AUDIO:
1165 caps = gst_caps_new_empty_simple ("audio/x-unknown");
1167 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
1168 caps = gst_caps_new_empty_simple ("application/x-subtitle-unknown");
1170 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1172 caps = gst_caps_new_empty_simple ("application/x-matroska-unknown");
1175 gst_caps_set_simple (caps, "codec-id", G_TYPE_STRING, context->codec_id,
1178 /* add any unrecognised riff fourcc / audio format, but after codec-id */
1179 if (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO && riff_audio_fmt != 0)
1180 gst_caps_set_simple (caps, "format", G_TYPE_INT, riff_audio_fmt, NULL);
1181 else if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO && riff_fourcc != 0) {
1182 gchar *fstr = g_strdup_printf ("%" GST_FOURCC_FORMAT,
1183 GST_FOURCC_ARGS (riff_fourcc));
1184 gst_caps_set_simple (caps, "fourcc", G_TYPE_STRING, fstr, NULL);
1187 } else if (context->stream_headers != NULL) {
1188 gst_matroska_demux_add_stream_headers_to_caps (demux,
1189 context->stream_headers, caps);
1192 /* the pad in here */
1193 context->pad = gst_pad_new_from_template (templ, padname);
1194 context->caps = caps;
1196 gst_pad_set_event_function (context->pad,
1197 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_event));
1198 gst_pad_set_query_function (context->pad,
1199 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_query));
1201 GST_INFO_OBJECT (demux, "Adding pad '%s' with caps %" GST_PTR_FORMAT,
1204 context->pending_tags = list;
1206 gst_pad_set_element_private (context->pad, context);
1208 gst_pad_use_fixed_caps (context->pad);
1209 gst_pad_set_active (context->pad, TRUE);
1212 gst_pad_create_stream_id_printf (context->pad, GST_ELEMENT_CAST (demux),
1213 "%03" G_GUINT64_FORMAT, context->uid);
1215 gst_pad_get_sticky_event (demux->common.sinkpad, GST_EVENT_STREAM_START,
1218 if (gst_event_parse_group_id (stream_start, &demux->group_id))
1219 demux->have_group_id = TRUE;
1221 demux->have_group_id = FALSE;
1222 gst_event_unref (stream_start);
1223 } else if (!demux->have_group_id) {
1224 demux->have_group_id = TRUE;
1225 demux->group_id = gst_util_group_id_next ();
1228 stream_start = gst_event_new_stream_start (stream_id);
1230 if (demux->have_group_id)
1231 gst_event_set_group_id (stream_start, demux->group_id);
1232 stream_flags = GST_STREAM_FLAG_NONE;
1233 if (context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)
1234 stream_flags |= GST_STREAM_FLAG_SPARSE;
1235 if (context->flags & GST_MATROSKA_TRACK_DEFAULT)
1236 stream_flags |= GST_STREAM_FLAG_SELECT;
1237 gst_event_set_stream_flags (stream_start, stream_flags);
1238 gst_pad_push_event (context->pad, stream_start);
1239 gst_pad_set_caps (context->pad, context->caps);
1241 gst_element_add_pad (GST_ELEMENT (demux), context->pad);
1242 gst_flow_combiner_add_pad (demux->flowcombiner, context->pad);
1251 gst_matroska_demux_query (GstMatroskaDemux * demux, GstPad * pad,
1254 gboolean res = FALSE;
1255 GstMatroskaTrackContext *context = NULL;
1258 context = gst_pad_get_element_private (pad);
1261 switch (GST_QUERY_TYPE (query)) {
1262 case GST_QUERY_POSITION:
1266 gst_query_parse_position (query, &format, NULL);
1269 if (format == GST_FORMAT_TIME) {
1270 GST_OBJECT_LOCK (demux);
1272 gst_query_set_position (query, GST_FORMAT_TIME,
1273 MAX (context->pos, demux->stream_start_time) -
1274 demux->stream_start_time);
1276 gst_query_set_position (query, GST_FORMAT_TIME,
1277 MAX (demux->common.segment.position, demux->stream_start_time) -
1278 demux->stream_start_time);
1279 GST_OBJECT_UNLOCK (demux);
1280 } else if (format == GST_FORMAT_DEFAULT && context
1281 && context->default_duration) {
1282 GST_OBJECT_LOCK (demux);
1283 gst_query_set_position (query, GST_FORMAT_DEFAULT,
1284 context->pos / context->default_duration);
1285 GST_OBJECT_UNLOCK (demux);
1287 GST_DEBUG_OBJECT (demux,
1288 "only position query in TIME and DEFAULT format is supported");
1294 case GST_QUERY_DURATION:
1298 gst_query_parse_duration (query, &format, NULL);
1301 if (format == GST_FORMAT_TIME) {
1302 GST_OBJECT_LOCK (demux);
1303 gst_query_set_duration (query, GST_FORMAT_TIME,
1304 demux->common.segment.duration);
1305 GST_OBJECT_UNLOCK (demux);
1306 } else if (format == GST_FORMAT_DEFAULT && context
1307 && context->default_duration) {
1308 GST_OBJECT_LOCK (demux);
1309 gst_query_set_duration (query, GST_FORMAT_DEFAULT,
1310 demux->common.segment.duration / context->default_duration);
1311 GST_OBJECT_UNLOCK (demux);
1313 GST_DEBUG_OBJECT (demux,
1314 "only duration query in TIME and DEFAULT format is supported");
1320 case GST_QUERY_SEEKING:
1324 gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
1325 GST_OBJECT_LOCK (demux);
1326 if (fmt == GST_FORMAT_TIME) {
1329 if (demux->streaming) {
1330 /* assuming we'll be able to get an index ... */
1331 seekable = demux->seekable;
1336 gst_query_set_seeking (query, GST_FORMAT_TIME, seekable,
1337 0, demux->common.segment.duration);
1340 GST_OBJECT_UNLOCK (demux);
1343 case GST_QUERY_SEGMENT:
1348 format = demux->common.segment.format;
1351 gst_segment_to_stream_time (&demux->common.segment, format,
1352 demux->common.segment.start);
1353 if ((stop = demux->common.segment.stop) == -1)
1354 stop = demux->common.segment.duration;
1357 gst_segment_to_stream_time (&demux->common.segment, format, stop);
1359 gst_query_set_segment (query, demux->common.segment.rate, format, start,
1366 res = gst_pad_query_default (pad, (GstObject *) demux, query);
1369 GST_ELEMENT_CLASS (parent_class)->query (GST_ELEMENT_CAST (demux),
1378 gst_matroska_demux_element_query (GstElement * element, GstQuery * query)
1380 return gst_matroska_demux_query (GST_MATROSKA_DEMUX (element), NULL, query);
1384 gst_matroska_demux_handle_src_query (GstPad * pad, GstObject * parent,
1387 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
1389 return gst_matroska_demux_query (demux, pad, query);
1392 /* returns FALSE if there are no pads to deliver event to,
1393 * otherwise TRUE (whatever the outcome of event sending),
1394 * takes ownership of the passed event! */
1396 gst_matroska_demux_send_event (GstMatroskaDemux * demux, GstEvent * event)
1398 gboolean is_segment;
1399 gboolean ret = FALSE;
1402 g_return_val_if_fail (event != NULL, FALSE);
1404 GST_DEBUG_OBJECT (demux, "Sending event of type %s to all source pads",
1405 GST_EVENT_TYPE_NAME (event));
1407 is_segment = (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT);
1409 g_assert (demux->common.src->len == demux->common.num_streams);
1410 for (i = 0; i < demux->common.src->len; i++) {
1411 GstMatroskaTrackContext *stream;
1413 stream = g_ptr_array_index (demux->common.src, i);
1414 gst_event_ref (event);
1415 gst_pad_push_event (stream->pad, event);
1418 /* FIXME: send global tags before stream tags */
1419 if (G_UNLIKELY (is_segment && stream->pending_tags != NULL)) {
1420 GST_DEBUG_OBJECT (demux, "Sending pending_tags %p for pad %s:%s : %"
1421 GST_PTR_FORMAT, stream->pending_tags,
1422 GST_DEBUG_PAD_NAME (stream->pad), stream->pending_tags);
1423 gst_pad_push_event (stream->pad,
1424 gst_event_new_tag (stream->pending_tags));
1425 stream->pending_tags = NULL;
1429 if (G_UNLIKELY (is_segment && demux->common.global_tags != NULL)) {
1430 GstEvent *tag_event;
1431 gst_tag_list_add (demux->common.global_tags, GST_TAG_MERGE_REPLACE,
1432 GST_TAG_CONTAINER_FORMAT, "Matroska", NULL);
1433 GST_DEBUG_OBJECT (demux, "Sending global_tags %p : %" GST_PTR_FORMAT,
1434 demux->common.global_tags, demux->common.global_tags);
1436 tag_event = gst_event_new_tag (demux->common.global_tags);
1438 for (i = 0; i < demux->common.src->len; i++) {
1439 GstMatroskaTrackContext *stream;
1441 stream = g_ptr_array_index (demux->common.src, i);
1442 gst_pad_push_event (stream->pad, gst_event_ref (tag_event));
1445 gst_event_unref (tag_event);
1446 demux->common.global_tags = NULL;
1449 gst_event_unref (event);
1454 gst_matroska_demux_element_send_event (GstElement * element, GstEvent * event)
1456 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
1459 g_return_val_if_fail (event != NULL, FALSE);
1461 if (GST_EVENT_TYPE (event) == GST_EVENT_SEEK) {
1462 res = gst_matroska_demux_handle_seek_event (demux, NULL, event);
1464 GST_WARNING_OBJECT (demux, "Unhandled event of type %s",
1465 GST_EVENT_TYPE_NAME (event));
1468 gst_event_unref (event);
1473 gst_matroska_demux_move_to_entry (GstMatroskaDemux * demux,
1474 GstMatroskaIndex * entry, gboolean reset, gboolean update)
1478 GST_OBJECT_LOCK (demux);
1481 /* seek (relative to matroska segment) */
1482 /* position might be invalid; will error when streaming resumes ... */
1483 demux->common.offset = entry->pos + demux->common.ebml_segment_start;
1484 demux->next_cluster_offset = 0;
1486 GST_DEBUG_OBJECT (demux,
1487 "Seeked to offset %" G_GUINT64_FORMAT ", block %d, " "time %"
1488 GST_TIME_FORMAT, entry->pos + demux->common.ebml_segment_start,
1489 entry->block, GST_TIME_ARGS (entry->time));
1491 /* update the time */
1492 gst_matroska_read_common_reset_streams (&demux->common, entry->time, TRUE);
1493 demux->common.segment.position = entry->time;
1494 demux->seek_block = entry->block;
1495 demux->seek_first = TRUE;
1496 demux->last_stop_end = GST_CLOCK_TIME_NONE;
1499 for (i = 0; i < demux->common.src->len; i++) {
1500 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
1503 stream->to_offset = G_MAXINT64;
1505 if (stream->from_offset != -1)
1506 stream->to_offset = stream->from_offset;
1508 stream->from_offset = -1;
1509 stream->from_time = GST_CLOCK_TIME_NONE;
1512 GST_OBJECT_UNLOCK (demux);
1518 gst_matroska_cluster_compare (gint64 * i1, gint64 * i2)
1528 /* searches for a cluster start from @pos,
1529 * return GST_FLOW_OK and cluster position in @pos if found */
1530 static GstFlowReturn
1531 gst_matroska_demux_search_cluster (GstMatroskaDemux * demux, gint64 * pos)
1533 gint64 newpos = *pos;
1535 GstFlowReturn ret = GST_FLOW_OK;
1536 const guint chunk = 64 * 1024;
1537 GstBuffer *buf = NULL;
1539 gpointer data = NULL;
1545 orig_offset = demux->common.offset;
1547 GST_LOG_OBJECT (demux, "searching cluster following offset %" G_GINT64_FORMAT,
1550 if (demux->clusters) {
1553 cpos = gst_util_array_binary_search (demux->clusters->data,
1554 demux->clusters->len, sizeof (gint64),
1555 (GCompareDataFunc) gst_matroska_cluster_compare,
1556 GST_SEARCH_MODE_AFTER, pos, NULL);
1559 GST_DEBUG_OBJECT (demux,
1560 "cluster reported at offset %" G_GINT64_FORMAT, *cpos);
1561 demux->common.offset = *cpos;
1562 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1563 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1564 if (ret == GST_FLOW_OK && id == GST_MATROSKA_ID_CLUSTER) {
1571 /* read in at newpos and scan for ebml cluster id */
1573 GstByteReader reader;
1577 gst_buffer_unmap (buf, &map);
1578 gst_buffer_unref (buf);
1581 ret = gst_pad_pull_range (demux->common.sinkpad, newpos, chunk, &buf);
1582 if (ret != GST_FLOW_OK)
1584 GST_DEBUG_OBJECT (demux,
1585 "read buffer size %" G_GSIZE_FORMAT " at offset %" G_GINT64_FORMAT,
1586 gst_buffer_get_size (buf), newpos);
1587 gst_buffer_map (buf, &map, GST_MAP_READ);
1590 gst_byte_reader_init (&reader, data, size);
1592 cluster_pos = gst_byte_reader_masked_scan_uint32 (&reader, 0xffffffff,
1593 GST_MATROSKA_ID_CLUSTER, 0, gst_byte_reader_get_remaining (&reader));
1594 if (cluster_pos >= 0) {
1595 newpos += cluster_pos;
1596 /* prepare resuming at next byte */
1597 if (!gst_byte_reader_skip (&reader, cluster_pos + 1)) {
1598 GST_DEBUG_OBJECT (demux, "Need more data -> continue");
1601 GST_DEBUG_OBJECT (demux,
1602 "found cluster ebml id at offset %" G_GINT64_FORMAT, newpos);
1603 /* extra checks whether we really sync'ed to a cluster:
1604 * - either it is the first and only cluster
1605 * - either there is a cluster after this one
1606 * - either cluster length is undefined
1608 /* ok if first cluster (there may not a subsequent one) */
1609 if (newpos == demux->first_cluster_offset) {
1610 GST_DEBUG_OBJECT (demux, "cluster is first cluster -> OK");
1613 demux->common.offset = newpos;
1614 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1615 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1616 if (ret != GST_FLOW_OK) {
1617 GST_DEBUG_OBJECT (demux, "need more data -> continue");
1620 g_assert (id == GST_MATROSKA_ID_CLUSTER);
1621 GST_DEBUG_OBJECT (demux, "cluster size %" G_GUINT64_FORMAT ", prefix %d",
1623 /* ok if undefined length or first cluster */
1624 if (length == GST_EBML_SIZE_UNKNOWN || length == G_MAXUINT64) {
1625 GST_DEBUG_OBJECT (demux, "cluster has undefined length -> OK");
1629 demux->common.offset += length + needed;
1630 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1631 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1632 if (ret != GST_FLOW_OK)
1634 GST_DEBUG_OBJECT (demux, "next element is %scluster",
1635 id == GST_MATROSKA_ID_CLUSTER ? "" : "not ");
1636 if (id == GST_MATROSKA_ID_CLUSTER)
1638 /* not ok, resume */
1641 /* partial cluster id may have been in tail of buffer */
1642 newpos += MAX (gst_byte_reader_get_remaining (&reader), 4) - 3;
1647 gst_buffer_unmap (buf, &map);
1648 gst_buffer_unref (buf);
1653 demux->common.offset = orig_offset;
1658 /* bisect and scan through file for cluster starting before @time,
1659 * returns fake index entry with corresponding info on cluster */
1660 static GstMatroskaIndex *
1661 gst_matroska_demux_search_pos (GstMatroskaDemux * demux, GstClockTime time)
1663 GstMatroskaIndex *entry = NULL;
1664 GstMatroskaReadState current_state;
1665 GstClockTime otime, prev_cluster_time, current_cluster_time, cluster_time;
1666 gint64 opos, newpos, startpos = 0, current_offset;
1667 gint64 prev_cluster_offset = -1, current_cluster_offset, cluster_offset;
1668 const guint chunk = 64 * 1024;
1674 /* (under)estimate new position, resync using cluster ebml id,
1675 * and scan forward to appropriate cluster
1676 * (and re-estimate if need to go backward) */
1678 prev_cluster_time = GST_CLOCK_TIME_NONE;
1680 /* store some current state */
1681 current_state = demux->common.state;
1682 g_return_val_if_fail (current_state == GST_MATROSKA_READ_STATE_DATA, NULL);
1684 current_cluster_offset = demux->cluster_offset;
1685 current_cluster_time = demux->cluster_time;
1686 current_offset = demux->common.offset;
1688 demux->common.state = GST_MATROSKA_READ_STATE_SCANNING;
1690 /* estimate using start and current position */
1691 GST_OBJECT_LOCK (demux);
1692 opos = demux->common.offset - demux->common.ebml_segment_start;
1693 otime = demux->common.segment.position;
1694 GST_OBJECT_UNLOCK (demux);
1697 time = MAX (time, demux->stream_start_time);
1699 /* avoid division by zero in first estimation below */
1700 if (otime <= demux->stream_start_time)
1704 GST_LOG_OBJECT (demux,
1705 "opos: %" G_GUINT64_FORMAT ", otime: %" GST_TIME_FORMAT ", %"
1706 GST_TIME_FORMAT " in stream time (start %" GST_TIME_FORMAT "), time %"
1707 GST_TIME_FORMAT, opos, GST_TIME_ARGS (otime),
1708 GST_TIME_ARGS (otime - demux->stream_start_time),
1709 GST_TIME_ARGS (demux->stream_start_time), GST_TIME_ARGS (time));
1711 if (otime <= demux->stream_start_time) {
1715 gst_util_uint64_scale (opos - demux->common.ebml_segment_start,
1716 time - demux->stream_start_time,
1717 otime - demux->stream_start_time) - chunk;
1721 /* favour undershoot */
1722 newpos = newpos * 90 / 100;
1723 newpos += demux->common.ebml_segment_start;
1725 GST_DEBUG_OBJECT (demux,
1726 "estimated offset for %" GST_TIME_FORMAT ": %" G_GINT64_FORMAT,
1727 GST_TIME_ARGS (time), newpos);
1729 /* and at least start scanning before previous scan start to avoid looping */
1730 startpos = startpos * 90 / 100;
1731 if (startpos && startpos < newpos)
1734 /* read in at newpos and scan for ebml cluster id */
1738 ret = gst_matroska_demux_search_cluster (demux, &newpos);
1739 if (ret == GST_FLOW_EOS) {
1740 /* heuristic HACK */
1741 newpos = startpos * 80 / 100;
1742 GST_DEBUG_OBJECT (demux, "EOS; "
1743 "new estimated offset for %" GST_TIME_FORMAT ": %" G_GINT64_FORMAT,
1744 GST_TIME_ARGS (time), newpos);
1747 } else if (ret != GST_FLOW_OK) {
1754 /* then start scanning and parsing for cluster time,
1755 * re-estimate if overshoot, otherwise next cluster and so on */
1756 demux->common.offset = newpos;
1757 demux->cluster_time = cluster_time = GST_CLOCK_TIME_NONE;
1759 guint64 cluster_size = 0;
1761 /* peek and parse some elements */
1762 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1763 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1764 if (ret != GST_FLOW_OK)
1766 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
1767 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
1769 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
1770 if (ret != GST_FLOW_OK)
1773 if (id == GST_MATROSKA_ID_CLUSTER) {
1774 cluster_time = GST_CLOCK_TIME_NONE;
1775 if (length == G_MAXUINT64)
1778 cluster_size = length + needed;
1780 if (demux->cluster_time != GST_CLOCK_TIME_NONE &&
1781 cluster_time == GST_CLOCK_TIME_NONE) {
1782 cluster_time = demux->cluster_time * demux->common.time_scale;
1783 cluster_offset = demux->cluster_offset;
1784 GST_DEBUG_OBJECT (demux, "found cluster at offset %" G_GINT64_FORMAT
1785 " with time %" GST_TIME_FORMAT, cluster_offset,
1786 GST_TIME_ARGS (cluster_time));
1787 if (cluster_time > time) {
1788 GST_DEBUG_OBJECT (demux, "overshot target");
1789 /* cluster overshoots */
1790 if (cluster_offset == demux->first_cluster_offset) {
1791 /* but no prev one */
1792 GST_DEBUG_OBJECT (demux, "but using first cluster anyway");
1793 prev_cluster_time = cluster_time;
1794 prev_cluster_offset = cluster_offset;
1797 if (prev_cluster_time != GST_CLOCK_TIME_NONE) {
1798 /* prev cluster did not overshoot, so prev cluster is target */
1801 /* re-estimate using this new position info */
1802 opos = cluster_offset;
1803 otime = cluster_time;
1807 /* cluster undershoots, goto next one */
1808 prev_cluster_time = cluster_time;
1809 prev_cluster_offset = cluster_offset;
1810 /* skip cluster if length is defined,
1811 * otherwise will be skippingly parsed into */
1813 GST_DEBUG_OBJECT (demux, "skipping to next cluster");
1814 demux->common.offset = cluster_offset + cluster_size;
1815 demux->cluster_time = GST_CLOCK_TIME_NONE;
1817 GST_DEBUG_OBJECT (demux, "parsing/skipping cluster elements");
1824 if (ret == GST_FLOW_EOS) {
1825 if (prev_cluster_time != GST_CLOCK_TIME_NONE)
1831 entry = g_new0 (GstMatroskaIndex, 1);
1832 entry->time = prev_cluster_time;
1833 entry->pos = prev_cluster_offset - demux->common.ebml_segment_start;
1834 GST_DEBUG_OBJECT (demux, "simulated index entry; time %" GST_TIME_FORMAT
1835 ", pos %" G_GUINT64_FORMAT, GST_TIME_ARGS (entry->time), entry->pos);
1839 /* restore some state */
1840 demux->cluster_offset = current_cluster_offset;
1841 demux->cluster_time = current_cluster_time;
1842 demux->common.offset = current_offset;
1843 demux->common.state = current_state;
1849 gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
1850 GstPad * pad, GstEvent * event)
1852 GstMatroskaIndex *entry = NULL;
1853 GstMatroskaIndex scan_entry;
1855 GstSeekType cur_type, stop_type;
1857 gboolean flush, keyunit, before, after, snap_next;
1860 GstMatroskaTrackContext *track = NULL;
1861 GstSegment seeksegment = { 0, };
1862 gboolean update = TRUE;
1863 gboolean pad_locked = FALSE;
1867 track = gst_pad_get_element_private (pad);
1869 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
1871 seqnum = gst_event_get_seqnum (event);
1873 /* we can only seek on time */
1874 if (format != GST_FORMAT_TIME) {
1875 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
1879 /* copy segment, we need this because we still need the old
1880 * segment when we close the current segment. */
1881 memcpy (&seeksegment, &demux->common.segment, sizeof (GstSegment));
1883 /* pull mode without index means that the actual duration is not known,
1884 * we might be playing a file that's still being recorded
1885 * so, invalidate our current duration, which is only a moving target,
1886 * and should not be used to clamp anything */
1887 if (!demux->streaming && !demux->common.index && demux->invalid_duration) {
1888 seeksegment.duration = GST_CLOCK_TIME_NONE;
1892 GST_DEBUG_OBJECT (demux, "configuring seek");
1893 gst_segment_do_seek (&seeksegment, rate, format, flags,
1894 cur_type, cur, stop_type, stop, &update);
1895 /* compensate for clip start time, but only for SET seeks,
1896 * otherwise it is already part of the segments */
1897 if (GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
1898 if (cur_type == GST_SEEK_TYPE_SET) {
1900 seeksegment.position += demux->stream_start_time;
1901 seeksegment.start += demux->stream_start_time;
1903 if (stop_type == GST_SEEK_TYPE_SET
1904 && GST_CLOCK_TIME_IS_VALID (seeksegment.stop)) {
1906 seeksegment.position += demux->stream_start_time;
1907 seeksegment.stop += demux->stream_start_time;
1912 /* restore segment duration (if any effect),
1913 * would be determined again when parsing, but anyway ... */
1914 seeksegment.duration = demux->common.segment.duration;
1916 flush = ! !(flags & GST_SEEK_FLAG_FLUSH);
1917 keyunit = ! !(flags & GST_SEEK_FLAG_KEY_UNIT);
1918 after = ! !(flags & GST_SEEK_FLAG_SNAP_AFTER);
1919 before = ! !(flags & GST_SEEK_FLAG_SNAP_BEFORE);
1921 /* always do full update if flushing,
1922 * otherwise problems might arise downstream with missing keyframes etc */
1923 update = update || flush;
1925 GST_DEBUG_OBJECT (demux, "New segment %" GST_SEGMENT_FORMAT, &seeksegment);
1927 /* check sanity before we start flushing and all that */
1928 snap_next = after && !before;
1929 if (seeksegment.rate < 0)
1930 snap_next = !snap_next;
1931 GST_OBJECT_LOCK (demux);
1932 track = gst_matroska_read_common_get_seek_track (&demux->common, track);
1933 if ((entry = gst_matroska_read_common_do_index_seek (&demux->common, track,
1934 seeksegment.position, &demux->seek_index, &demux->seek_entry,
1935 snap_next)) == NULL) {
1936 /* pull mode without index can scan later on */
1937 if (demux->streaming) {
1938 GST_DEBUG_OBJECT (demux, "No matching seek entry in index");
1939 GST_OBJECT_UNLOCK (demux);
1941 } else if (rate < 0.0) {
1942 /* FIXME: We should build an index during playback or when scanning
1943 * that can be used here. The reverse playback code requires seek_index
1944 * and seek_entry to be set!
1946 GST_DEBUG_OBJECT (demux,
1947 "No matching seek entry in index, needed for reverse playback");
1948 GST_OBJECT_UNLOCK (demux);
1952 GST_DEBUG_OBJECT (demux, "Seek position looks sane");
1953 GST_OBJECT_UNLOCK (demux);
1956 /* only have to update some segment,
1957 * but also still have to honour flush and so on */
1958 GST_DEBUG_OBJECT (demux, "... no update");
1959 /* bad goto, bad ... */
1963 if (demux->streaming)
1968 GstEvent *flush_event = gst_event_new_flush_start ();
1969 gst_event_set_seqnum (flush_event, seqnum);
1970 GST_DEBUG_OBJECT (demux, "Starting flush");
1971 gst_pad_push_event (demux->common.sinkpad, gst_event_ref (flush_event));
1972 gst_matroska_demux_send_event (demux, flush_event);
1974 GST_DEBUG_OBJECT (demux, "Non-flushing seek, pausing task");
1975 gst_pad_pause_task (demux->common.sinkpad);
1979 GST_PAD_STREAM_LOCK (demux->common.sinkpad);
1984 /* now grab the stream lock so that streaming cannot continue, for
1985 * non flushing seeks when the element is in PAUSED this could block
1987 GST_DEBUG_OBJECT (demux, "Waiting for streaming to stop");
1988 GST_PAD_STREAM_LOCK (demux->common.sinkpad);
1991 /* pull mode without index can do some scanning */
1992 if (!demux->streaming && !entry) {
1993 GstEvent *flush_event;
1995 /* need to stop flushing upstream as we need it next */
1997 flush_event = gst_event_new_flush_stop (TRUE);
1998 gst_event_set_seqnum (flush_event, seqnum);
1999 gst_pad_push_event (demux->common.sinkpad, flush_event);
2001 entry = gst_matroska_demux_search_pos (demux, seeksegment.position);
2002 /* keep local copy */
2004 scan_entry = *entry;
2006 entry = &scan_entry;
2008 GST_DEBUG_OBJECT (demux, "Scan failed to find matching position");
2010 flush_event = gst_event_new_flush_stop (TRUE);
2011 gst_event_set_seqnum (flush_event, seqnum);
2012 gst_matroska_demux_send_event (demux, flush_event);
2020 GST_DEBUG_OBJECT (demux, "seek to key unit, adjusting segment start from %"
2021 GST_TIME_FORMAT " to %" GST_TIME_FORMAT,
2022 GST_TIME_ARGS (seeksegment.start), GST_TIME_ARGS (entry->time));
2023 seeksegment.start = MAX (entry->time, demux->stream_start_time);
2024 seeksegment.position = seeksegment.start;
2025 seeksegment.time = seeksegment.start - demux->stream_start_time;
2028 if (demux->streaming) {
2029 GST_OBJECT_LOCK (demux);
2030 /* track real position we should start at */
2031 GST_DEBUG_OBJECT (demux, "storing segment start");
2032 demux->requested_seek_time = seeksegment.position;
2033 demux->seek_offset = entry->pos + demux->common.ebml_segment_start;
2034 GST_OBJECT_UNLOCK (demux);
2035 /* need to seek to cluster start to pick up cluster time */
2036 /* upstream takes care of flushing and all that
2037 * ... and newsegment event handling takes care of the rest */
2038 return perform_seek_to_offset (demux, rate,
2039 entry->pos + demux->common.ebml_segment_start, seqnum);
2044 GstEvent *flush_event = gst_event_new_flush_stop (TRUE);
2045 gst_event_set_seqnum (flush_event, seqnum);
2046 GST_DEBUG_OBJECT (demux, "Stopping flush");
2047 gst_pad_push_event (demux->common.sinkpad, gst_event_ref (flush_event));
2048 gst_matroska_demux_send_event (demux, flush_event);
2051 GST_OBJECT_LOCK (demux);
2052 /* now update the real segment info */
2053 GST_DEBUG_OBJECT (demux, "Committing new seek segment");
2054 memcpy (&demux->common.segment, &seeksegment, sizeof (GstSegment));
2055 GST_OBJECT_UNLOCK (demux);
2057 /* update some (segment) state */
2058 if (!gst_matroska_demux_move_to_entry (demux, entry, TRUE, update))
2061 /* notify start of new segment */
2062 if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
2065 msg = gst_message_new_segment_start (GST_OBJECT (demux),
2066 GST_FORMAT_TIME, demux->common.segment.start);
2067 gst_message_set_seqnum (msg, seqnum);
2068 gst_element_post_message (GST_ELEMENT (demux), msg);
2071 GST_OBJECT_LOCK (demux);
2072 if (demux->new_segment)
2073 gst_event_unref (demux->new_segment);
2075 /* On port from 0.10, discarded !update (for segment.update) here, FIXME? */
2076 demux->new_segment = gst_event_new_segment (&demux->common.segment);
2077 gst_event_set_seqnum (demux->new_segment, seqnum);
2078 if (demux->common.segment.rate < 0 && demux->common.segment.stop == -1)
2079 demux->to_time = demux->common.segment.position;
2081 demux->to_time = GST_CLOCK_TIME_NONE;
2082 GST_OBJECT_UNLOCK (demux);
2084 /* restart our task since it might have been stopped when we did the
2086 gst_pad_start_task (demux->common.sinkpad,
2087 (GstTaskFunction) gst_matroska_demux_loop, demux->common.sinkpad, NULL);
2089 /* streaming can continue now */
2091 GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
2099 GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
2101 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Got a seek error"));
2107 * Handle whether we can perform the seek event or if we have to let the chain
2108 * function handle seeks to build the seek indexes first.
2111 gst_matroska_demux_handle_seek_push (GstMatroskaDemux * demux, GstPad * pad,
2115 GstSeekType cur_type, stop_type;
2120 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
2125 /* we can only seek on time */
2126 if (format != GST_FORMAT_TIME) {
2127 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
2131 if (stop_type != GST_SEEK_TYPE_NONE && stop != GST_CLOCK_TIME_NONE) {
2132 GST_DEBUG_OBJECT (demux, "Seek end-time not supported in streaming mode");
2136 if (!(flags & GST_SEEK_FLAG_FLUSH)) {
2137 GST_DEBUG_OBJECT (demux,
2138 "Non-flushing seek not supported in streaming mode");
2142 if (flags & GST_SEEK_FLAG_SEGMENT) {
2143 GST_DEBUG_OBJECT (demux, "Segment seek not supported in streaming mode");
2147 /* check for having parsed index already */
2148 if (!demux->common.index_parsed) {
2149 gboolean building_index;
2152 if (!demux->index_offset) {
2153 GST_DEBUG_OBJECT (demux, "no index (location); no seek in push mode");
2157 GST_OBJECT_LOCK (demux);
2158 /* handle the seek event in the chain function */
2159 demux->common.state = GST_MATROSKA_READ_STATE_SEEK;
2160 /* no more seek can be issued until state reset to _DATA */
2162 /* copy the event */
2163 if (demux->seek_event)
2164 gst_event_unref (demux->seek_event);
2165 demux->seek_event = gst_event_ref (event);
2167 /* set the building_index flag so that only one thread can setup the
2168 * structures for index seeking. */
2169 building_index = demux->building_index;
2170 if (!building_index) {
2171 demux->building_index = TRUE;
2172 offset = demux->index_offset;
2174 GST_OBJECT_UNLOCK (demux);
2176 if (!building_index) {
2177 /* seek to the first subindex or legacy index */
2178 GST_INFO_OBJECT (demux, "Seeking to Cues at %" G_GUINT64_FORMAT, offset);
2179 return perform_seek_to_offset (demux, rate, offset,
2180 gst_event_get_seqnum (event));
2183 /* well, we are handling it already */
2187 /* delegate to tweaked regular seek */
2188 return gst_matroska_demux_handle_seek_event (demux, pad, event);
2192 gst_matroska_demux_handle_src_event (GstPad * pad, GstObject * parent,
2195 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
2196 gboolean res = TRUE;
2198 switch (GST_EVENT_TYPE (event)) {
2199 case GST_EVENT_SEEK:
2200 /* no seeking until we are (safely) ready */
2201 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
2202 GST_DEBUG_OBJECT (demux, "not ready for seeking yet");
2205 if (!demux->streaming)
2206 res = gst_matroska_demux_handle_seek_event (demux, pad, event);
2208 res = gst_matroska_demux_handle_seek_push (demux, pad, event);
2209 gst_event_unref (event);
2214 GstMatroskaTrackContext *context = gst_pad_get_element_private (pad);
2215 if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
2216 GstMatroskaTrackVideoContext *videocontext =
2217 (GstMatroskaTrackVideoContext *) context;
2219 GstClockTimeDiff diff;
2220 GstClockTime timestamp;
2222 gst_event_parse_qos (event, NULL, &proportion, &diff, ×tamp);
2224 GST_OBJECT_LOCK (demux);
2225 videocontext->earliest_time = timestamp + diff;
2226 GST_OBJECT_UNLOCK (demux);
2229 gst_event_unref (event);
2233 case GST_EVENT_TOC_SELECT:
2236 GstTocEntry *entry = NULL;
2237 GstEvent *seek_event;
2240 if (!demux->common.toc) {
2241 GST_DEBUG_OBJECT (demux, "no TOC to select");
2244 gst_event_parse_toc_select (event, &uid);
2246 GST_OBJECT_LOCK (demux);
2247 entry = gst_toc_find_entry (demux->common.toc, uid);
2248 if (entry == NULL) {
2249 GST_OBJECT_UNLOCK (demux);
2250 GST_WARNING_OBJECT (demux, "no TOC entry with given UID: %s", uid);
2253 gst_toc_entry_get_start_stop_times (entry, &start_pos, NULL);
2254 GST_OBJECT_UNLOCK (demux);
2255 seek_event = gst_event_new_seek (1.0,
2257 GST_SEEK_FLAG_FLUSH,
2258 GST_SEEK_TYPE_SET, start_pos, GST_SEEK_TYPE_SET, -1);
2259 res = gst_matroska_demux_handle_seek_event (demux, pad, seek_event);
2260 gst_event_unref (seek_event);
2264 GST_WARNING_OBJECT (demux, "received empty TOC select event");
2268 gst_event_unref (event);
2272 /* events we don't need to handle */
2273 case GST_EVENT_NAVIGATION:
2274 gst_event_unref (event);
2278 case GST_EVENT_LATENCY:
2280 res = gst_pad_push_event (demux->common.sinkpad, event);
2287 static GstFlowReturn
2288 gst_matroska_demux_seek_to_previous_keyframe (GstMatroskaDemux * demux)
2290 GstFlowReturn ret = GST_FLOW_EOS;
2291 gboolean done = TRUE;
2294 g_return_val_if_fail (demux->seek_index, GST_FLOW_EOS);
2295 g_return_val_if_fail (demux->seek_entry < demux->seek_index->len,
2298 GST_DEBUG_OBJECT (demux, "locating previous keyframe");
2300 if (!demux->seek_entry) {
2301 GST_DEBUG_OBJECT (demux, "no earlier index entry");
2305 for (i = 0; i < demux->common.src->len; i++) {
2306 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
2308 GST_DEBUG_OBJECT (demux, "segment start %" GST_TIME_FORMAT
2309 ", stream %d at %" GST_TIME_FORMAT,
2310 GST_TIME_ARGS (demux->common.segment.start), stream->index,
2311 GST_TIME_ARGS (stream->from_time));
2312 if (GST_CLOCK_TIME_IS_VALID (stream->from_time)) {
2313 if (stream->from_time > demux->common.segment.start) {
2314 GST_DEBUG_OBJECT (demux, "stream %d not finished yet", stream->index);
2318 /* nothing pushed for this stream;
2319 * likely seek entry did not start at keyframe, so all was skipped.
2320 * So we need an earlier entry */
2326 GstMatroskaIndex *entry;
2328 entry = &g_array_index (demux->seek_index, GstMatroskaIndex,
2329 --demux->seek_entry);
2330 if (!gst_matroska_demux_move_to_entry (demux, entry, FALSE, TRUE))
2340 static GstFlowReturn
2341 gst_matroska_demux_parse_tracks (GstMatroskaDemux * demux, GstEbmlRead * ebml)
2343 GstFlowReturn ret = GST_FLOW_OK;
2346 DEBUG_ELEMENT_START (demux, ebml, "Tracks");
2348 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2349 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
2353 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
2354 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
2358 /* one track within the "all-tracks" header */
2359 case GST_MATROSKA_ID_TRACKENTRY:
2360 ret = gst_matroska_demux_add_stream (demux, ebml);
2364 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
2369 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
2371 demux->tracks_parsed = TRUE;
2377 * Read signed/unsigned "EBML" numbers.
2378 * Return: number of bytes processed.
2382 gst_matroska_ebmlnum_uint (guint8 * data, guint size, guint64 * num)
2384 gint len_mask = 0x80, read = 1, n = 1, num_ffs = 0;
2392 while (read <= 8 && !(total & len_mask)) {
2399 if ((total &= (len_mask - 1)) == len_mask - 1)
2404 if (data[n] == 0xff)
2406 total = (total << 8) | data[n];
2410 if (read == num_ffs && total != 0)
2419 gst_matroska_ebmlnum_sint (guint8 * data, guint size, gint64 * num)
2424 /* read as unsigned number first */
2425 if ((res = gst_matroska_ebmlnum_uint (data, size, &unum)) < 0)
2429 if (unum == G_MAXUINT64)
2432 *num = unum - ((1 << ((7 * res) - 1)) - 1);
2438 * Mostly used for subtitles. We add void filler data for each
2439 * lagging stream to make sure we don't deadlock.
2443 gst_matroska_demux_sync_streams (GstMatroskaDemux * demux)
2447 GST_OBJECT_LOCK (demux);
2449 GST_LOG_OBJECT (demux, "Sync to %" GST_TIME_FORMAT,
2450 GST_TIME_ARGS (demux->common.segment.position));
2452 g_assert (demux->common.num_streams == demux->common.src->len);
2453 for (stream_nr = 0; stream_nr < demux->common.src->len; stream_nr++) {
2454 GstMatroskaTrackContext *context;
2456 context = g_ptr_array_index (demux->common.src, stream_nr);
2458 GST_LOG_OBJECT (demux,
2459 "Checking for resync on stream %d (%" GST_TIME_FORMAT ")", stream_nr,
2460 GST_TIME_ARGS (context->pos));
2462 if (G_LIKELY (context->type != GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
2463 GST_LOG_OBJECT (demux, "Skipping sync on non-subtitle stream");
2467 /* does it lag? 0.5 seconds is a random threshold...
2468 * lag need only be considered if we have advanced into requested segment */
2469 if (GST_CLOCK_TIME_IS_VALID (context->pos) &&
2470 GST_CLOCK_TIME_IS_VALID (demux->common.segment.position) &&
2471 demux->common.segment.position > demux->common.segment.start &&
2472 context->pos + (GST_SECOND / 2) < demux->common.segment.position) {
2475 guint64 start = context->pos;
2476 guint64 stop = demux->common.segment.position - (GST_SECOND / 2);
2478 GST_DEBUG_OBJECT (demux,
2479 "Synchronizing stream %d with other by advancing time from %"
2480 GST_TIME_FORMAT " to %" GST_TIME_FORMAT, stream_nr,
2481 GST_TIME_ARGS (start), GST_TIME_ARGS (stop));
2483 context->pos = stop;
2485 event = gst_event_new_gap (start, stop - start);
2486 GST_OBJECT_UNLOCK (demux);
2487 gst_pad_push_event (context->pad, event);
2488 GST_OBJECT_LOCK (demux);
2492 GST_OBJECT_UNLOCK (demux);
2495 static GstFlowReturn
2496 gst_matroska_demux_push_stream_headers (GstMatroskaDemux * demux,
2497 GstMatroskaTrackContext * stream)
2499 GstFlowReturn ret = GST_FLOW_OK;
2502 num = gst_buffer_list_length (stream->stream_headers);
2503 for (i = 0; i < num; ++i) {
2506 buf = gst_buffer_list_get (stream->stream_headers, i);
2507 buf = gst_buffer_copy (buf);
2509 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
2511 if (stream->set_discont) {
2512 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
2513 stream->set_discont = FALSE;
2515 GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DISCONT);
2518 /* push out all headers in one go and use last flow return */
2519 ret = gst_pad_push (stream->pad, buf);
2522 /* don't need these any longer */
2523 gst_buffer_list_unref (stream->stream_headers);
2524 stream->stream_headers = NULL;
2527 ret = gst_flow_combiner_update_flow (demux->flowcombiner, ret);
2533 gst_matroska_demux_push_dvd_clut_change_event (GstMatroskaDemux * demux,
2534 GstMatroskaTrackContext * stream)
2538 g_assert (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB));
2540 if (!stream->codec_priv)
2543 /* ideally, VobSub private data should be parsed and stored more convenient
2544 * elsewhere, but for now, only interested in a small part */
2546 /* make sure we have terminating 0 */
2547 buf = g_strndup (stream->codec_priv, stream->codec_priv_size);
2549 /* just locate and parse palette part */
2550 start = strstr (buf, "palette:");
2555 guint8 r, g, b, y, u, v;
2558 while (g_ascii_isspace (*start))
2560 for (i = 0; i < 16; i++) {
2561 if (sscanf (start, "%06x", &col) != 1)
2564 while ((*start == ',') || g_ascii_isspace (*start))
2566 /* sigh, need to convert this from vobsub pseudo-RGB to YUV */
2567 r = (col >> 16) & 0xff;
2568 g = (col >> 8) & 0xff;
2570 y = CLAMP ((0.1494 * r + 0.6061 * g + 0.2445 * b) * 219 / 255 + 16, 0,
2572 u = CLAMP (0.6066 * r - 0.4322 * g - 0.1744 * b + 128, 0, 255);
2573 v = CLAMP (-0.08435 * r - 0.3422 * g + 0.4266 * b + 128, 0, 255);
2574 clut[i] = (y << 16) | (u << 8) | v;
2577 /* got them all without problems; build and send event */
2581 s = gst_structure_new ("application/x-gst-dvd", "event", G_TYPE_STRING,
2582 "dvd-spu-clut-change", "clut00", G_TYPE_INT, clut[0], "clut01",
2583 G_TYPE_INT, clut[1], "clut02", G_TYPE_INT, clut[2], "clut03",
2584 G_TYPE_INT, clut[3], "clut04", G_TYPE_INT, clut[4], "clut05",
2585 G_TYPE_INT, clut[5], "clut06", G_TYPE_INT, clut[6], "clut07",
2586 G_TYPE_INT, clut[7], "clut08", G_TYPE_INT, clut[8], "clut09",
2587 G_TYPE_INT, clut[9], "clut10", G_TYPE_INT, clut[10], "clut11",
2588 G_TYPE_INT, clut[11], "clut12", G_TYPE_INT, clut[12], "clut13",
2589 G_TYPE_INT, clut[13], "clut14", G_TYPE_INT, clut[14], "clut15",
2590 G_TYPE_INT, clut[15], NULL);
2592 gst_pad_push_event (stream->pad,
2593 gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM_STICKY, s));
2600 gst_matroska_demux_push_codec_data_all (GstMatroskaDemux * demux)
2604 GST_OBJECT_LOCK (demux);
2606 g_assert (demux->common.num_streams == demux->common.src->len);
2607 for (stream_nr = 0; stream_nr < demux->common.src->len; stream_nr++) {
2608 GstMatroskaTrackContext *stream;
2610 stream = g_ptr_array_index (demux->common.src, stream_nr);
2612 if (stream->send_stream_headers) {
2613 if (stream->stream_headers != NULL) {
2614 gst_matroska_demux_push_stream_headers (demux, stream);
2616 /* FIXME: perhaps we can just disable and skip this stream then */
2617 GST_ELEMENT_ERROR (demux, STREAM, DECODE, (NULL),
2618 ("Failed to extract stream headers from codec private data"));
2620 stream->send_stream_headers = FALSE;
2623 if (stream->send_dvd_event) {
2624 gst_matroska_demux_push_dvd_clut_change_event (demux, stream);
2625 /* FIXME: should we send this event again after (flushing) seek ? */
2626 stream->send_dvd_event = FALSE;
2630 GST_OBJECT_UNLOCK (demux);
2633 static GstFlowReturn
2634 gst_matroska_demux_add_mpeg_seq_header (GstElement * element,
2635 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2638 guint seq_header_len;
2639 guint32 header, tmp;
2641 if (stream->codec_state) {
2642 seq_header = stream->codec_state;
2643 seq_header_len = stream->codec_state_size;
2644 } else if (stream->codec_priv) {
2645 seq_header = stream->codec_priv;
2646 seq_header_len = stream->codec_priv_size;
2651 /* Sequence header only needed for keyframes */
2652 if (GST_BUFFER_FLAG_IS_SET (*buf, GST_BUFFER_FLAG_DELTA_UNIT))
2655 if (gst_buffer_get_size (*buf) < 4)
2658 gst_buffer_extract (*buf, 0, &tmp, sizeof (guint32));
2659 header = GUINT32_FROM_BE (tmp);
2661 /* Sequence start code, if not found prepend */
2662 if (header != 0x000001b3) {
2665 GST_DEBUG_OBJECT (element, "Prepending MPEG sequence header");
2667 newbuf = gst_buffer_new_wrapped (g_memdup (seq_header, seq_header_len),
2670 gst_buffer_copy_into (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
2671 GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_MEMORY, 0,
2672 gst_buffer_get_size (*buf));
2674 gst_buffer_unref (*buf);
2681 static GstFlowReturn
2682 gst_matroska_demux_add_wvpk_header (GstElement * element,
2683 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2685 GstMatroskaTrackAudioContext *audiocontext =
2686 (GstMatroskaTrackAudioContext *) stream;
2687 GstBuffer *newbuf = NULL;
2688 GstMapInfo map, outmap;
2689 guint8 *buf_data, *data;
2697 wvh.version = GST_READ_UINT16_LE (stream->codec_priv);
2700 wvh.total_samples = -1;
2701 wvh.block_index = audiocontext->wvpk_block_index;
2703 if (audiocontext->channels <= 2) {
2704 guint32 block_samples, tmp;
2705 gsize size = gst_buffer_get_size (*buf);
2707 gst_buffer_extract (*buf, 0, &tmp, sizeof (guint32));
2708 block_samples = GUINT32_FROM_LE (tmp);
2709 /* we need to reconstruct the header of the wavpack block */
2711 /* -20 because ck_size is the size of the wavpack block -8
2712 * and lace_size is the size of the wavpack block + 12
2713 * (the three guint32 of the header that already are in the buffer) */
2714 wvh.ck_size = size + sizeof (Wavpack4Header) - 20;
2716 /* block_samples, flags and crc are already in the buffer */
2717 newbuf = gst_buffer_new_allocate (NULL, sizeof (Wavpack4Header) - 12, NULL);
2719 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2725 GST_WRITE_UINT32_LE (data + 4, wvh.ck_size);
2726 GST_WRITE_UINT16_LE (data + 8, wvh.version);
2727 GST_WRITE_UINT8 (data + 10, wvh.track_no);
2728 GST_WRITE_UINT8 (data + 11, wvh.index_no);
2729 GST_WRITE_UINT32_LE (data + 12, wvh.total_samples);
2730 GST_WRITE_UINT32_LE (data + 16, wvh.block_index);
2732 /* Append data from buf: */
2733 gst_buffer_copy_into (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
2734 GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_MEMORY, 0, size);
2736 gst_buffer_unref (*buf);
2738 audiocontext->wvpk_block_index += block_samples;
2740 guint8 *outdata = NULL;
2742 gsize buf_size, size, out_size = 0;
2743 guint32 block_samples, flags, crc, blocksize;
2745 gst_buffer_map (*buf, &map, GST_MAP_READ);
2746 buf_data = map.data;
2747 buf_size = map.size;
2750 GST_ERROR_OBJECT (element, "Too small wavpack buffer");
2751 gst_buffer_unmap (*buf, &map);
2752 return GST_FLOW_ERROR;
2758 block_samples = GST_READ_UINT32_LE (data);
2763 flags = GST_READ_UINT32_LE (data);
2766 crc = GST_READ_UINT32_LE (data);
2769 blocksize = GST_READ_UINT32_LE (data);
2773 if (blocksize == 0 || size < blocksize)
2776 g_assert ((newbuf == NULL) == (outdata == NULL));
2778 if (newbuf == NULL) {
2779 out_size = sizeof (Wavpack4Header) + blocksize;
2780 newbuf = gst_buffer_new_allocate (NULL, out_size, NULL);
2782 gst_buffer_copy_into (newbuf, *buf,
2783 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS, 0, -1);
2786 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2787 outdata = outmap.data;
2789 gst_buffer_unmap (newbuf, &outmap);
2790 out_size += sizeof (Wavpack4Header) + blocksize;
2791 gst_buffer_set_size (newbuf, out_size);
2792 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2793 outdata = outmap.data;
2796 outdata[outpos] = 'w';
2797 outdata[outpos + 1] = 'v';
2798 outdata[outpos + 2] = 'p';
2799 outdata[outpos + 3] = 'k';
2802 GST_WRITE_UINT32_LE (outdata + outpos,
2803 blocksize + sizeof (Wavpack4Header) - 8);
2804 GST_WRITE_UINT16_LE (outdata + outpos + 4, wvh.version);
2805 GST_WRITE_UINT8 (outdata + outpos + 6, wvh.track_no);
2806 GST_WRITE_UINT8 (outdata + outpos + 7, wvh.index_no);
2807 GST_WRITE_UINT32_LE (outdata + outpos + 8, wvh.total_samples);
2808 GST_WRITE_UINT32_LE (outdata + outpos + 12, wvh.block_index);
2809 GST_WRITE_UINT32_LE (outdata + outpos + 16, block_samples);
2810 GST_WRITE_UINT32_LE (outdata + outpos + 20, flags);
2811 GST_WRITE_UINT32_LE (outdata + outpos + 24, crc);
2814 memmove (outdata + outpos, data, blocksize);
2815 outpos += blocksize;
2819 gst_buffer_unmap (*buf, &map);
2820 gst_buffer_unref (*buf);
2823 gst_buffer_unmap (newbuf, &outmap);
2826 audiocontext->wvpk_block_index += block_samples;
2832 /* @text must be null-terminated */
2834 gst_matroska_demux_subtitle_chunk_has_tag (GstElement * element,
2839 g_return_val_if_fail (text != NULL, FALSE);
2841 /* yes, this might all lead to false positives ... */
2842 tag = (gchar *) text;
2843 while ((tag = strchr (tag, '<'))) {
2845 if (*tag != '\0' && *(tag + 1) == '>') {
2846 /* some common convenience ones */
2847 /* maybe any character will do here ? */
2860 if (strstr (text, "<span"))
2866 static GstFlowReturn
2867 gst_matroska_demux_check_subtitle_buffer (GstElement * element,
2868 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2870 GstMatroskaTrackSubtitleContext *sub_stream;
2871 const gchar *encoding;
2876 gboolean needs_unmap = TRUE;
2878 sub_stream = (GstMatroskaTrackSubtitleContext *) stream;
2880 if (!gst_buffer_get_size (*buf) || !gst_buffer_map (*buf, &map, GST_MAP_READ))
2883 /* Need \0-terminator at the end */
2884 if (map.data[map.size - 1] != '\0') {
2885 newbuf = gst_buffer_new_and_alloc (map.size + 1);
2887 /* Copy old buffer and add a 0 at the end */
2888 gst_buffer_fill (newbuf, 0, map.data, map.size);
2889 gst_buffer_memset (newbuf, map.size, 0, 1);
2890 gst_buffer_unmap (*buf, &map);
2892 gst_buffer_copy_into (newbuf, *buf,
2893 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS |
2894 GST_BUFFER_COPY_META, 0, -1);
2895 gst_buffer_unref (*buf);
2897 gst_buffer_map (*buf, &map, GST_MAP_READ);
2900 if (!sub_stream->invalid_utf8) {
2901 if (g_utf8_validate ((gchar *) map.data, map.size - 1, NULL)) {
2904 GST_WARNING_OBJECT (element, "subtitle stream %" G_GUINT64_FORMAT
2905 " is not valid UTF-8, this is broken according to the matroska"
2906 " specification", stream->num);
2907 sub_stream->invalid_utf8 = TRUE;
2910 /* file with broken non-UTF8 subtitle, do the best we can do to fix it */
2911 encoding = g_getenv ("GST_SUBTITLE_ENCODING");
2912 if (encoding == NULL || *encoding == '\0') {
2913 /* if local encoding is UTF-8 and no encoding specified
2914 * via the environment variable, assume ISO-8859-15 */
2915 if (g_get_charset (&encoding)) {
2916 encoding = "ISO-8859-15";
2921 g_convert_with_fallback ((gchar *) map.data, map.size, "UTF-8", encoding,
2922 (char *) "*", NULL, NULL, &err);
2925 GST_LOG_OBJECT (element, "could not convert string from '%s' to UTF-8: %s",
2926 encoding, err->message);
2930 /* invalid input encoding, fall back to ISO-8859-15 (always succeeds) */
2931 encoding = "ISO-8859-15";
2933 g_convert_with_fallback ((gchar *) map.data, map.size, "UTF-8",
2934 encoding, (char *) "*", NULL, NULL, NULL);
2937 GST_LOG_OBJECT (element, "converted subtitle text from %s to UTF-8 %s",
2938 encoding, (err) ? "(using ISO-8859-15 as fallback)" : "");
2941 utf8 = g_strdup ("invalid subtitle");
2943 newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
2944 gst_buffer_unmap (*buf, &map);
2945 gst_buffer_copy_into (newbuf, *buf,
2946 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_META,
2948 gst_buffer_unref (*buf);
2951 gst_buffer_map (*buf, &map, GST_MAP_READ);
2955 if (sub_stream->check_markup) {
2956 /* caps claim markup text, so we need to escape text,
2957 * except if text is already markup and then needs no further escaping */
2958 sub_stream->seen_markup_tag = sub_stream->seen_markup_tag ||
2959 gst_matroska_demux_subtitle_chunk_has_tag (element, (gchar *) map.data);
2961 if (!sub_stream->seen_markup_tag) {
2962 utf8 = g_markup_escape_text ((gchar *) map.data, map.size);
2964 newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
2965 gst_buffer_unmap (*buf, &map);
2966 gst_buffer_copy_into (newbuf, *buf,
2967 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS |
2968 GST_BUFFER_COPY_META, 0, -1);
2969 gst_buffer_unref (*buf);
2972 needs_unmap = FALSE;
2977 gst_buffer_unmap (*buf, &map);
2982 static GstFlowReturn
2983 gst_matroska_demux_check_aac (GstElement * element,
2984 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2989 gst_buffer_extract (*buf, 0, data, 2);
2990 size = gst_buffer_get_size (*buf);
2992 if (size > 2 && data[0] == 0xff && (data[1] >> 4 == 0x0f)) {
2995 /* tss, ADTS data, remove codec_data
2996 * still assume it is at least parsed */
2997 stream->caps = gst_caps_make_writable (stream->caps);
2998 s = gst_caps_get_structure (stream->caps, 0);
3000 gst_structure_remove_field (s, "codec_data");
3001 gst_pad_set_caps (stream->pad, stream->caps);
3002 GST_DEBUG_OBJECT (element, "ADTS AAC audio data; removing codec-data, "
3003 "new caps: %" GST_PTR_FORMAT, stream->caps);
3006 /* disable subsequent checking */
3007 stream->postprocess_frame = NULL;
3013 gst_matroska_demux_align_buffer (GstMatroskaDemux * demux,
3014 GstBuffer * buffer, gsize alignment)
3018 gst_buffer_map (buffer, &map, GST_MAP_READ);
3020 if (map.size < sizeof (guintptr)) {
3021 gst_buffer_unmap (buffer, &map);
3025 if (((guintptr) map.data) & (alignment - 1)) {
3026 GstBuffer *new_buffer;
3027 GstAllocationParams params = { 0, alignment - 1, 0, 0, };
3029 new_buffer = gst_buffer_new_allocate (NULL,
3030 gst_buffer_get_size (buffer), ¶ms);
3032 /* Copy data "by hand", so ensure alignment is kept: */
3033 gst_buffer_fill (new_buffer, 0, map.data, map.size);
3035 gst_buffer_copy_into (new_buffer, buffer, GST_BUFFER_COPY_METADATA, 0, -1);
3036 GST_DEBUG_OBJECT (demux,
3037 "We want output aligned on %" G_GSIZE_FORMAT ", reallocated",
3040 gst_buffer_unmap (buffer, &map);
3041 gst_buffer_unref (buffer);
3046 gst_buffer_unmap (buffer, &map);
3050 static GstFlowReturn
3051 gst_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux,
3052 GstEbmlRead * ebml, guint64 cluster_time, guint64 cluster_offset,
3053 gboolean is_simpleblock)
3055 GstMatroskaTrackContext *stream = NULL;
3056 GstFlowReturn ret = GST_FLOW_OK;
3057 gboolean readblock = FALSE;
3059 guint64 block_duration = -1;
3060 GstBuffer *buf = NULL;
3062 gint stream_num = -1, n, laces = 0;
3064 gint *lace_size = NULL;
3067 gint64 referenceblock = 0;
3070 offset = gst_ebml_read_get_offset (ebml);
3072 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3073 if (!is_simpleblock) {
3074 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK) {
3078 id = GST_MATROSKA_ID_SIMPLEBLOCK;
3082 /* one block inside the group. Note, block parsing is one
3083 * of the harder things, so this code is a bit complicated.
3084 * See http://www.matroska.org/ for documentation. */
3085 case GST_MATROSKA_ID_SIMPLEBLOCK:
3086 case GST_MATROSKA_ID_BLOCK:
3092 gst_buffer_unmap (buf, &map);
3093 gst_buffer_unref (buf);
3096 if ((ret = gst_ebml_read_buffer (ebml, &id, &buf)) != GST_FLOW_OK)
3099 gst_buffer_map (buf, &map, GST_MAP_READ);
3103 /* first byte(s): blocknum */
3104 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
3109 /* fetch stream from num */
3110 stream_num = gst_matroska_read_common_stream_from_num (&demux->common,
3112 if (G_UNLIKELY (size < 3)) {
3113 GST_WARNING_OBJECT (demux, "Invalid size %u", size);
3114 /* non-fatal, try next block(group) */
3117 } else if (G_UNLIKELY (stream_num < 0 ||
3118 stream_num >= demux->common.num_streams)) {
3119 /* let's not give up on a stray invalid track number */
3120 GST_WARNING_OBJECT (demux,
3121 "Invalid stream %d for track number %" G_GUINT64_FORMAT
3122 "; ignoring block", stream_num, num);
3126 stream = g_ptr_array_index (demux->common.src, stream_num);
3128 /* time (relative to cluster time) */
3129 time = ((gint16) GST_READ_UINT16_BE (data));
3132 flags = GST_READ_UINT8 (data);
3136 GST_LOG_OBJECT (demux, "time %" G_GUINT64_FORMAT ", flags %d", time,
3139 switch ((flags & 0x06) >> 1) {
3140 case 0x0: /* no lacing */
3142 lace_size = g_new (gint, 1);
3143 lace_size[0] = size;
3146 case 0x1: /* xiph lacing */
3147 case 0x2: /* fixed-size lacing */
3148 case 0x3: /* EBML lacing */
3150 goto invalid_lacing;
3151 laces = GST_READ_UINT8 (data) + 1;
3154 lace_size = g_new0 (gint, laces);
3156 switch ((flags & 0x06) >> 1) {
3157 case 0x1: /* xiph lacing */ {
3158 guint temp, total = 0;
3160 for (n = 0; ret == GST_FLOW_OK && n < laces - 1; n++) {
3163 goto invalid_lacing;
3164 temp = GST_READ_UINT8 (data);
3165 lace_size[n] += temp;
3171 total += lace_size[n];
3173 lace_size[n] = size - total;
3177 case 0x2: /* fixed-size lacing */
3178 for (n = 0; n < laces; n++)
3179 lace_size[n] = size / laces;
3182 case 0x3: /* EBML lacing */ {
3185 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
3189 total = lace_size[0] = num;
3190 for (n = 1; ret == GST_FLOW_OK && n < laces - 1; n++) {
3194 if ((r = gst_matroska_ebmlnum_sint (data, size, &snum)) < 0)
3198 lace_size[n] = lace_size[n - 1] + snum;
3199 total += lace_size[n];
3202 lace_size[n] = size - total;
3209 if (ret != GST_FLOW_OK)
3216 case GST_MATROSKA_ID_BLOCKDURATION:{
3217 ret = gst_ebml_read_uint (ebml, &id, &block_duration);
3218 GST_DEBUG_OBJECT (demux, "BlockDuration: %" G_GUINT64_FORMAT,
3223 case GST_MATROSKA_ID_REFERENCEBLOCK:{
3224 ret = gst_ebml_read_sint (ebml, &id, &referenceblock);
3225 GST_DEBUG_OBJECT (demux, "ReferenceBlock: %" G_GINT64_FORMAT,
3230 case GST_MATROSKA_ID_CODECSTATE:{
3232 guint64 data_len = 0;
3235 gst_ebml_read_binary (ebml, &id, &data,
3236 &data_len)) != GST_FLOW_OK)
3239 if (G_UNLIKELY (stream == NULL)) {
3240 GST_WARNING_OBJECT (demux,
3241 "Unexpected CodecState subelement - ignoring");
3245 g_free (stream->codec_state);
3246 stream->codec_state = data;
3247 stream->codec_state_size = data_len;
3249 /* Decode if necessary */
3250 if (stream->encodings && stream->encodings->len > 0
3251 && stream->codec_state && stream->codec_state_size > 0) {
3252 if (!gst_matroska_decode_data (stream->encodings,
3253 &stream->codec_state, &stream->codec_state_size,
3254 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
3255 GST_WARNING_OBJECT (demux, "Decoding codec state failed");
3259 GST_DEBUG_OBJECT (demux, "CodecState of %" G_GSIZE_FORMAT " bytes",
3260 stream->codec_state_size);
3265 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3269 case GST_MATROSKA_ID_BLOCKVIRTUAL:
3270 case GST_MATROSKA_ID_BLOCKADDITIONS:
3271 case GST_MATROSKA_ID_REFERENCEPRIORITY:
3272 case GST_MATROSKA_ID_REFERENCEVIRTUAL:
3273 case GST_MATROSKA_ID_SLICES:
3274 GST_DEBUG_OBJECT (demux,
3275 "Skipping BlockGroup subelement 0x%x - ignoring", id);
3276 ret = gst_ebml_read_skip (ebml);
3284 /* reading a number or so could have failed */
3285 if (ret != GST_FLOW_OK)
3288 if (ret == GST_FLOW_OK && readblock) {
3289 gboolean invisible_frame = FALSE;
3290 gboolean delta_unit = FALSE;
3291 guint64 duration = 0;
3292 gint64 lace_time = 0;
3294 stream = g_ptr_array_index (demux->common.src, stream_num);
3296 if (cluster_time != GST_CLOCK_TIME_NONE) {
3297 /* FIXME: What to do with negative timestamps? Give timestamp 0 or -1?
3298 * Drop unless the lace contains timestamp 0? */
3299 if (time < 0 && (-time) > cluster_time) {
3302 if (stream->timecodescale == 1.0)
3303 lace_time = (cluster_time + time) * demux->common.time_scale;
3306 gst_util_guint64_to_gdouble ((cluster_time + time) *
3307 demux->common.time_scale) * stream->timecodescale;
3310 lace_time = GST_CLOCK_TIME_NONE;
3313 /* need to refresh segment info ASAP */
3314 if (GST_CLOCK_TIME_IS_VALID (lace_time) && demux->need_segment) {
3315 GstSegment *segment = &demux->common.segment;
3317 GstEvent *segment_event;
3319 if (!GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
3320 demux->stream_start_time = lace_time;
3321 GST_DEBUG_OBJECT (demux,
3322 "Setting stream start time to %" GST_TIME_FORMAT,
3323 GST_TIME_ARGS (lace_time));
3325 clace_time = MAX (lace_time, demux->stream_start_time);
3326 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.position) &&
3327 demux->common.segment.position != 0) {
3328 GST_DEBUG_OBJECT (demux,
3329 "using stored seek position %" GST_TIME_FORMAT,
3330 GST_TIME_ARGS (demux->common.segment.position));
3331 clace_time = demux->common.segment.position + demux->stream_start_time;
3332 segment->position = GST_CLOCK_TIME_NONE;
3334 segment->start = clace_time;
3335 segment->stop = GST_CLOCK_TIME_NONE;
3336 segment->time = segment->start - demux->stream_start_time;
3337 segment->position = segment->start - demux->stream_start_time;
3338 GST_DEBUG_OBJECT (demux,
3339 "generated segment starting at %" GST_TIME_FORMAT ": %"
3340 GST_SEGMENT_FORMAT, GST_TIME_ARGS (lace_time), segment);
3341 /* now convey our segment notion downstream */
3342 segment_event = gst_event_new_segment (segment);
3343 if (demux->segment_seqnum)
3344 gst_event_set_seqnum (segment_event, demux->segment_seqnum);
3345 gst_matroska_demux_send_event (demux, segment_event);
3346 demux->need_segment = FALSE;
3347 demux->segment_seqnum = 0;
3350 /* send pending codec data headers for all streams,
3351 * before we perform sync across all streams */
3352 gst_matroska_demux_push_codec_data_all (demux);
3354 if (block_duration != -1) {
3355 if (stream->timecodescale == 1.0)
3356 duration = gst_util_uint64_scale (block_duration,
3357 demux->common.time_scale, 1);
3360 gst_util_gdouble_to_guint64 (gst_util_guint64_to_gdouble
3361 (gst_util_uint64_scale (block_duration, demux->common.time_scale,
3362 1)) * stream->timecodescale);
3363 } else if (stream->default_duration) {
3364 duration = stream->default_duration * laces;
3366 /* else duration is diff between timecode of this and next block */
3368 /* For SimpleBlock, look at the keyframe bit in flags. Otherwise,
3369 a ReferenceBlock implies that this is not a keyframe. In either
3370 case, it only makes sense for video streams. */
3371 if (stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
3372 if ((is_simpleblock && !(flags & 0x80)) || referenceblock) {
3374 invisible_frame = ((flags & 0x08)) &&
3375 (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8) ||
3376 !strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP9));
3380 for (n = 0; n < laces; n++) {
3383 if (G_UNLIKELY (lace_size[n] > size)) {
3384 GST_WARNING_OBJECT (demux, "Invalid lace size");
3388 /* QoS for video track with an index. the assumption is that
3389 index entries point to keyframes, but if that is not true we
3390 will instad skip until the next keyframe. */
3391 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
3392 stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
3393 stream->index_table && demux->common.segment.rate > 0.0) {
3394 GstMatroskaTrackVideoContext *videocontext =
3395 (GstMatroskaTrackVideoContext *) stream;
3396 GstClockTime earliest_time;
3397 GstClockTime earliest_stream_time;
3399 GST_OBJECT_LOCK (demux);
3400 earliest_time = videocontext->earliest_time;
3401 GST_OBJECT_UNLOCK (demux);
3402 earliest_stream_time = gst_segment_to_position (&demux->common.segment,
3403 GST_FORMAT_TIME, earliest_time);
3405 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
3406 GST_CLOCK_TIME_IS_VALID (earliest_stream_time) &&
3407 lace_time <= earliest_stream_time) {
3408 /* find index entry (keyframe) <= earliest_stream_time */
3409 GstMatroskaIndex *entry =
3410 gst_util_array_binary_search (stream->index_table->data,
3411 stream->index_table->len, sizeof (GstMatroskaIndex),
3412 (GCompareDataFunc) gst_matroska_index_seek_find,
3413 GST_SEARCH_MODE_BEFORE, &earliest_stream_time, NULL);
3415 /* if that entry (keyframe) is after the current the current
3416 buffer, we can skip pushing (and thus decoding) all
3417 buffers until that keyframe. */
3418 if (entry && GST_CLOCK_TIME_IS_VALID (entry->time) &&
3419 entry->time > lace_time) {
3420 GST_LOG_OBJECT (demux, "Skipping lace before late keyframe");
3421 stream->set_discont = TRUE;
3427 sub = gst_buffer_copy_region (buf, GST_BUFFER_COPY_ALL,
3428 gst_buffer_get_size (buf) - size, lace_size[n]);
3429 GST_DEBUG_OBJECT (demux, "created subbuffer %p", sub);
3432 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
3434 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
3436 if (invisible_frame)
3437 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DECODE_ONLY);
3439 if (stream->encodings != NULL && stream->encodings->len > 0)
3440 sub = gst_matroska_decode_buffer (stream, sub);
3443 GST_WARNING_OBJECT (demux, "Decoding buffer failed");
3447 GST_BUFFER_TIMESTAMP (sub) = lace_time;
3449 if (GST_CLOCK_TIME_IS_VALID (lace_time)) {
3450 GstClockTime last_stop_end;
3452 /* Check if this stream is after segment stop */
3453 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop) &&
3454 lace_time >= demux->common.segment.stop) {
3455 GST_DEBUG_OBJECT (demux,
3456 "Stream %d after segment stop %" GST_TIME_FORMAT, stream->index,
3457 GST_TIME_ARGS (demux->common.segment.stop));
3458 gst_buffer_unref (sub);
3461 if (offset >= stream->to_offset
3462 || (GST_CLOCK_TIME_IS_VALID (demux->to_time)
3463 && lace_time > demux->to_time)) {
3464 GST_DEBUG_OBJECT (demux, "Stream %d after playback section",
3466 gst_buffer_unref (sub);
3470 /* handle gaps, e.g. non-zero start-time, or an cue index entry
3471 * that landed us with timestamps not quite intended */
3472 GST_OBJECT_LOCK (demux);
3473 if (demux->max_gap_time &&
3474 GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) &&
3475 demux->common.segment.rate > 0.0) {
3476 GstClockTimeDiff diff;
3478 /* only send segments with increasing start times,
3479 * otherwise if these go back and forth downstream (sinks) increase
3480 * accumulated time and running_time */
3481 diff = GST_CLOCK_DIFF (demux->last_stop_end, lace_time);
3482 if (diff > 0 && diff > demux->max_gap_time
3483 && lace_time > demux->common.segment.start
3484 && (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop)
3485 || lace_time < demux->common.segment.stop)) {
3487 GST_DEBUG_OBJECT (demux,
3488 "Gap of %" G_GINT64_FORMAT " ns detected in"
3489 "stream %d (%" GST_TIME_FORMAT " -> %" GST_TIME_FORMAT "). "
3490 "Sending updated SEGMENT events", diff,
3491 stream->index, GST_TIME_ARGS (stream->pos),
3492 GST_TIME_ARGS (lace_time));
3494 event = gst_event_new_gap (demux->last_stop_end, diff);
3495 GST_OBJECT_UNLOCK (demux);
3496 gst_pad_push_event (stream->pad, event);
3497 GST_OBJECT_LOCK (demux);
3501 if (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.position)
3502 || demux->common.segment.position < lace_time) {
3503 demux->common.segment.position = lace_time;
3505 GST_OBJECT_UNLOCK (demux);
3507 last_stop_end = lace_time;
3509 GST_BUFFER_DURATION (sub) = duration / laces;
3510 last_stop_end += GST_BUFFER_DURATION (sub);
3513 if (!GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) ||
3514 demux->last_stop_end < last_stop_end)
3515 demux->last_stop_end = last_stop_end;
3517 GST_OBJECT_LOCK (demux);
3518 if (demux->common.segment.duration == -1 ||
3519 demux->stream_start_time + demux->common.segment.duration <
3521 demux->common.segment.duration =
3522 last_stop_end - demux->stream_start_time;
3523 GST_OBJECT_UNLOCK (demux);
3524 if (!demux->invalid_duration) {
3525 gst_element_post_message (GST_ELEMENT_CAST (demux),
3526 gst_message_new_duration_changed (GST_OBJECT_CAST (demux)));
3527 demux->invalid_duration = TRUE;
3530 GST_OBJECT_UNLOCK (demux);
3534 stream->pos = lace_time;
3536 gst_matroska_demux_sync_streams (demux);
3538 if (stream->set_discont) {
3539 GST_DEBUG_OBJECT (demux, "marking DISCONT");
3540 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DISCONT);
3541 stream->set_discont = FALSE;
3543 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DISCONT);
3546 /* reverse playback book-keeping */
3547 if (!GST_CLOCK_TIME_IS_VALID (stream->from_time))
3548 stream->from_time = lace_time;
3549 if (stream->from_offset == -1)
3550 stream->from_offset = offset;
3552 GST_DEBUG_OBJECT (demux,
3553 "Pushing lace %d, data of size %" G_GSIZE_FORMAT
3554 " for stream %d, time=%" GST_TIME_FORMAT " and duration=%"
3555 GST_TIME_FORMAT, n, gst_buffer_get_size (sub), stream_num,
3556 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (sub)),
3557 GST_TIME_ARGS (GST_BUFFER_DURATION (sub)));
3560 if (demux->common.element_index) {
3561 if (stream->index_writer_id == -1)
3562 gst_index_get_writer_id (demux->common.element_index,
3563 GST_OBJECT (stream->pad), &stream->index_writer_id);
3565 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
3566 G_GUINT64_FORMAT " for writer id %d",
3567 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (sub)), cluster_offset,
3568 stream->index_writer_id);
3569 gst_index_add_association (demux->common.element_index,
3570 stream->index_writer_id, GST_BUFFER_FLAG_IS_SET (sub,
3571 GST_BUFFER_FLAG_DELTA_UNIT) ? 0 : GST_ASSOCIATION_FLAG_KEY_UNIT,
3572 GST_FORMAT_TIME, GST_BUFFER_TIMESTAMP (sub), GST_FORMAT_BYTES,
3573 cluster_offset, NULL);
3577 /* Postprocess the buffers depending on the codec used */
3578 if (stream->postprocess_frame) {
3579 GST_LOG_OBJECT (demux, "running post process");
3580 ret = stream->postprocess_frame (GST_ELEMENT (demux), stream, &sub);
3583 /* At this point, we have a sub-buffer pointing at data within a larger
3584 buffer. This data might not be aligned with anything. If the data is
3585 raw samples though, we want it aligned to the raw type (eg, 4 bytes
3586 for 32 bit samples, etc), or bad things will happen downstream as
3587 elements typically assume minimal alignment.
3588 Therefore, create an aligned copy if necessary. */
3589 g_assert (stream->alignment <= G_MEM_ALIGN);
3590 sub = gst_matroska_demux_align_buffer (demux, sub, stream->alignment);
3592 if (GST_BUFFER_PTS_IS_VALID (sub)) {
3593 stream->pos = GST_BUFFER_PTS (sub);
3594 if (GST_BUFFER_DURATION_IS_VALID (sub))
3595 stream->pos += GST_BUFFER_DURATION (sub);
3598 ret = gst_pad_push (stream->pad, sub);
3600 if (demux->common.segment.rate < 0) {
3601 if (lace_time > demux->common.segment.stop && ret == GST_FLOW_EOS) {
3602 /* In reverse playback we can get a GST_FLOW_EOS when
3603 * we are at the end of the segment, so we just need to jump
3604 * back to the previous section. */
3605 GST_DEBUG_OBJECT (demux, "downstream has reached end of segment");
3610 ret = gst_flow_combiner_update_flow (demux->flowcombiner, ret);
3613 size -= lace_size[n];
3614 if (lace_time != GST_CLOCK_TIME_NONE && duration)
3615 lace_time += duration / laces;
3617 lace_time = GST_CLOCK_TIME_NONE;
3623 gst_buffer_unmap (buf, &map);
3624 gst_buffer_unref (buf);
3636 ret = gst_flow_combiner_update_flow (demux->flowcombiner, ret);
3641 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Invalid lacing size"));
3642 /* non-fatal, try next block(group) */
3648 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Data error"));
3649 /* non-fatal, try next block(group) */
3655 /* return FALSE if block(group) should be skipped (due to a seek) */
3656 static inline gboolean
3657 gst_matroska_demux_seek_block (GstMatroskaDemux * demux)
3659 if (G_UNLIKELY (demux->seek_block)) {
3660 if (!(--demux->seek_block)) {
3663 GST_LOG_OBJECT (demux, "should skip block due to seek");
3671 static GstFlowReturn
3672 gst_matroska_demux_parse_contents_seekentry (GstMatroskaDemux * demux,
3676 guint64 seek_pos = (guint64) - 1;
3677 guint32 seek_id = 0;
3680 DEBUG_ELEMENT_START (demux, ebml, "Seek");
3682 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3683 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
3687 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3688 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3692 case GST_MATROSKA_ID_SEEKID:
3696 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
3699 GST_DEBUG_OBJECT (demux, "SeekID: %" G_GUINT64_FORMAT, t);
3704 case GST_MATROSKA_ID_SEEKPOSITION:
3708 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
3711 if (t > G_MAXINT64) {
3712 GST_WARNING_OBJECT (demux,
3713 "Too large SeekPosition %" G_GUINT64_FORMAT, t);
3717 GST_DEBUG_OBJECT (demux, "SeekPosition: %" G_GUINT64_FORMAT, t);
3723 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3729 if (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)
3732 if (!seek_id || seek_pos == (guint64) - 1) {
3733 GST_WARNING_OBJECT (demux, "Incomplete seekhead entry (0x%x/%"
3734 G_GUINT64_FORMAT ")", seek_id, seek_pos);
3739 case GST_MATROSKA_ID_SEEKHEAD:
3742 case GST_MATROSKA_ID_CUES:
3743 case GST_MATROSKA_ID_TAGS:
3744 case GST_MATROSKA_ID_TRACKS:
3745 case GST_MATROSKA_ID_SEGMENTINFO:
3746 case GST_MATROSKA_ID_ATTACHMENTS:
3747 case GST_MATROSKA_ID_CHAPTERS:
3749 guint64 before_pos, length;
3753 length = gst_matroska_read_common_get_length (&demux->common);
3754 before_pos = demux->common.offset;
3756 if (length == (guint64) - 1) {
3757 GST_DEBUG_OBJECT (demux, "no upstream length, skipping SeakHead entry");
3761 /* check for validity */
3762 if (seek_pos + demux->common.ebml_segment_start + 12 >= length) {
3763 GST_WARNING_OBJECT (demux,
3764 "SeekHead reference lies outside file!" " (%"
3765 G_GUINT64_FORMAT "+%" G_GUINT64_FORMAT "+12 >= %"
3766 G_GUINT64_FORMAT ")", seek_pos, demux->common.ebml_segment_start,
3771 /* only pick up index location when streaming */
3772 if (demux->streaming) {
3773 if (seek_id == GST_MATROSKA_ID_CUES) {
3774 demux->index_offset = seek_pos + demux->common.ebml_segment_start;
3775 GST_DEBUG_OBJECT (demux, "Cues located at offset %" G_GUINT64_FORMAT,
3776 demux->index_offset);
3782 demux->common.offset = seek_pos + demux->common.ebml_segment_start;
3785 if ((ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
3786 GST_ELEMENT_CAST (demux), &id, &length, &needed)) !=
3790 if (id != seek_id) {
3791 GST_WARNING_OBJECT (demux,
3792 "We looked for ID=0x%x but got ID=0x%x (pos=%" G_GUINT64_FORMAT ")",
3793 seek_id, id, seek_pos + demux->common.ebml_segment_start);
3796 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
3801 demux->common.offset = before_pos;
3805 case GST_MATROSKA_ID_CLUSTER:
3807 guint64 pos = seek_pos + demux->common.ebml_segment_start;
3809 GST_LOG_OBJECT (demux, "Cluster position");
3810 if (G_UNLIKELY (!demux->clusters))
3811 demux->clusters = g_array_sized_new (TRUE, TRUE, sizeof (guint64), 100);
3812 g_array_append_val (demux->clusters, pos);
3817 GST_DEBUG_OBJECT (demux, "Ignoring Seek entry for ID=0x%x", seek_id);
3820 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
3825 static GstFlowReturn
3826 gst_matroska_demux_parse_contents (GstMatroskaDemux * demux, GstEbmlRead * ebml)
3828 GstFlowReturn ret = GST_FLOW_OK;
3831 DEBUG_ELEMENT_START (demux, ebml, "SeekHead");
3833 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3834 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
3838 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3839 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3843 case GST_MATROSKA_ID_SEEKENTRY:
3845 ret = gst_matroska_demux_parse_contents_seekentry (demux, ebml);
3846 /* Ignore EOS and errors here */
3847 if (ret != GST_FLOW_OK) {
3848 GST_DEBUG_OBJECT (demux, "Ignoring %s", gst_flow_get_name (ret));
3855 ret = gst_matroska_read_common_parse_skip (&demux->common,
3856 ebml, "SeekHead", id);
3861 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
3863 /* Sort clusters by position for easier searching */
3864 if (demux->clusters)
3865 g_array_sort (demux->clusters, (GCompareFunc) gst_matroska_cluster_compare);
3870 #define GST_FLOW_OVERFLOW GST_FLOW_CUSTOM_ERROR
3872 #define MAX_BLOCK_SIZE (15 * 1024 * 1024)
3874 static inline GstFlowReturn
3875 gst_matroska_demux_check_read_size (GstMatroskaDemux * demux, guint64 bytes)
3877 if (G_UNLIKELY (bytes > MAX_BLOCK_SIZE)) {
3878 /* only a few blocks are expected/allowed to be large,
3879 * and will be recursed into, whereas others will be read and must fit */
3880 if (demux->streaming) {
3881 /* fatal in streaming case, as we can't step over easily */
3882 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
3883 ("reading large block of size %" G_GUINT64_FORMAT " not supported; "
3884 "file might be corrupt.", bytes));
3885 return GST_FLOW_ERROR;
3887 /* indicate higher level to quietly give up */
3888 GST_DEBUG_OBJECT (demux,
3889 "too large block of size %" G_GUINT64_FORMAT, bytes);
3890 return GST_FLOW_ERROR;
3897 /* returns TRUE if we truely are in error state, and should give up */
3898 static inline GstFlowReturn
3899 gst_matroska_demux_check_parse_error (GstMatroskaDemux * demux)
3901 if (!demux->streaming && demux->next_cluster_offset > 0) {
3902 /* just repositioning to where next cluster should be and try from there */
3903 GST_WARNING_OBJECT (demux, "parse error, trying next cluster expected at %"
3904 G_GUINT64_FORMAT, demux->next_cluster_offset);
3905 demux->common.offset = demux->next_cluster_offset;
3906 demux->next_cluster_offset = 0;
3912 /* sigh, one last attempt above and beyond call of duty ...;
3913 * search for cluster mark following current pos */
3914 pos = demux->common.offset;
3915 GST_WARNING_OBJECT (demux, "parse error, looking for next cluster");
3916 if ((ret = gst_matroska_demux_search_cluster (demux, &pos)) != GST_FLOW_OK) {
3917 /* did not work, give up */
3920 GST_DEBUG_OBJECT (demux, "... found at %" G_GUINT64_FORMAT, pos);
3921 /* try that position */
3922 demux->common.offset = pos;
3928 static inline GstFlowReturn
3929 gst_matroska_demux_flush (GstMatroskaDemux * demux, guint flush)
3931 GST_LOG_OBJECT (demux, "skipping %d bytes", flush);
3932 demux->common.offset += flush;
3933 if (demux->streaming) {
3936 /* hard to skip large blocks when streaming */
3937 ret = gst_matroska_demux_check_read_size (demux, flush);
3938 if (ret != GST_FLOW_OK)
3940 if (flush <= gst_adapter_available (demux->common.adapter))
3941 gst_adapter_flush (demux->common.adapter, flush);
3943 return GST_FLOW_EOS;
3948 /* initializes @ebml with @bytes from input stream at current offset.
3949 * Returns EOS if insufficient available,
3950 * ERROR if too much was attempted to read. */
3951 static inline GstFlowReturn
3952 gst_matroska_demux_take (GstMatroskaDemux * demux, guint64 bytes,
3955 GstBuffer *buffer = NULL;
3956 GstFlowReturn ret = GST_FLOW_OK;
3958 GST_LOG_OBJECT (demux, "taking %" G_GUINT64_FORMAT " bytes for parsing",
3960 ret = gst_matroska_demux_check_read_size (demux, bytes);
3961 if (G_UNLIKELY (ret != GST_FLOW_OK)) {
3962 if (!demux->streaming) {
3963 /* in pull mode, we can skip */
3964 if ((ret = gst_matroska_demux_flush (demux, bytes)) == GST_FLOW_OK)
3965 ret = GST_FLOW_OVERFLOW;
3967 /* otherwise fatal */
3968 ret = GST_FLOW_ERROR;
3972 if (demux->streaming) {
3973 if (gst_adapter_available (demux->common.adapter) >= bytes)
3974 buffer = gst_adapter_take_buffer (demux->common.adapter, bytes);
3978 ret = gst_matroska_read_common_peek_bytes (&demux->common,
3979 demux->common.offset, bytes, &buffer, NULL);
3980 if (G_LIKELY (buffer)) {
3981 gst_ebml_read_init (ebml, GST_ELEMENT_CAST (demux), buffer,
3982 demux->common.offset);
3983 demux->common.offset += bytes;
3990 gst_matroska_demux_check_seekability (GstMatroskaDemux * demux)
3993 gboolean seekable = FALSE;
3994 gint64 start = -1, stop = -1;
3996 query = gst_query_new_seeking (GST_FORMAT_BYTES);
3997 if (!gst_pad_peer_query (demux->common.sinkpad, query)) {
3998 GST_DEBUG_OBJECT (demux, "seeking query failed");
4002 gst_query_parse_seeking (query, NULL, &seekable, &start, &stop);
4004 /* try harder to query upstream size if we didn't get it the first time */
4005 if (seekable && stop == -1) {
4006 GST_DEBUG_OBJECT (demux, "doing duration query to fix up unset stop");
4007 gst_pad_peer_query_duration (demux->common.sinkpad, GST_FORMAT_BYTES,
4011 /* if upstream doesn't know the size, it's likely that it's not seekable in
4012 * practice even if it technically may be seekable */
4013 if (seekable && (start != 0 || stop <= start)) {
4014 GST_DEBUG_OBJECT (demux, "seekable but unknown start/stop -> disable");
4019 GST_INFO_OBJECT (demux, "seekable: %d (%" G_GUINT64_FORMAT " - %"
4020 G_GUINT64_FORMAT ")", seekable, start, stop);
4021 demux->seekable = seekable;
4023 gst_query_unref (query);
4026 static GstFlowReturn
4027 gst_matroska_demux_find_tracks (GstMatroskaDemux * demux)
4033 GstFlowReturn ret = GST_FLOW_OK;
4035 GST_WARNING_OBJECT (demux,
4036 "Found Cluster element before Tracks, searching Tracks");
4039 before_pos = demux->common.offset;
4041 /* Search Tracks element */
4043 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4044 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4045 if (ret != GST_FLOW_OK)
4048 if (id != GST_MATROSKA_ID_TRACKS) {
4049 /* we may be skipping large cluster here, so forego size check etc */
4050 /* ... but we can't skip undefined size; force error */
4051 if (length == G_MAXUINT64) {
4052 ret = gst_matroska_demux_check_read_size (demux, length);
4055 demux->common.offset += needed;
4056 demux->common.offset += length;
4061 /* will lead to track parsing ... */
4062 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4067 demux->common.offset = before_pos;
4072 #define GST_READ_CHECK(stmt) \
4074 if (G_UNLIKELY ((ret = (stmt)) != GST_FLOW_OK)) { \
4075 if (ret == GST_FLOW_OVERFLOW) { \
4076 ret = GST_FLOW_OK; \
4082 static GstFlowReturn
4083 gst_matroska_demux_parse_id (GstMatroskaDemux * demux, guint32 id,
4084 guint64 length, guint needed)
4086 GstEbmlRead ebml = { 0, };
4087 GstFlowReturn ret = GST_FLOW_OK;
4090 GST_LOG_OBJECT (demux, "Parsing Element id 0x%x, "
4091 "size %" G_GUINT64_FORMAT ", prefix %d", id, length, needed);
4093 /* if we plan to read and parse this element, we need prefix (id + length)
4094 * and the contents */
4095 /* mind about overflow wrap-around when dealing with undefined size */
4097 if (G_LIKELY (length != G_MAXUINT64))
4100 switch (demux->common.state) {
4101 case GST_MATROSKA_READ_STATE_START:
4103 case GST_EBML_ID_HEADER:
4104 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4105 ret = gst_matroska_read_common_parse_header (&demux->common, &ebml);
4106 if (ret != GST_FLOW_OK)
4108 demux->common.state = GST_MATROSKA_READ_STATE_SEGMENT;
4109 gst_matroska_demux_check_seekability (demux);
4112 goto invalid_header;
4116 case GST_MATROSKA_READ_STATE_SEGMENT:
4118 case GST_MATROSKA_ID_SEGMENT:
4119 /* eat segment prefix */
4120 GST_READ_CHECK (gst_matroska_demux_flush (demux, needed));
4121 GST_DEBUG_OBJECT (demux,
4122 "Found Segment start at offset %" G_GUINT64_FORMAT " with size %"
4123 G_GUINT64_FORMAT, demux->common.offset, length);
4124 /* seeks are from the beginning of the segment,
4125 * after the segment ID/length */
4126 demux->common.ebml_segment_start = demux->common.offset;
4128 length = G_MAXUINT64;
4129 demux->common.ebml_segment_length = length;
4130 demux->common.state = GST_MATROSKA_READ_STATE_HEADER;
4133 GST_WARNING_OBJECT (demux,
4134 "Expected a Segment ID (0x%x), but received 0x%x!",
4135 GST_MATROSKA_ID_SEGMENT, id);
4136 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4140 case GST_MATROSKA_READ_STATE_SCANNING:
4141 if (id != GST_MATROSKA_ID_CLUSTER &&
4142 id != GST_MATROSKA_ID_CLUSTERTIMECODE)
4145 case GST_MATROSKA_READ_STATE_HEADER:
4146 case GST_MATROSKA_READ_STATE_DATA:
4147 case GST_MATROSKA_READ_STATE_SEEK:
4149 case GST_MATROSKA_ID_SEGMENTINFO:
4150 if (!demux->common.segmentinfo_parsed) {
4151 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4152 ret = gst_matroska_read_common_parse_info (&demux->common,
4153 GST_ELEMENT_CAST (demux), &ebml);
4155 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4158 case GST_MATROSKA_ID_TRACKS:
4159 if (!demux->tracks_parsed) {
4160 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4161 ret = gst_matroska_demux_parse_tracks (demux, &ebml);
4163 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4166 case GST_MATROSKA_ID_CLUSTER:
4167 if (G_UNLIKELY (!demux->tracks_parsed)) {
4168 if (demux->streaming) {
4169 GST_DEBUG_OBJECT (demux, "Cluster before Track");
4170 goto not_streamable;
4172 ret = gst_matroska_demux_find_tracks (demux);
4173 if (!demux->tracks_parsed)
4177 if (G_UNLIKELY (demux->common.state
4178 == GST_MATROSKA_READ_STATE_HEADER)) {
4179 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
4180 demux->first_cluster_offset = demux->common.offset;
4181 GST_DEBUG_OBJECT (demux, "signaling no more pads");
4182 gst_element_no_more_pads (GST_ELEMENT (demux));
4183 /* send initial segment - we wait till we know the first
4184 incoming timestamp, so we can properly set the start of
4186 demux->need_segment = TRUE;
4188 demux->cluster_time = GST_CLOCK_TIME_NONE;
4189 demux->cluster_offset = demux->common.offset;
4190 if (G_UNLIKELY (!demux->seek_first && demux->seek_block)) {
4191 GST_DEBUG_OBJECT (demux, "seek target block %" G_GUINT64_FORMAT
4192 " not found in Cluster, trying next Cluster's first block instead",
4194 demux->seek_block = 0;
4196 demux->seek_first = FALSE;
4197 /* record next cluster for recovery */
4198 if (read != G_MAXUINT64)
4199 demux->next_cluster_offset = demux->cluster_offset + read;
4200 /* eat cluster prefix */
4201 gst_matroska_demux_flush (demux, needed);
4203 case GST_MATROSKA_ID_CLUSTERTIMECODE:
4207 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4208 if ((ret = gst_ebml_read_uint (&ebml, &id, &num)) != GST_FLOW_OK)
4210 GST_DEBUG_OBJECT (demux, "ClusterTimeCode: %" G_GUINT64_FORMAT, num);
4211 demux->cluster_time = num;
4213 if (demux->common.element_index) {
4214 if (demux->common.element_index_writer_id == -1)
4215 gst_index_get_writer_id (demux->common.element_index,
4216 GST_OBJECT (demux), &demux->common.element_index_writer_id);
4217 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
4218 G_GUINT64_FORMAT " for writer id %d",
4219 GST_TIME_ARGS (demux->cluster_time), demux->cluster_offset,
4220 demux->common.element_index_writer_id);
4221 gst_index_add_association (demux->common.element_index,
4222 demux->common.element_index_writer_id,
4223 GST_ASSOCIATION_FLAG_KEY_UNIT,
4224 GST_FORMAT_TIME, demux->cluster_time,
4225 GST_FORMAT_BYTES, demux->cluster_offset, NULL);
4230 case GST_MATROSKA_ID_BLOCKGROUP:
4231 if (!gst_matroska_demux_seek_block (demux))
4233 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4234 DEBUG_ELEMENT_START (demux, &ebml, "BlockGroup");
4235 if ((ret = gst_ebml_read_master (&ebml, &id)) == GST_FLOW_OK) {
4236 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4237 &ebml, demux->cluster_time, demux->cluster_offset, FALSE);
4239 DEBUG_ELEMENT_STOP (demux, &ebml, "BlockGroup", ret);
4241 case GST_MATROSKA_ID_SIMPLEBLOCK:
4242 if (!gst_matroska_demux_seek_block (demux))
4244 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4245 DEBUG_ELEMENT_START (demux, &ebml, "SimpleBlock");
4246 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4247 &ebml, demux->cluster_time, demux->cluster_offset, TRUE);
4248 DEBUG_ELEMENT_STOP (demux, &ebml, "SimpleBlock", ret);
4250 case GST_MATROSKA_ID_ATTACHMENTS:
4251 if (!demux->common.attachments_parsed) {
4252 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4253 ret = gst_matroska_read_common_parse_attachments (&demux->common,
4254 GST_ELEMENT_CAST (demux), &ebml);
4256 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4259 case GST_MATROSKA_ID_TAGS:
4260 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4261 ret = gst_matroska_read_common_parse_metadata (&demux->common,
4262 GST_ELEMENT_CAST (demux), &ebml);
4264 case GST_MATROSKA_ID_CHAPTERS:
4265 if (!demux->common.chapters_parsed) {
4266 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4268 gst_matroska_read_common_parse_chapters (&demux->common, &ebml);
4270 if (demux->common.toc) {
4271 gst_matroska_demux_send_event (demux,
4272 gst_event_new_toc (demux->common.toc, FALSE));
4275 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4277 case GST_MATROSKA_ID_SEEKHEAD:
4278 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4279 ret = gst_matroska_demux_parse_contents (demux, &ebml);
4281 case GST_MATROSKA_ID_CUES:
4282 if (demux->common.index_parsed) {
4283 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4286 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4287 ret = gst_matroska_read_common_parse_index (&demux->common, &ebml);
4288 /* only push based; delayed index building */
4289 if (ret == GST_FLOW_OK
4290 && demux->common.state == GST_MATROSKA_READ_STATE_SEEK) {
4293 GST_OBJECT_LOCK (demux);
4294 event = demux->seek_event;
4295 demux->seek_event = NULL;
4296 GST_OBJECT_UNLOCK (demux);
4299 /* unlikely to fail, since we managed to seek to this point */
4300 if (!gst_matroska_demux_handle_seek_event (demux, NULL, event))
4302 /* resume data handling, main thread clear to seek again */
4303 GST_OBJECT_LOCK (demux);
4304 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
4305 GST_OBJECT_UNLOCK (demux);
4308 case GST_MATROSKA_ID_POSITION:
4309 case GST_MATROSKA_ID_PREVSIZE:
4310 case GST_MATROSKA_ID_ENCRYPTEDBLOCK:
4311 case GST_MATROSKA_ID_SILENTTRACKS:
4312 GST_DEBUG_OBJECT (demux,
4313 "Skipping Cluster subelement 0x%x - ignoring", id);
4317 GST_DEBUG_OBJECT (demux, "skipping Element 0x%x", id);
4318 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4324 if (ret == GST_FLOW_PARSE)
4328 gst_ebml_read_clear (&ebml);
4334 /* simply exit, maybe not enough data yet */
4335 /* no ebml to clear if read error */
4340 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4341 ("Failed to parse Element 0x%x", id));
4342 ret = GST_FLOW_ERROR;
4347 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4348 ("File layout does not permit streaming"));
4349 ret = GST_FLOW_ERROR;
4354 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4355 ("No Tracks element found"));
4356 ret = GST_FLOW_ERROR;
4361 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Invalid header"));
4362 ret = GST_FLOW_ERROR;
4367 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Failed to seek"));
4368 ret = GST_FLOW_ERROR;
4374 gst_matroska_demux_loop (GstPad * pad)
4376 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (pad));
4382 /* If we have to close a segment, send a new segment to do this now */
4383 if (G_LIKELY (demux->common.state == GST_MATROSKA_READ_STATE_DATA)) {
4384 if (G_UNLIKELY (demux->new_segment)) {
4385 gst_matroska_demux_send_event (demux, demux->new_segment);
4386 demux->new_segment = NULL;
4390 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4391 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4392 if (ret == GST_FLOW_EOS) {
4394 } else if (ret == GST_FLOW_FLUSHING) {
4396 } else if (ret != GST_FLOW_OK) {
4397 ret = gst_matroska_demux_check_parse_error (demux);
4399 /* Only handle EOS as no error if we're outside the segment already */
4400 if (ret == GST_FLOW_EOS && (demux->common.ebml_segment_length != G_MAXUINT64
4401 && demux->common.offset >=
4402 demux->common.ebml_segment_start +
4403 demux->common.ebml_segment_length))
4405 else if (ret != GST_FLOW_OK)
4411 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
4412 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
4415 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4416 if (ret == GST_FLOW_EOS)
4418 if (ret != GST_FLOW_OK)
4421 /* check if we're at the end of a configured segment */
4422 if (G_LIKELY (demux->common.src->len)) {
4425 g_assert (demux->common.num_streams == demux->common.src->len);
4426 for (i = 0; i < demux->common.src->len; i++) {
4427 GstMatroskaTrackContext *context = g_ptr_array_index (demux->common.src,
4429 GST_DEBUG_OBJECT (context->pad, "pos %" GST_TIME_FORMAT,
4430 GST_TIME_ARGS (context->pos));
4431 if (context->eos == FALSE)
4435 GST_INFO_OBJECT (demux, "All streams are EOS");
4441 if (G_UNLIKELY (demux->cached_length == G_MAXUINT64 ||
4442 demux->common.offset >= demux->cached_length)) {
4443 demux->cached_length = gst_matroska_read_common_get_length (&demux->common);
4444 if (demux->common.offset == demux->cached_length) {
4445 GST_LOG_OBJECT (demux, "Reached end of stream");
4456 if (demux->common.segment.rate < 0.0) {
4457 ret = gst_matroska_demux_seek_to_previous_keyframe (demux);
4458 if (ret == GST_FLOW_OK)
4465 const gchar *reason = gst_flow_get_name (ret);
4466 gboolean push_eos = FALSE;
4468 GST_LOG_OBJECT (demux, "pausing task, reason %s", reason);
4469 gst_pad_pause_task (demux->common.sinkpad);
4471 if (ret == GST_FLOW_EOS) {
4472 /* perform EOS logic */
4474 /* If we were in the headers, make sure we send no-more-pads.
4475 This will ensure decodebin2 does not get stuck thinking
4476 the chain is not complete yet, and waiting indefinitely. */
4477 if (G_UNLIKELY (demux->common.state == GST_MATROSKA_READ_STATE_HEADER)) {
4478 if (demux->common.src->len == 0) {
4479 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
4480 ("No pads created"));
4482 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL),
4483 ("Failed to finish reading headers"));
4485 gst_element_no_more_pads (GST_ELEMENT (demux));
4488 if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
4491 /* for segment playback we need to post when (in stream time)
4492 * we stopped, this is either stop (when set) or the duration. */
4493 if ((stop = demux->common.segment.stop) == -1)
4494 stop = demux->last_stop_end;
4496 GST_LOG_OBJECT (demux, "Sending segment done, at end of segment");
4497 gst_element_post_message (GST_ELEMENT (demux),
4498 gst_message_new_segment_done (GST_OBJECT (demux), GST_FORMAT_TIME,
4500 gst_matroska_demux_send_event (demux,
4501 gst_event_new_segment_done (GST_FORMAT_TIME, stop));
4505 } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS) {
4506 /* for fatal errors we post an error message */
4507 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
4508 ("stream stopped, reason %s", reason));
4512 /* send EOS, and prevent hanging if no streams yet */
4513 GST_LOG_OBJECT (demux, "Sending EOS, at end of stream");
4514 if (!gst_matroska_demux_send_event (demux, gst_event_new_eos ()) &&
4515 (ret == GST_FLOW_EOS)) {
4516 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4517 (NULL), ("got eos but no streams (yet)"));
4525 * Create and push a flushing seek event upstream
4528 perform_seek_to_offset (GstMatroskaDemux * demux, gdouble rate, guint64 offset,
4534 GST_DEBUG_OBJECT (demux, "Seeking to %" G_GUINT64_FORMAT, offset);
4537 gst_event_new_seek (rate, GST_FORMAT_BYTES,
4538 GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, GST_SEEK_TYPE_SET, offset,
4539 GST_SEEK_TYPE_NONE, -1);
4540 gst_event_set_seqnum (event, seqnum);
4542 res = gst_pad_push_event (demux->common.sinkpad, event);
4544 /* segment event will update offset */
4548 static GstFlowReturn
4549 gst_matroska_demux_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
4551 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4553 GstFlowReturn ret = GST_FLOW_OK;
4558 if (G_UNLIKELY (GST_BUFFER_IS_DISCONT (buffer))) {
4559 GST_DEBUG_OBJECT (demux, "got DISCONT");
4560 gst_adapter_clear (demux->common.adapter);
4561 GST_OBJECT_LOCK (demux);
4562 gst_matroska_read_common_reset_streams (&demux->common,
4563 GST_CLOCK_TIME_NONE, FALSE);
4564 GST_OBJECT_UNLOCK (demux);
4567 gst_adapter_push (demux->common.adapter, buffer);
4571 available = gst_adapter_available (demux->common.adapter);
4573 ret = gst_matroska_read_common_peek_id_length_push (&demux->common,
4574 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4575 if (G_UNLIKELY (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)) {
4576 if (demux->common.ebml_segment_length != G_MAXUINT64
4577 && demux->common.offset >=
4578 demux->common.ebml_segment_start + demux->common.ebml_segment_length)
4583 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
4584 "size %" G_GUINT64_FORMAT ", needed %d, available %d",
4585 demux->common.offset, id, length, needed, available);
4587 if (needed > available)
4590 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4591 if (ret == GST_FLOW_EOS) {
4592 /* need more data */
4594 } else if (ret != GST_FLOW_OK) {
4601 gst_matroska_demux_handle_sink_event (GstPad * pad, GstObject * parent,
4604 gboolean res = TRUE;
4605 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4607 GST_DEBUG_OBJECT (demux,
4608 "have event type %s: %p on sink pad", GST_EVENT_TYPE_NAME (event), event);
4610 switch (GST_EVENT_TYPE (event)) {
4611 case GST_EVENT_SEGMENT:
4613 const GstSegment *segment;
4615 /* some debug output */
4616 gst_event_parse_segment (event, &segment);
4617 /* FIXME: do we need to update segment base here (like accum in 0.10)? */
4618 GST_DEBUG_OBJECT (demux,
4619 "received format %d segment %" GST_SEGMENT_FORMAT, segment->format,
4622 if (demux->common.state < GST_MATROSKA_READ_STATE_DATA) {
4623 GST_DEBUG_OBJECT (demux, "still starting");
4627 /* we only expect a BYTE segment, e.g. following a seek */
4628 if (segment->format != GST_FORMAT_BYTES) {
4629 GST_DEBUG_OBJECT (demux, "unsupported segment format, ignoring");
4633 GST_DEBUG_OBJECT (demux, "clearing segment state");
4634 GST_OBJECT_LOCK (demux);
4635 /* clear current segment leftover */
4636 gst_adapter_clear (demux->common.adapter);
4637 /* and some streaming setup */
4638 demux->common.offset = segment->start;
4639 /* accumulate base based on current position */
4640 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.position))
4641 demux->common.segment.base +=
4642 (MAX (demux->common.segment.position, demux->stream_start_time)
4643 - demux->stream_start_time) / fabs (demux->common.segment.rate);
4644 /* do not know where we are;
4645 * need to come across a cluster and generate segment */
4646 demux->common.segment.position = GST_CLOCK_TIME_NONE;
4647 demux->cluster_time = GST_CLOCK_TIME_NONE;
4648 demux->cluster_offset = 0;
4649 demux->need_segment = TRUE;
4650 demux->segment_seqnum = gst_event_get_seqnum (event);
4651 /* but keep some of the upstream segment */
4652 demux->common.segment.rate = segment->rate;
4653 /* also check if need to keep some of the requested seek position */
4654 if (demux->seek_offset == segment->start) {
4655 GST_DEBUG_OBJECT (demux, "position matches requested seek");
4656 demux->common.segment.position = demux->requested_seek_time;
4658 GST_DEBUG_OBJECT (demux, "unexpected segment position");
4660 demux->requested_seek_time = GST_CLOCK_TIME_NONE;
4661 demux->seek_offset = -1;
4662 GST_OBJECT_UNLOCK (demux);
4664 /* chain will send initial segment after pads have been added,
4665 * or otherwise come up with one */
4666 GST_DEBUG_OBJECT (demux, "eating event");
4667 gst_event_unref (event);
4673 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
4674 gst_event_unref (event);
4675 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4676 (NULL), ("got eos and didn't receive a complete header object"));
4677 } else if (demux->common.num_streams == 0) {
4678 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4679 (NULL), ("got eos but no streams (yet)"));
4681 gst_matroska_demux_send_event (demux, event);
4685 case GST_EVENT_FLUSH_STOP:
4689 gst_adapter_clear (demux->common.adapter);
4690 GST_OBJECT_LOCK (demux);
4691 gst_matroska_read_common_reset_streams (&demux->common,
4692 GST_CLOCK_TIME_NONE, TRUE);
4693 dur = demux->common.segment.duration;
4694 gst_segment_init (&demux->common.segment, GST_FORMAT_TIME);
4695 demux->common.segment.duration = dur;
4696 demux->cluster_time = GST_CLOCK_TIME_NONE;
4697 demux->cluster_offset = 0;
4698 GST_OBJECT_UNLOCK (demux);
4702 res = gst_pad_event_default (pad, parent, event);
4710 gst_matroska_demux_sink_activate (GstPad * sinkpad, GstObject * parent)
4712 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4714 gboolean pull_mode = FALSE;
4716 query = gst_query_new_scheduling ();
4718 if (gst_pad_peer_query (sinkpad, query))
4719 pull_mode = gst_query_has_scheduling_mode_with_flags (query,
4720 GST_PAD_MODE_PULL, GST_SCHEDULING_FLAG_SEEKABLE);
4722 gst_query_unref (query);
4725 GST_DEBUG ("going to pull mode");
4726 demux->streaming = FALSE;
4727 return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PULL, TRUE);
4729 GST_DEBUG ("going to push (streaming) mode");
4730 demux->streaming = TRUE;
4731 return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PUSH, TRUE);
4736 gst_matroska_demux_sink_activate_mode (GstPad * sinkpad, GstObject * parent,
4737 GstPadMode mode, gboolean active)
4740 case GST_PAD_MODE_PULL:
4742 /* if we have a scheduler we can start the task */
4743 gst_pad_start_task (sinkpad, (GstTaskFunction) gst_matroska_demux_loop,
4746 gst_pad_stop_task (sinkpad);
4749 case GST_PAD_MODE_PUSH:
4757 gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext *
4758 videocontext, const gchar * codec_id, guint8 * data, guint size,
4759 gchar ** codec_name, guint32 * riff_fourcc)
4761 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) videocontext;
4762 GstCaps *caps = NULL;
4764 g_assert (videocontext != NULL);
4765 g_assert (codec_name != NULL);
4770 /* TODO: check if we have all codec types from matroska-ids.h
4771 * check if we have to do more special things with codec_private
4774 * GST_MATROSKA_CODEC_ID_VIDEO_QUICKTIME
4775 * GST_MATROSKA_CODEC_ID_VIDEO_SNOW
4778 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VFW_FOURCC)) {
4779 gst_riff_strf_vids *vids = NULL;
4782 GstBuffer *buf = NULL;
4784 vids = (gst_riff_strf_vids *) data;
4786 /* assure size is big enough */
4788 GST_WARNING ("Too small BITMAPINFOHEADER (%d bytes)", size);
4791 if (size < sizeof (gst_riff_strf_vids)) {
4792 vids = g_new (gst_riff_strf_vids, 1);
4793 memcpy (vids, data, size);
4796 /* little-endian -> byte-order */
4797 vids->size = GUINT32_FROM_LE (vids->size);
4798 vids->width = GUINT32_FROM_LE (vids->width);
4799 vids->height = GUINT32_FROM_LE (vids->height);
4800 vids->planes = GUINT16_FROM_LE (vids->planes);
4801 vids->bit_cnt = GUINT16_FROM_LE (vids->bit_cnt);
4802 vids->compression = GUINT32_FROM_LE (vids->compression);
4803 vids->image_size = GUINT32_FROM_LE (vids->image_size);
4804 vids->xpels_meter = GUINT32_FROM_LE (vids->xpels_meter);
4805 vids->ypels_meter = GUINT32_FROM_LE (vids->ypels_meter);
4806 vids->num_colors = GUINT32_FROM_LE (vids->num_colors);
4807 vids->imp_colors = GUINT32_FROM_LE (vids->imp_colors);
4809 if (size > sizeof (gst_riff_strf_vids)) { /* some extra_data */
4810 gsize offset = sizeof (gst_riff_strf_vids);
4813 gst_buffer_new_wrapped (g_memdup ((guint8 *) vids + offset,
4814 size - offset), size - offset);
4818 *riff_fourcc = vids->compression;
4820 caps = gst_riff_create_video_caps (vids->compression, NULL, vids,
4821 buf, NULL, codec_name);
4824 GST_WARNING ("Unhandled RIFF fourcc %" GST_FOURCC_FORMAT,
4825 GST_FOURCC_ARGS (vids->compression));
4829 gst_buffer_unref (buf);
4831 if (vids != (gst_riff_strf_vids *) data)
4834 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_UNCOMPRESSED)) {
4836 GstVideoFormat format;
4838 gst_video_info_init (&info);
4839 switch (videocontext->fourcc) {
4840 case GST_MAKE_FOURCC ('I', '4', '2', '0'):
4841 format = GST_VIDEO_FORMAT_I420;
4843 case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
4844 format = GST_VIDEO_FORMAT_YUY2;
4846 case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
4847 format = GST_VIDEO_FORMAT_YV12;
4849 case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
4850 format = GST_VIDEO_FORMAT_UYVY;
4852 case GST_MAKE_FOURCC ('A', 'Y', 'U', 'V'):
4853 format = GST_VIDEO_FORMAT_AYUV;
4855 case GST_MAKE_FOURCC ('Y', '8', '0', '0'):
4856 case GST_MAKE_FOURCC ('Y', '8', ' ', ' '):
4857 format = GST_VIDEO_FORMAT_GRAY8;
4859 case GST_MAKE_FOURCC ('R', 'G', 'B', 24):
4860 format = GST_VIDEO_FORMAT_RGB;
4862 case GST_MAKE_FOURCC ('B', 'G', 'R', 24):
4863 format = GST_VIDEO_FORMAT_BGR;
4866 GST_DEBUG ("Unknown fourcc %" GST_FOURCC_FORMAT,
4867 GST_FOURCC_ARGS (videocontext->fourcc));
4871 gst_video_info_set_format (&info, format, videocontext->pixel_width,
4872 videocontext->pixel_height);
4873 caps = gst_video_info_to_caps (&info);
4874 *codec_name = gst_pb_utils_get_codec_description (caps);
4875 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_SP)) {
4876 caps = gst_caps_new_simple ("video/x-divx",
4877 "divxversion", G_TYPE_INT, 4, NULL);
4878 *codec_name = g_strdup ("MPEG-4 simple profile");
4879 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP) ||
4880 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AP)) {
4881 caps = gst_caps_new_simple ("video/mpeg",
4882 "mpegversion", G_TYPE_INT, 4,
4883 "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
4887 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
4888 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
4889 gst_buffer_unref (priv);
4891 gst_codec_utils_mpeg4video_caps_set_level_and_profile (caps, data, size);
4893 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP))
4894 *codec_name = g_strdup ("MPEG-4 advanced simple profile");
4896 *codec_name = g_strdup ("MPEG-4 advanced profile");
4897 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MSMPEG4V3)) {
4899 caps = gst_caps_new_full (gst_structure_new ("video/x-divx",
4900 "divxversion", G_TYPE_INT, 3, NULL),
4901 gst_structure_new ("video/x-msmpeg",
4902 "msmpegversion", G_TYPE_INT, 43, NULL), NULL);
4904 caps = gst_caps_new_simple ("video/x-msmpeg",
4905 "msmpegversion", G_TYPE_INT, 43, NULL);
4906 *codec_name = g_strdup ("Microsoft MPEG-4 v.3");
4907 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1) ||
4908 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG2)) {
4911 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1))
4916 caps = gst_caps_new_simple ("video/mpeg",
4917 "systemstream", G_TYPE_BOOLEAN, FALSE,
4918 "mpegversion", G_TYPE_INT, mpegversion, NULL);
4919 *codec_name = g_strdup_printf ("MPEG-%d video", mpegversion);
4920 context->postprocess_frame = gst_matroska_demux_add_mpeg_seq_header;
4921 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MJPEG)) {
4922 caps = gst_caps_new_empty_simple ("image/jpeg");
4923 *codec_name = g_strdup ("Motion-JPEG");
4924 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AVC)) {
4925 caps = gst_caps_new_empty_simple ("video/x-h264");
4929 /* First byte is the version, second is the profile indication, and third
4930 * is the 5 contraint_set_flags and 3 reserved bits. Fourth byte is the
4931 * level indication. */
4932 gst_codec_utils_h264_caps_set_level_and_profile (caps, data + 1,
4935 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
4936 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
4937 gst_buffer_unref (priv);
4939 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "avc",
4940 "alignment", G_TYPE_STRING, "au", NULL);
4942 GST_WARNING ("No codec data found, assuming output is byte-stream");
4943 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
4946 *codec_name = g_strdup ("H264");
4947 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEGH_HEVC)) {
4948 caps = gst_caps_new_empty_simple ("video/x-h265");
4952 gst_codec_utils_h265_caps_set_level_tier_and_profile (caps, data + 1,
4955 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
4956 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
4957 gst_buffer_unref (priv);
4959 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "hvc1",
4960 "alignment", G_TYPE_STRING, "au", NULL);
4962 GST_WARNING ("No codec data found, assuming output is byte-stream");
4963 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
4966 *codec_name = g_strdup ("HEVC");
4967 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1)) ||
4968 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2)) ||
4969 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3)) ||
4970 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))) {
4971 gint rmversion = -1;
4973 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1))
4975 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2))
4977 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3))
4979 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))
4982 caps = gst_caps_new_simple ("video/x-pn-realvideo",
4983 "rmversion", G_TYPE_INT, rmversion, NULL);
4984 GST_DEBUG ("data:%p, size:0x%x", data, size);
4985 /* We need to extract the extradata ! */
4986 if (data && (size >= 0x22)) {
4991 subformat = GST_READ_UINT32_BE (data + 0x1a);
4992 rformat = GST_READ_UINT32_BE (data + 0x1e);
4995 gst_buffer_new_wrapped (g_memdup (data + 0x1a, size - 0x1a),
4997 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, "format",
4998 G_TYPE_INT, rformat, "subformat", G_TYPE_INT, subformat, NULL);
4999 gst_buffer_unref (priv);
5002 *codec_name = g_strdup_printf ("RealVideo %d.0", rmversion);
5003 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_THEORA)) {
5004 caps = gst_caps_new_empty_simple ("video/x-theora");
5005 context->stream_headers =
5006 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
5007 context->codec_priv_size);
5008 /* FIXME: mark stream as broken and skip if there are no stream headers */
5009 context->send_stream_headers = TRUE;
5010 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_DIRAC)) {
5011 caps = gst_caps_new_empty_simple ("video/x-dirac");
5012 *codec_name = g_strdup_printf ("Dirac");
5013 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8)) {
5014 caps = gst_caps_new_empty_simple ("video/x-vp8");
5015 *codec_name = g_strdup_printf ("On2 VP8");
5016 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP9)) {
5017 caps = gst_caps_new_empty_simple ("video/x-vp9");
5018 *codec_name = g_strdup_printf ("On2 VP9");
5020 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
5026 GstStructure *structure;
5028 for (i = 0; i < gst_caps_get_size (caps); i++) {
5029 structure = gst_caps_get_structure (caps, i);
5031 /* FIXME: use the real unit here! */
5032 GST_DEBUG ("video size %dx%d, target display size %dx%d (any unit)",
5033 videocontext->pixel_width,
5034 videocontext->pixel_height,
5035 videocontext->display_width, videocontext->display_height);
5037 /* pixel width and height are the w and h of the video in pixels */
5038 if (videocontext->pixel_width > 0 && videocontext->pixel_height > 0) {
5039 gint w = videocontext->pixel_width;
5040 gint h = videocontext->pixel_height;
5042 gst_structure_set (structure,
5043 "width", G_TYPE_INT, w, "height", G_TYPE_INT, h, NULL);
5046 if (videocontext->display_width > 0 || videocontext->display_height > 0) {
5049 if (videocontext->display_width <= 0)
5050 videocontext->display_width = videocontext->pixel_width;
5051 if (videocontext->display_height <= 0)
5052 videocontext->display_height = videocontext->pixel_height;
5054 /* calculate the pixel aspect ratio using the display and pixel w/h */
5055 n = videocontext->display_width * videocontext->pixel_height;
5056 d = videocontext->display_height * videocontext->pixel_width;
5057 GST_DEBUG ("setting PAR to %d/%d", n, d);
5058 gst_structure_set (structure, "pixel-aspect-ratio",
5060 videocontext->display_width * videocontext->pixel_height,
5061 videocontext->display_height * videocontext->pixel_width, NULL);
5064 if (videocontext->default_fps > 0.0) {
5067 gst_util_double_to_fraction (videocontext->default_fps, &fps_n, &fps_d);
5069 GST_DEBUG ("using default fps %d/%d", fps_n, fps_d);
5071 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION, fps_n,
5073 } else if (context->default_duration > 0) {
5076 gst_video_guess_framerate (context->default_duration, &fps_n, &fps_d);
5078 GST_INFO ("using default duration %" G_GUINT64_FORMAT
5079 " framerate %d/%d", context->default_duration, fps_n, fps_d);
5081 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
5082 fps_n, fps_d, NULL);
5084 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
5088 if (videocontext->parent.flags & GST_MATROSKA_VIDEOTRACK_INTERLACED)
5089 gst_structure_set (structure, "interlace-mode", G_TYPE_STRING,
5093 caps = gst_caps_simplify (caps);
5100 * Some AAC specific code... *sigh*
5101 * FIXME: maybe we should use '15' and code the sample rate explicitly
5102 * if the sample rate doesn't match the predefined rates exactly? (tpm)
5106 aac_rate_idx (gint rate)
5110 else if (75132 <= rate)
5112 else if (55426 <= rate)
5114 else if (46009 <= rate)
5116 else if (37566 <= rate)
5118 else if (27713 <= rate)
5120 else if (23004 <= rate)
5122 else if (18783 <= rate)
5124 else if (13856 <= rate)
5126 else if (11502 <= rate)
5128 else if (9391 <= rate)
5135 aac_profile_idx (const gchar * codec_id)
5139 if (strlen (codec_id) <= 12)
5141 else if (!strncmp (&codec_id[12], "MAIN", 4))
5143 else if (!strncmp (&codec_id[12], "LC", 2))
5145 else if (!strncmp (&codec_id[12], "SSR", 3))
5154 round_up_pow2 (guint n)
5165 #define AAC_SYNC_EXTENSION_TYPE 0x02b7
5168 gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext *
5169 audiocontext, const gchar * codec_id, guint8 * data, guint size,
5170 gchar ** codec_name, guint16 * riff_audio_fmt)
5172 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) audiocontext;
5173 GstCaps *caps = NULL;
5175 g_assert (audiocontext != NULL);
5176 g_assert (codec_name != NULL);
5179 *riff_audio_fmt = 0;
5181 /* TODO: check if we have all codec types from matroska-ids.h
5182 * check if we have to do more special things with codec_private
5183 * check if we need bitdepth in different places too
5184 * implement channel position magic
5186 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID9
5187 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID10
5188 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDMC
5189 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDM2
5192 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1) ||
5193 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2) ||
5194 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L3)) {
5197 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1))
5199 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2))
5204 caps = gst_caps_new_simple ("audio/mpeg",
5205 "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, layer, NULL);
5206 *codec_name = g_strdup_printf ("MPEG-1 layer %d", layer);
5207 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE) ||
5208 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_LE)) {
5211 GstAudioFormat format;
5213 sign = (audiocontext->bitdepth != 8);
5214 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE))
5215 endianness = G_BIG_ENDIAN;
5217 endianness = G_LITTLE_ENDIAN;
5219 format = gst_audio_format_build_integer (sign, endianness,
5220 audiocontext->bitdepth, audiocontext->bitdepth);
5222 /* FIXME: Channel mask and reordering */
5223 caps = gst_caps_new_simple ("audio/x-raw",
5224 "format", G_TYPE_STRING, gst_audio_format_to_string (format),
5225 "layout", G_TYPE_STRING, "interleaved", NULL);
5227 *codec_name = g_strdup_printf ("Raw %d-bit PCM audio",
5228 audiocontext->bitdepth);
5229 context->alignment = GST_ROUND_UP_8 (audiocontext->bitdepth) / 8;
5230 context->alignment = round_up_pow2 (context->alignment);
5231 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_FLOAT)) {
5232 const gchar *format;
5233 if (audiocontext->bitdepth == 32)
5237 /* FIXME: Channel mask and reordering */
5238 caps = gst_caps_new_simple ("audio/x-raw",
5239 "format", G_TYPE_STRING, format,
5240 "layout", G_TYPE_STRING, "interleaved", NULL);
5241 *codec_name = g_strdup_printf ("Raw %d-bit floating-point audio",
5242 audiocontext->bitdepth);
5243 context->alignment = audiocontext->bitdepth / 8;
5244 context->alignment = round_up_pow2 (context->alignment);
5245 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AC3,
5246 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AC3))) {
5247 caps = gst_caps_new_simple ("audio/x-ac3",
5248 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5249 *codec_name = g_strdup ("AC-3 audio");
5250 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_EAC3,
5251 strlen (GST_MATROSKA_CODEC_ID_AUDIO_EAC3))) {
5252 caps = gst_caps_new_simple ("audio/x-eac3",
5253 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5254 *codec_name = g_strdup ("E-AC-3 audio");
5255 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TRUEHD,
5256 strlen (GST_MATROSKA_CODEC_ID_AUDIO_TRUEHD))) {
5257 caps = gst_caps_new_empty_simple ("audio/x-true-hd");
5258 *codec_name = g_strdup ("Dolby TrueHD");
5259 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_DTS)) {
5260 caps = gst_caps_new_empty_simple ("audio/x-dts");
5261 *codec_name = g_strdup ("DTS audio");
5262 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_VORBIS)) {
5263 caps = gst_caps_new_empty_simple ("audio/x-vorbis");
5264 context->stream_headers =
5265 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
5266 context->codec_priv_size);
5267 /* FIXME: mark stream as broken and skip if there are no stream headers */
5268 context->send_stream_headers = TRUE;
5269 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_FLAC)) {
5270 caps = gst_caps_new_empty_simple ("audio/x-flac");
5271 context->stream_headers =
5272 gst_matroska_parse_flac_stream_headers (context->codec_priv,
5273 context->codec_priv_size);
5274 /* FIXME: mark stream as broken and skip if there are no stream headers */
5275 context->send_stream_headers = TRUE;
5276 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_SPEEX)) {
5277 caps = gst_caps_new_empty_simple ("audio/x-speex");
5278 context->stream_headers =
5279 gst_matroska_parse_speex_stream_headers (context->codec_priv,
5280 context->codec_priv_size);
5281 /* FIXME: mark stream as broken and skip if there are no stream headers */
5282 context->send_stream_headers = TRUE;
5283 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_OPUS)) {
5284 caps = gst_caps_new_empty_simple ("audio/x-opus");
5285 *codec_name = g_strdup ("Opus");
5286 context->stream_headers =
5287 gst_matroska_parse_opus_stream_headers (context->codec_priv,
5288 context->codec_priv_size);
5289 if (context->stream_headers) {
5290 /* There was a valid header. Multistream headers are more than
5291 * 19 bytes, as they include an extra channel mapping table. */
5292 gboolean multistream = (context->codec_priv_size > 19);
5293 gst_caps_set_simple (caps, "multistream", G_TYPE_BOOLEAN, multistream,
5296 /* FIXME: mark stream as broken and skip if there are no stream headers */
5297 context->send_stream_headers = TRUE;
5298 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_ACM)) {
5299 gst_riff_strf_auds auds;
5301 if (data && size >= 18) {
5302 GstBuffer *codec_data = NULL;
5304 /* little-endian -> byte-order */
5305 auds.format = GST_READ_UINT16_LE (data);
5306 auds.channels = GST_READ_UINT16_LE (data + 2);
5307 auds.rate = GST_READ_UINT32_LE (data + 4);
5308 auds.av_bps = GST_READ_UINT32_LE (data + 8);
5309 auds.blockalign = GST_READ_UINT16_LE (data + 12);
5310 auds.bits_per_sample = GST_READ_UINT16_LE (data + 16);
5312 /* 18 is the waveformatex size */
5314 codec_data = gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY,
5315 data + 18, size - 18, 0, size - 18, NULL, NULL);
5319 *riff_audio_fmt = auds.format;
5321 /* FIXME: Handle reorder map */
5322 caps = gst_riff_create_audio_caps (auds.format, NULL, &auds, NULL,
5323 codec_data, codec_name, NULL);
5325 gst_buffer_unref (codec_data);
5328 GST_WARNING ("Unhandled RIFF audio format 0x%02x", auds.format);
5331 GST_WARNING ("Invalid codec data size (%d expected, got %d)", 18, size);
5333 } else if (g_str_has_prefix (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC)) {
5334 GstBuffer *priv = NULL;
5336 gint rate_idx, profile;
5337 guint8 *data = NULL;
5339 /* unspecified AAC profile with opaque private codec data */
5340 if (strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC) == 0) {
5341 if (context->codec_priv_size >= 2) {
5342 guint obj_type, freq_index, explicit_freq_bytes = 0;
5344 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
5346 freq_index = (GST_READ_UINT16_BE (context->codec_priv) & 0x780) >> 7;
5347 obj_type = (GST_READ_UINT16_BE (context->codec_priv) & 0xF800) >> 11;
5348 if (freq_index == 15)
5349 explicit_freq_bytes = 3;
5350 GST_DEBUG ("obj_type = %u, freq_index = %u", obj_type, freq_index);
5351 priv = gst_buffer_new_wrapped (g_memdup (context->codec_priv,
5352 context->codec_priv_size), context->codec_priv_size);
5353 /* assume SBR if samplerate <= 24kHz */
5354 if (obj_type == 5 || (freq_index >= 6 && freq_index != 15) ||
5355 (context->codec_priv_size == (5 + explicit_freq_bytes))) {
5356 audiocontext->samplerate *= 2;
5359 GST_WARNING ("Opaque A_AAC codec ID, but no codec private data");
5360 /* this is pretty broken;
5361 * maybe we need to make up some default private,
5362 * or maybe ADTS data got dumped in.
5363 * Let's set up some private data now, and check actual data later */
5364 /* just try this and see what happens ... */
5365 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
5366 context->postprocess_frame = gst_matroska_demux_check_aac;
5370 /* make up decoder-specific data if it is not supplied */
5374 priv = gst_buffer_new_allocate (NULL, 5, NULL);
5375 gst_buffer_map (priv, &map, GST_MAP_WRITE);
5377 rate_idx = aac_rate_idx (audiocontext->samplerate);
5378 profile = aac_profile_idx (codec_id);
5380 data[0] = ((profile + 1) << 3) | ((rate_idx & 0xE) >> 1);
5381 data[1] = ((rate_idx & 0x1) << 7) | (audiocontext->channels << 3);
5383 if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2,
5384 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2))) {
5386 gst_buffer_unmap (priv, &map);
5387 gst_buffer_set_size (priv, 2);
5388 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4,
5389 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4))) {
5392 if (g_strrstr (codec_id, "SBR")) {
5393 /* HE-AAC (aka SBR AAC) */
5394 audiocontext->samplerate *= 2;
5395 rate_idx = aac_rate_idx (audiocontext->samplerate);
5396 data[2] = AAC_SYNC_EXTENSION_TYPE >> 3;
5397 data[3] = ((AAC_SYNC_EXTENSION_TYPE & 0x07) << 5) | 5;
5398 data[4] = (1 << 7) | (rate_idx << 3);
5399 gst_buffer_unmap (priv, &map);
5401 gst_buffer_unmap (priv, &map);
5402 gst_buffer_set_size (priv, 2);
5405 gst_buffer_unmap (priv, &map);
5406 gst_buffer_unref (priv);
5408 GST_ERROR ("Unknown AAC profile and no codec private data");
5413 caps = gst_caps_new_simple ("audio/mpeg",
5414 "mpegversion", G_TYPE_INT, mpegversion,
5415 "framed", G_TYPE_BOOLEAN, TRUE,
5416 "stream-format", G_TYPE_STRING, "raw", NULL);
5417 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5418 if (context->codec_priv && context->codec_priv_size > 0)
5419 gst_codec_utils_aac_caps_set_level_and_profile (caps,
5420 context->codec_priv, context->codec_priv_size);
5421 *codec_name = g_strdup_printf ("MPEG-%d AAC audio", mpegversion);
5422 gst_buffer_unref (priv);
5424 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TTA)) {
5425 caps = gst_caps_new_simple ("audio/x-tta",
5426 "width", G_TYPE_INT, audiocontext->bitdepth, NULL);
5427 *codec_name = g_strdup ("TTA audio");
5428 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_WAVPACK4)) {
5429 caps = gst_caps_new_simple ("audio/x-wavpack",
5430 "width", G_TYPE_INT, audiocontext->bitdepth,
5431 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5432 *codec_name = g_strdup ("Wavpack audio");
5433 context->postprocess_frame = gst_matroska_demux_add_wvpk_header;
5434 audiocontext->wvpk_block_index = 0;
5435 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4)) ||
5436 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_28_8)) ||
5437 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))) {
5438 gint raversion = -1;
5440 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4))
5442 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))
5447 caps = gst_caps_new_simple ("audio/x-pn-realaudio",
5448 "raversion", G_TYPE_INT, raversion, NULL);
5449 /* Extract extra information from caps, mapping varies based on codec */
5450 if (data && (size >= 0x50)) {
5457 guint extra_data_size;
5459 GST_ERROR ("real audio raversion:%d", raversion);
5460 if (raversion == 8) {
5462 flavor = GST_READ_UINT16_BE (data + 22);
5463 packet_size = GST_READ_UINT32_BE (data + 24);
5464 height = GST_READ_UINT16_BE (data + 40);
5465 leaf_size = GST_READ_UINT16_BE (data + 44);
5466 sample_width = GST_READ_UINT16_BE (data + 58);
5467 extra_data_size = GST_READ_UINT32_BE (data + 74);
5470 ("flavor:%d, packet_size:%d, height:%d, leaf_size:%d, sample_width:%d, extra_data_size:%d",
5471 flavor, packet_size, height, leaf_size, sample_width,
5473 gst_caps_set_simple (caps, "flavor", G_TYPE_INT, flavor, "packet_size",
5474 G_TYPE_INT, packet_size, "height", G_TYPE_INT, height, "leaf_size",
5475 G_TYPE_INT, leaf_size, "width", G_TYPE_INT, sample_width, NULL);
5477 if ((size - 78) >= extra_data_size) {
5478 priv = gst_buffer_new_wrapped (g_memdup (data + 78, extra_data_size),
5480 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5481 gst_buffer_unref (priv);
5486 *codec_name = g_strdup_printf ("RealAudio %d.0", raversion);
5487 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_SIPR)) {
5488 caps = gst_caps_new_empty_simple ("audio/x-sipro");
5489 *codec_name = g_strdup ("Sipro/ACELP.NET Voice Codec");
5490 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_RALF)) {
5491 caps = gst_caps_new_empty_simple ("audio/x-ralf-mpeg4-generic");
5492 *codec_name = g_strdup ("Real Audio Lossless");
5493 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_ATRC)) {
5494 caps = gst_caps_new_empty_simple ("audio/x-vnd.sony.atrac3");
5495 *codec_name = g_strdup ("Sony ATRAC3");
5497 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
5502 if (audiocontext->samplerate > 0 && audiocontext->channels > 0) {
5505 for (i = 0; i < gst_caps_get_size (caps); i++) {
5506 gst_structure_set (gst_caps_get_structure (caps, i),
5507 "channels", G_TYPE_INT, audiocontext->channels,
5508 "rate", G_TYPE_INT, audiocontext->samplerate, NULL);
5512 caps = gst_caps_simplify (caps);
5519 gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
5520 subtitlecontext, const gchar * codec_id, gpointer data, guint size)
5522 GstCaps *caps = NULL;
5523 GstMatroskaTrackContext *context =
5524 (GstMatroskaTrackContext *) subtitlecontext;
5526 /* for backwards compatibility */
5527 if (!g_ascii_strcasecmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASCII))
5528 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8;
5529 else if (!g_ascii_strcasecmp (codec_id, "S_SSA"))
5530 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_SSA;
5531 else if (!g_ascii_strcasecmp (codec_id, "S_ASS"))
5532 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_ASS;
5533 else if (!g_ascii_strcasecmp (codec_id, "S_USF"))
5534 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_USF;
5536 /* TODO: Add GST_MATROSKA_CODEC_ID_SUBTITLE_BMP support
5537 * Check if we have to do something with codec_private */
5538 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8)) {
5539 /* well, plain text simply does not have a lot of markup ... */
5540 caps = gst_caps_new_simple ("text/x-raw", "format", G_TYPE_STRING,
5541 "pango-markup", NULL);
5542 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5543 subtitlecontext->check_markup = TRUE;
5544 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_SSA)) {
5545 caps = gst_caps_new_empty_simple ("application/x-ssa");
5546 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5547 subtitlecontext->check_markup = FALSE;
5548 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASS)) {
5549 caps = gst_caps_new_empty_simple ("application/x-ass");
5550 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5551 subtitlecontext->check_markup = FALSE;
5552 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_USF)) {
5553 caps = gst_caps_new_empty_simple ("application/x-usf");
5554 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5555 subtitlecontext->check_markup = FALSE;
5556 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB)) {
5557 caps = gst_caps_new_empty_simple ("subpicture/x-dvd");
5558 ((GstMatroskaTrackContext *) subtitlecontext)->send_dvd_event = TRUE;
5559 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_HDMVPGS)) {
5560 caps = gst_caps_new_empty_simple ("subpicture/x-pgs");
5561 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_KATE)) {
5562 caps = gst_caps_new_empty_simple ("subtitle/x-kate");
5563 context->stream_headers =
5564 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
5565 context->codec_priv_size);
5566 /* FIXME: mark stream as broken and skip if there are no stream headers */
5567 context->send_stream_headers = TRUE;
5569 GST_DEBUG ("Unknown subtitle stream: codec_id='%s'", codec_id);
5570 caps = gst_caps_new_empty_simple ("application/x-subtitle-unknown");
5573 if (data != NULL && size > 0) {
5576 buf = gst_buffer_new_wrapped (g_memdup (data, size), size);
5577 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, buf, NULL);
5578 gst_buffer_unref (buf);
5586 gst_matroska_demux_set_index (GstElement * element, GstIndex * index)
5588 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5590 GST_OBJECT_LOCK (demux);
5591 if (demux->common.element_index)
5592 gst_object_unref (demux->common.element_index);
5593 demux->common.element_index = index ? gst_object_ref (index) : NULL;
5594 GST_OBJECT_UNLOCK (demux);
5595 GST_DEBUG_OBJECT (demux, "Set index %" GST_PTR_FORMAT,
5596 demux->common.element_index);
5600 gst_matroska_demux_get_index (GstElement * element)
5602 GstIndex *result = NULL;
5603 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5605 GST_OBJECT_LOCK (demux);
5606 if (demux->common.element_index)
5607 result = gst_object_ref (demux->common.element_index);
5608 GST_OBJECT_UNLOCK (demux);
5610 GST_DEBUG_OBJECT (demux, "Returning index %" GST_PTR_FORMAT, result);
5616 static GstStateChangeReturn
5617 gst_matroska_demux_change_state (GstElement * element,
5618 GstStateChange transition)
5620 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5621 GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
5623 /* handle upwards state changes here */
5624 switch (transition) {
5629 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
5631 /* handle downwards state changes */
5632 switch (transition) {
5633 case GST_STATE_CHANGE_PAUSED_TO_READY:
5634 gst_matroska_demux_reset (GST_ELEMENT (demux));
5644 gst_matroska_demux_set_property (GObject * object,
5645 guint prop_id, const GValue * value, GParamSpec * pspec)
5647 GstMatroskaDemux *demux;
5649 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
5650 demux = GST_MATROSKA_DEMUX (object);
5653 case ARG_MAX_GAP_TIME:
5654 GST_OBJECT_LOCK (demux);
5655 demux->max_gap_time = g_value_get_uint64 (value);
5656 GST_OBJECT_UNLOCK (demux);
5659 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
5665 gst_matroska_demux_get_property (GObject * object,
5666 guint prop_id, GValue * value, GParamSpec * pspec)
5668 GstMatroskaDemux *demux;
5670 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
5671 demux = GST_MATROSKA_DEMUX (object);
5674 case ARG_MAX_GAP_TIME:
5675 GST_OBJECT_LOCK (demux);
5676 g_value_set_uint64 (value, demux->max_gap_time);
5677 GST_OBJECT_UNLOCK (demux);
5680 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
5686 gst_matroska_demux_plugin_init (GstPlugin * plugin)
5690 /* parser helper separate debug */
5691 GST_DEBUG_CATEGORY_INIT (ebmlread_debug, "ebmlread",
5692 0, "EBML stream helper class");
5694 /* create an elementfactory for the matroska_demux element */
5695 if (!gst_element_register (plugin, "matroskademux",
5696 GST_RANK_PRIMARY, GST_TYPE_MATROSKA_DEMUX))