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 if (newpos == demux->common.offset) {
1614 GST_ERROR_OBJECT (demux, "Stuck at the same offset");
1615 ret = GST_FLOW_ERROR;
1618 demux->common.offset = newpos;
1619 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1620 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1621 if (ret != GST_FLOW_OK) {
1622 GST_DEBUG_OBJECT (demux, "need more data -> continue");
1625 g_assert (id == GST_MATROSKA_ID_CLUSTER);
1626 GST_DEBUG_OBJECT (demux, "cluster size %" G_GUINT64_FORMAT ", prefix %d",
1628 /* ok if undefined length or first cluster */
1629 if (length == GST_EBML_SIZE_UNKNOWN || length == G_MAXUINT64) {
1630 GST_DEBUG_OBJECT (demux, "cluster has undefined length -> OK");
1634 demux->common.offset += length + needed;
1635 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1636 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1637 if (ret != GST_FLOW_OK)
1639 GST_DEBUG_OBJECT (demux, "next element is %scluster",
1640 id == GST_MATROSKA_ID_CLUSTER ? "" : "not ");
1641 if (id == GST_MATROSKA_ID_CLUSTER)
1643 /* not ok, resume */
1646 /* partial cluster id may have been in tail of buffer */
1647 newpos += MAX (gst_byte_reader_get_remaining (&reader), 4) - 3;
1652 gst_buffer_unmap (buf, &map);
1653 gst_buffer_unref (buf);
1658 demux->common.offset = orig_offset;
1663 /* bisect and scan through file for cluster starting before @time,
1664 * returns fake index entry with corresponding info on cluster */
1665 static GstMatroskaIndex *
1666 gst_matroska_demux_search_pos (GstMatroskaDemux * demux, GstClockTime time)
1668 GstMatroskaIndex *entry = NULL;
1669 GstMatroskaReadState current_state;
1670 GstClockTime otime, prev_cluster_time, current_cluster_time, cluster_time;
1671 gint64 opos, newpos, startpos = 0, current_offset;
1672 gint64 prev_cluster_offset = -1, current_cluster_offset, cluster_offset;
1673 const guint chunk = 64 * 1024;
1679 /* (under)estimate new position, resync using cluster ebml id,
1680 * and scan forward to appropriate cluster
1681 * (and re-estimate if need to go backward) */
1683 prev_cluster_time = GST_CLOCK_TIME_NONE;
1685 /* store some current state */
1686 current_state = demux->common.state;
1687 g_return_val_if_fail (current_state == GST_MATROSKA_READ_STATE_DATA, NULL);
1689 current_cluster_offset = demux->cluster_offset;
1690 current_cluster_time = demux->cluster_time;
1691 current_offset = demux->common.offset;
1693 demux->common.state = GST_MATROSKA_READ_STATE_SCANNING;
1695 /* estimate using start and current position */
1696 GST_OBJECT_LOCK (demux);
1697 opos = demux->common.offset - demux->common.ebml_segment_start;
1698 otime = demux->common.segment.position;
1699 GST_OBJECT_UNLOCK (demux);
1702 time = MAX (time, demux->stream_start_time);
1704 /* avoid division by zero in first estimation below */
1705 if (otime <= demux->stream_start_time)
1709 GST_LOG_OBJECT (demux,
1710 "opos: %" G_GUINT64_FORMAT ", otime: %" GST_TIME_FORMAT ", %"
1711 GST_TIME_FORMAT " in stream time (start %" GST_TIME_FORMAT "), time %"
1712 GST_TIME_FORMAT, opos, GST_TIME_ARGS (otime),
1713 GST_TIME_ARGS (otime - demux->stream_start_time),
1714 GST_TIME_ARGS (demux->stream_start_time), GST_TIME_ARGS (time));
1716 if (otime <= demux->stream_start_time) {
1720 gst_util_uint64_scale (opos - demux->common.ebml_segment_start,
1721 time - demux->stream_start_time,
1722 otime - demux->stream_start_time) - chunk;
1726 /* favour undershoot */
1727 newpos = newpos * 90 / 100;
1728 newpos += demux->common.ebml_segment_start;
1730 GST_DEBUG_OBJECT (demux,
1731 "estimated offset for %" GST_TIME_FORMAT ": %" G_GINT64_FORMAT,
1732 GST_TIME_ARGS (time), newpos);
1734 /* and at least start scanning before previous scan start to avoid looping */
1735 startpos = startpos * 90 / 100;
1736 if (startpos && startpos < newpos)
1739 /* read in at newpos and scan for ebml cluster id */
1743 ret = gst_matroska_demux_search_cluster (demux, &newpos);
1744 if (ret == GST_FLOW_EOS) {
1745 /* heuristic HACK */
1746 newpos = startpos * 80 / 100;
1747 GST_DEBUG_OBJECT (demux, "EOS; "
1748 "new estimated offset for %" GST_TIME_FORMAT ": %" G_GINT64_FORMAT,
1749 GST_TIME_ARGS (time), newpos);
1752 } else if (ret != GST_FLOW_OK) {
1759 /* then start scanning and parsing for cluster time,
1760 * re-estimate if overshoot, otherwise next cluster and so on */
1761 demux->common.offset = newpos;
1762 demux->cluster_time = cluster_time = GST_CLOCK_TIME_NONE;
1764 guint64 cluster_size = 0;
1766 /* peek and parse some elements */
1767 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1768 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1769 if (ret != GST_FLOW_OK)
1771 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
1772 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
1774 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
1775 if (ret != GST_FLOW_OK)
1778 if (id == GST_MATROSKA_ID_CLUSTER) {
1779 cluster_time = GST_CLOCK_TIME_NONE;
1780 if (length == G_MAXUINT64)
1783 cluster_size = length + needed;
1785 if (demux->cluster_time != GST_CLOCK_TIME_NONE &&
1786 cluster_time == GST_CLOCK_TIME_NONE) {
1787 cluster_time = demux->cluster_time * demux->common.time_scale;
1788 cluster_offset = demux->cluster_offset;
1789 GST_DEBUG_OBJECT (demux, "found cluster at offset %" G_GINT64_FORMAT
1790 " with time %" GST_TIME_FORMAT, cluster_offset,
1791 GST_TIME_ARGS (cluster_time));
1792 if (cluster_time > time) {
1793 GST_DEBUG_OBJECT (demux, "overshot target");
1794 /* cluster overshoots */
1795 if (cluster_offset == demux->first_cluster_offset) {
1796 /* but no prev one */
1797 GST_DEBUG_OBJECT (demux, "but using first cluster anyway");
1798 prev_cluster_time = cluster_time;
1799 prev_cluster_offset = cluster_offset;
1802 if (prev_cluster_time != GST_CLOCK_TIME_NONE) {
1803 /* prev cluster did not overshoot, so prev cluster is target */
1806 /* re-estimate using this new position info */
1807 opos = cluster_offset;
1808 otime = cluster_time;
1812 /* cluster undershoots, goto next one */
1813 prev_cluster_time = cluster_time;
1814 prev_cluster_offset = cluster_offset;
1815 /* skip cluster if length is defined,
1816 * otherwise will be skippingly parsed into */
1818 GST_DEBUG_OBJECT (demux, "skipping to next cluster");
1819 demux->common.offset = cluster_offset + cluster_size;
1820 demux->cluster_time = GST_CLOCK_TIME_NONE;
1822 GST_DEBUG_OBJECT (demux, "parsing/skipping cluster elements");
1829 if (ret == GST_FLOW_EOS) {
1830 if (prev_cluster_time != GST_CLOCK_TIME_NONE)
1836 entry = g_new0 (GstMatroskaIndex, 1);
1837 entry->time = prev_cluster_time;
1838 entry->pos = prev_cluster_offset - demux->common.ebml_segment_start;
1839 GST_DEBUG_OBJECT (demux, "simulated index entry; time %" GST_TIME_FORMAT
1840 ", pos %" G_GUINT64_FORMAT, GST_TIME_ARGS (entry->time), entry->pos);
1844 /* restore some state */
1845 demux->cluster_offset = current_cluster_offset;
1846 demux->cluster_time = current_cluster_time;
1847 demux->common.offset = current_offset;
1848 demux->common.state = current_state;
1854 gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
1855 GstPad * pad, GstEvent * event)
1857 GstMatroskaIndex *entry = NULL;
1858 GstMatroskaIndex scan_entry;
1860 GstSeekType cur_type, stop_type;
1862 gboolean flush, keyunit, before, after, snap_next;
1865 GstMatroskaTrackContext *track = NULL;
1866 GstSegment seeksegment = { 0, };
1867 gboolean update = TRUE;
1868 gboolean pad_locked = FALSE;
1872 track = gst_pad_get_element_private (pad);
1874 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
1876 seqnum = gst_event_get_seqnum (event);
1878 /* we can only seek on time */
1879 if (format != GST_FORMAT_TIME) {
1880 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
1884 /* copy segment, we need this because we still need the old
1885 * segment when we close the current segment. */
1886 memcpy (&seeksegment, &demux->common.segment, sizeof (GstSegment));
1888 /* pull mode without index means that the actual duration is not known,
1889 * we might be playing a file that's still being recorded
1890 * so, invalidate our current duration, which is only a moving target,
1891 * and should not be used to clamp anything */
1892 if (!demux->streaming && !demux->common.index && demux->invalid_duration) {
1893 seeksegment.duration = GST_CLOCK_TIME_NONE;
1897 GST_DEBUG_OBJECT (demux, "configuring seek");
1898 gst_segment_do_seek (&seeksegment, rate, format, flags,
1899 cur_type, cur, stop_type, stop, &update);
1900 /* compensate for clip start time, but only for SET seeks,
1901 * otherwise it is already part of the segments */
1902 if (GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
1903 if (cur_type == GST_SEEK_TYPE_SET) {
1905 seeksegment.position += demux->stream_start_time;
1906 seeksegment.start += demux->stream_start_time;
1908 if (stop_type == GST_SEEK_TYPE_SET
1909 && GST_CLOCK_TIME_IS_VALID (seeksegment.stop)) {
1911 seeksegment.position += demux->stream_start_time;
1912 seeksegment.stop += demux->stream_start_time;
1917 /* restore segment duration (if any effect),
1918 * would be determined again when parsing, but anyway ... */
1919 seeksegment.duration = demux->common.segment.duration;
1921 flush = ! !(flags & GST_SEEK_FLAG_FLUSH);
1922 keyunit = ! !(flags & GST_SEEK_FLAG_KEY_UNIT);
1923 after = ! !(flags & GST_SEEK_FLAG_SNAP_AFTER);
1924 before = ! !(flags & GST_SEEK_FLAG_SNAP_BEFORE);
1926 /* always do full update if flushing,
1927 * otherwise problems might arise downstream with missing keyframes etc */
1928 update = update || flush;
1930 GST_DEBUG_OBJECT (demux, "New segment %" GST_SEGMENT_FORMAT, &seeksegment);
1932 /* check sanity before we start flushing and all that */
1933 snap_next = after && !before;
1934 if (seeksegment.rate < 0)
1935 snap_next = !snap_next;
1936 GST_OBJECT_LOCK (demux);
1937 track = gst_matroska_read_common_get_seek_track (&demux->common, track);
1938 if ((entry = gst_matroska_read_common_do_index_seek (&demux->common, track,
1939 seeksegment.position, &demux->seek_index, &demux->seek_entry,
1940 snap_next)) == NULL) {
1941 /* pull mode without index can scan later on */
1942 if (demux->streaming) {
1943 GST_DEBUG_OBJECT (demux, "No matching seek entry in index");
1944 GST_OBJECT_UNLOCK (demux);
1946 } else if (rate < 0.0) {
1947 /* FIXME: We should build an index during playback or when scanning
1948 * that can be used here. The reverse playback code requires seek_index
1949 * and seek_entry to be set!
1951 GST_DEBUG_OBJECT (demux,
1952 "No matching seek entry in index, needed for reverse playback");
1953 GST_OBJECT_UNLOCK (demux);
1957 GST_DEBUG_OBJECT (demux, "Seek position looks sane");
1958 GST_OBJECT_UNLOCK (demux);
1961 /* only have to update some segment,
1962 * but also still have to honour flush and so on */
1963 GST_DEBUG_OBJECT (demux, "... no update");
1964 /* bad goto, bad ... */
1968 if (demux->streaming)
1973 GstEvent *flush_event = gst_event_new_flush_start ();
1974 gst_event_set_seqnum (flush_event, seqnum);
1975 GST_DEBUG_OBJECT (demux, "Starting flush");
1976 gst_pad_push_event (demux->common.sinkpad, gst_event_ref (flush_event));
1977 gst_matroska_demux_send_event (demux, flush_event);
1979 GST_DEBUG_OBJECT (demux, "Non-flushing seek, pausing task");
1980 gst_pad_pause_task (demux->common.sinkpad);
1984 GST_PAD_STREAM_LOCK (demux->common.sinkpad);
1989 /* now grab the stream lock so that streaming cannot continue, for
1990 * non flushing seeks when the element is in PAUSED this could block
1992 GST_DEBUG_OBJECT (demux, "Waiting for streaming to stop");
1993 GST_PAD_STREAM_LOCK (demux->common.sinkpad);
1996 /* pull mode without index can do some scanning */
1997 if (!demux->streaming && !entry) {
1998 GstEvent *flush_event;
2000 /* need to stop flushing upstream as we need it next */
2002 flush_event = gst_event_new_flush_stop (TRUE);
2003 gst_event_set_seqnum (flush_event, seqnum);
2004 gst_pad_push_event (demux->common.sinkpad, flush_event);
2006 entry = gst_matroska_demux_search_pos (demux, seeksegment.position);
2007 /* keep local copy */
2009 scan_entry = *entry;
2011 entry = &scan_entry;
2013 GST_DEBUG_OBJECT (demux, "Scan failed to find matching position");
2015 flush_event = gst_event_new_flush_stop (TRUE);
2016 gst_event_set_seqnum (flush_event, seqnum);
2017 gst_matroska_demux_send_event (demux, flush_event);
2025 GST_DEBUG_OBJECT (demux, "seek to key unit, adjusting segment start from %"
2026 GST_TIME_FORMAT " to %" GST_TIME_FORMAT,
2027 GST_TIME_ARGS (seeksegment.start), GST_TIME_ARGS (entry->time));
2028 seeksegment.start = MAX (entry->time, demux->stream_start_time);
2029 seeksegment.position = seeksegment.start;
2030 seeksegment.time = seeksegment.start - demux->stream_start_time;
2033 if (demux->streaming) {
2034 GST_OBJECT_LOCK (demux);
2035 /* track real position we should start at */
2036 GST_DEBUG_OBJECT (demux, "storing segment start");
2037 demux->requested_seek_time = seeksegment.position;
2038 demux->seek_offset = entry->pos + demux->common.ebml_segment_start;
2039 GST_OBJECT_UNLOCK (demux);
2040 /* need to seek to cluster start to pick up cluster time */
2041 /* upstream takes care of flushing and all that
2042 * ... and newsegment event handling takes care of the rest */
2043 return perform_seek_to_offset (demux, rate,
2044 entry->pos + demux->common.ebml_segment_start, seqnum);
2049 GstEvent *flush_event = gst_event_new_flush_stop (TRUE);
2050 gst_event_set_seqnum (flush_event, seqnum);
2051 GST_DEBUG_OBJECT (demux, "Stopping flush");
2052 gst_pad_push_event (demux->common.sinkpad, gst_event_ref (flush_event));
2053 gst_matroska_demux_send_event (demux, flush_event);
2056 GST_OBJECT_LOCK (demux);
2057 /* now update the real segment info */
2058 GST_DEBUG_OBJECT (demux, "Committing new seek segment");
2059 memcpy (&demux->common.segment, &seeksegment, sizeof (GstSegment));
2060 GST_OBJECT_UNLOCK (demux);
2062 /* update some (segment) state */
2063 if (!gst_matroska_demux_move_to_entry (demux, entry, TRUE, update))
2066 /* notify start of new segment */
2067 if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
2070 msg = gst_message_new_segment_start (GST_OBJECT (demux),
2071 GST_FORMAT_TIME, demux->common.segment.start);
2072 gst_message_set_seqnum (msg, seqnum);
2073 gst_element_post_message (GST_ELEMENT (demux), msg);
2076 GST_OBJECT_LOCK (demux);
2077 if (demux->new_segment)
2078 gst_event_unref (demux->new_segment);
2080 /* On port from 0.10, discarded !update (for segment.update) here, FIXME? */
2081 demux->new_segment = gst_event_new_segment (&demux->common.segment);
2082 gst_event_set_seqnum (demux->new_segment, seqnum);
2083 if (demux->common.segment.rate < 0 && demux->common.segment.stop == -1)
2084 demux->to_time = demux->common.segment.position;
2086 demux->to_time = GST_CLOCK_TIME_NONE;
2087 GST_OBJECT_UNLOCK (demux);
2089 /* restart our task since it might have been stopped when we did the
2091 gst_pad_start_task (demux->common.sinkpad,
2092 (GstTaskFunction) gst_matroska_demux_loop, demux->common.sinkpad, NULL);
2094 /* streaming can continue now */
2096 GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
2104 GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
2106 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Got a seek error"));
2112 * Handle whether we can perform the seek event or if we have to let the chain
2113 * function handle seeks to build the seek indexes first.
2116 gst_matroska_demux_handle_seek_push (GstMatroskaDemux * demux, GstPad * pad,
2120 GstSeekType cur_type, stop_type;
2125 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
2130 /* we can only seek on time */
2131 if (format != GST_FORMAT_TIME) {
2132 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
2136 if (stop_type != GST_SEEK_TYPE_NONE && stop != GST_CLOCK_TIME_NONE) {
2137 GST_DEBUG_OBJECT (demux, "Seek end-time not supported in streaming mode");
2141 if (!(flags & GST_SEEK_FLAG_FLUSH)) {
2142 GST_DEBUG_OBJECT (demux,
2143 "Non-flushing seek not supported in streaming mode");
2147 if (flags & GST_SEEK_FLAG_SEGMENT) {
2148 GST_DEBUG_OBJECT (demux, "Segment seek not supported in streaming mode");
2152 /* check for having parsed index already */
2153 if (!demux->common.index_parsed) {
2154 gboolean building_index;
2157 if (!demux->index_offset) {
2158 GST_DEBUG_OBJECT (demux, "no index (location); no seek in push mode");
2162 GST_OBJECT_LOCK (demux);
2163 /* handle the seek event in the chain function */
2164 demux->common.state = GST_MATROSKA_READ_STATE_SEEK;
2165 /* no more seek can be issued until state reset to _DATA */
2167 /* copy the event */
2168 if (demux->seek_event)
2169 gst_event_unref (demux->seek_event);
2170 demux->seek_event = gst_event_ref (event);
2172 /* set the building_index flag so that only one thread can setup the
2173 * structures for index seeking. */
2174 building_index = demux->building_index;
2175 if (!building_index) {
2176 demux->building_index = TRUE;
2177 offset = demux->index_offset;
2179 GST_OBJECT_UNLOCK (demux);
2181 if (!building_index) {
2182 /* seek to the first subindex or legacy index */
2183 GST_INFO_OBJECT (demux, "Seeking to Cues at %" G_GUINT64_FORMAT, offset);
2184 return perform_seek_to_offset (demux, rate, offset,
2185 gst_event_get_seqnum (event));
2188 /* well, we are handling it already */
2192 /* delegate to tweaked regular seek */
2193 return gst_matroska_demux_handle_seek_event (demux, pad, event);
2197 gst_matroska_demux_handle_src_event (GstPad * pad, GstObject * parent,
2200 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
2201 gboolean res = TRUE;
2203 switch (GST_EVENT_TYPE (event)) {
2204 case GST_EVENT_SEEK:
2205 /* no seeking until we are (safely) ready */
2206 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
2207 GST_DEBUG_OBJECT (demux, "not ready for seeking yet");
2210 if (!demux->streaming)
2211 res = gst_matroska_demux_handle_seek_event (demux, pad, event);
2213 res = gst_matroska_demux_handle_seek_push (demux, pad, event);
2214 gst_event_unref (event);
2219 GstMatroskaTrackContext *context = gst_pad_get_element_private (pad);
2220 if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
2221 GstMatroskaTrackVideoContext *videocontext =
2222 (GstMatroskaTrackVideoContext *) context;
2224 GstClockTimeDiff diff;
2225 GstClockTime timestamp;
2227 gst_event_parse_qos (event, NULL, &proportion, &diff, ×tamp);
2229 GST_OBJECT_LOCK (demux);
2230 videocontext->earliest_time = timestamp + diff;
2231 GST_OBJECT_UNLOCK (demux);
2234 gst_event_unref (event);
2238 case GST_EVENT_TOC_SELECT:
2241 GstTocEntry *entry = NULL;
2242 GstEvent *seek_event;
2245 if (!demux->common.toc) {
2246 GST_DEBUG_OBJECT (demux, "no TOC to select");
2249 gst_event_parse_toc_select (event, &uid);
2251 GST_OBJECT_LOCK (demux);
2252 entry = gst_toc_find_entry (demux->common.toc, uid);
2253 if (entry == NULL) {
2254 GST_OBJECT_UNLOCK (demux);
2255 GST_WARNING_OBJECT (demux, "no TOC entry with given UID: %s", uid);
2258 gst_toc_entry_get_start_stop_times (entry, &start_pos, NULL);
2259 GST_OBJECT_UNLOCK (demux);
2260 seek_event = gst_event_new_seek (1.0,
2262 GST_SEEK_FLAG_FLUSH,
2263 GST_SEEK_TYPE_SET, start_pos, GST_SEEK_TYPE_SET, -1);
2264 res = gst_matroska_demux_handle_seek_event (demux, pad, seek_event);
2265 gst_event_unref (seek_event);
2269 GST_WARNING_OBJECT (demux, "received empty TOC select event");
2273 gst_event_unref (event);
2277 /* events we don't need to handle */
2278 case GST_EVENT_NAVIGATION:
2279 gst_event_unref (event);
2283 case GST_EVENT_LATENCY:
2285 res = gst_pad_push_event (demux->common.sinkpad, event);
2292 static GstFlowReturn
2293 gst_matroska_demux_seek_to_previous_keyframe (GstMatroskaDemux * demux)
2295 GstFlowReturn ret = GST_FLOW_EOS;
2296 gboolean done = TRUE;
2299 g_return_val_if_fail (demux->seek_index, GST_FLOW_EOS);
2300 g_return_val_if_fail (demux->seek_entry < demux->seek_index->len,
2303 GST_DEBUG_OBJECT (demux, "locating previous keyframe");
2305 if (!demux->seek_entry) {
2306 GST_DEBUG_OBJECT (demux, "no earlier index entry");
2310 for (i = 0; i < demux->common.src->len; i++) {
2311 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
2313 GST_DEBUG_OBJECT (demux, "segment start %" GST_TIME_FORMAT
2314 ", stream %d at %" GST_TIME_FORMAT,
2315 GST_TIME_ARGS (demux->common.segment.start), stream->index,
2316 GST_TIME_ARGS (stream->from_time));
2317 if (GST_CLOCK_TIME_IS_VALID (stream->from_time)) {
2318 if (stream->from_time > demux->common.segment.start) {
2319 GST_DEBUG_OBJECT (demux, "stream %d not finished yet", stream->index);
2323 /* nothing pushed for this stream;
2324 * likely seek entry did not start at keyframe, so all was skipped.
2325 * So we need an earlier entry */
2331 GstMatroskaIndex *entry;
2333 entry = &g_array_index (demux->seek_index, GstMatroskaIndex,
2334 --demux->seek_entry);
2335 if (!gst_matroska_demux_move_to_entry (demux, entry, FALSE, TRUE))
2345 static GstFlowReturn
2346 gst_matroska_demux_parse_tracks (GstMatroskaDemux * demux, GstEbmlRead * ebml)
2348 GstFlowReturn ret = GST_FLOW_OK;
2351 DEBUG_ELEMENT_START (demux, ebml, "Tracks");
2353 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2354 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
2358 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
2359 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
2363 /* one track within the "all-tracks" header */
2364 case GST_MATROSKA_ID_TRACKENTRY:
2365 ret = gst_matroska_demux_add_stream (demux, ebml);
2369 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
2374 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
2376 demux->tracks_parsed = TRUE;
2382 * Read signed/unsigned "EBML" numbers.
2383 * Return: number of bytes processed.
2387 gst_matroska_ebmlnum_uint (guint8 * data, guint size, guint64 * num)
2389 gint len_mask = 0x80, read = 1, n = 1, num_ffs = 0;
2397 while (read <= 8 && !(total & len_mask)) {
2404 if ((total &= (len_mask - 1)) == len_mask - 1)
2409 if (data[n] == 0xff)
2411 total = (total << 8) | data[n];
2415 if (read == num_ffs && total != 0)
2424 gst_matroska_ebmlnum_sint (guint8 * data, guint size, gint64 * num)
2429 /* read as unsigned number first */
2430 if ((res = gst_matroska_ebmlnum_uint (data, size, &unum)) < 0)
2434 if (unum == G_MAXUINT64)
2437 *num = unum - ((1 << ((7 * res) - 1)) - 1);
2443 * Mostly used for subtitles. We add void filler data for each
2444 * lagging stream to make sure we don't deadlock.
2448 gst_matroska_demux_sync_streams (GstMatroskaDemux * demux)
2452 GST_OBJECT_LOCK (demux);
2454 GST_LOG_OBJECT (demux, "Sync to %" GST_TIME_FORMAT,
2455 GST_TIME_ARGS (demux->common.segment.position));
2457 g_assert (demux->common.num_streams == demux->common.src->len);
2458 for (stream_nr = 0; stream_nr < demux->common.src->len; stream_nr++) {
2459 GstMatroskaTrackContext *context;
2461 context = g_ptr_array_index (demux->common.src, stream_nr);
2463 GST_LOG_OBJECT (demux,
2464 "Checking for resync on stream %d (%" GST_TIME_FORMAT ")", stream_nr,
2465 GST_TIME_ARGS (context->pos));
2467 if (G_LIKELY (context->type != GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
2468 GST_LOG_OBJECT (demux, "Skipping sync on non-subtitle stream");
2472 /* does it lag? 0.5 seconds is a random threshold...
2473 * lag need only be considered if we have advanced into requested segment */
2474 if (GST_CLOCK_TIME_IS_VALID (context->pos) &&
2475 GST_CLOCK_TIME_IS_VALID (demux->common.segment.position) &&
2476 demux->common.segment.position > demux->common.segment.start &&
2477 context->pos + (GST_SECOND / 2) < demux->common.segment.position) {
2480 guint64 start = context->pos;
2481 guint64 stop = demux->common.segment.position - (GST_SECOND / 2);
2483 GST_DEBUG_OBJECT (demux,
2484 "Synchronizing stream %d with other by advancing time from %"
2485 GST_TIME_FORMAT " to %" GST_TIME_FORMAT, stream_nr,
2486 GST_TIME_ARGS (start), GST_TIME_ARGS (stop));
2488 context->pos = stop;
2490 event = gst_event_new_gap (start, stop - start);
2491 GST_OBJECT_UNLOCK (demux);
2492 gst_pad_push_event (context->pad, event);
2493 GST_OBJECT_LOCK (demux);
2497 GST_OBJECT_UNLOCK (demux);
2500 static GstFlowReturn
2501 gst_matroska_demux_push_stream_headers (GstMatroskaDemux * demux,
2502 GstMatroskaTrackContext * stream)
2504 GstFlowReturn ret = GST_FLOW_OK;
2507 num = gst_buffer_list_length (stream->stream_headers);
2508 for (i = 0; i < num; ++i) {
2511 buf = gst_buffer_list_get (stream->stream_headers, i);
2512 buf = gst_buffer_copy (buf);
2514 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
2516 if (stream->set_discont) {
2517 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
2518 stream->set_discont = FALSE;
2520 GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DISCONT);
2523 /* push out all headers in one go and use last flow return */
2524 ret = gst_pad_push (stream->pad, buf);
2527 /* don't need these any longer */
2528 gst_buffer_list_unref (stream->stream_headers);
2529 stream->stream_headers = NULL;
2532 ret = gst_flow_combiner_update_flow (demux->flowcombiner, ret);
2538 gst_matroska_demux_push_dvd_clut_change_event (GstMatroskaDemux * demux,
2539 GstMatroskaTrackContext * stream)
2543 g_assert (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB));
2545 if (!stream->codec_priv)
2548 /* ideally, VobSub private data should be parsed and stored more convenient
2549 * elsewhere, but for now, only interested in a small part */
2551 /* make sure we have terminating 0 */
2552 buf = g_strndup (stream->codec_priv, stream->codec_priv_size);
2554 /* just locate and parse palette part */
2555 start = strstr (buf, "palette:");
2560 guint8 r, g, b, y, u, v;
2563 while (g_ascii_isspace (*start))
2565 for (i = 0; i < 16; i++) {
2566 if (sscanf (start, "%06x", &col) != 1)
2569 while ((*start == ',') || g_ascii_isspace (*start))
2571 /* sigh, need to convert this from vobsub pseudo-RGB to YUV */
2572 r = (col >> 16) & 0xff;
2573 g = (col >> 8) & 0xff;
2575 y = CLAMP ((0.1494 * r + 0.6061 * g + 0.2445 * b) * 219 / 255 + 16, 0,
2577 u = CLAMP (0.6066 * r - 0.4322 * g - 0.1744 * b + 128, 0, 255);
2578 v = CLAMP (-0.08435 * r - 0.3422 * g + 0.4266 * b + 128, 0, 255);
2579 clut[i] = (y << 16) | (u << 8) | v;
2582 /* got them all without problems; build and send event */
2586 s = gst_structure_new ("application/x-gst-dvd", "event", G_TYPE_STRING,
2587 "dvd-spu-clut-change", "clut00", G_TYPE_INT, clut[0], "clut01",
2588 G_TYPE_INT, clut[1], "clut02", G_TYPE_INT, clut[2], "clut03",
2589 G_TYPE_INT, clut[3], "clut04", G_TYPE_INT, clut[4], "clut05",
2590 G_TYPE_INT, clut[5], "clut06", G_TYPE_INT, clut[6], "clut07",
2591 G_TYPE_INT, clut[7], "clut08", G_TYPE_INT, clut[8], "clut09",
2592 G_TYPE_INT, clut[9], "clut10", G_TYPE_INT, clut[10], "clut11",
2593 G_TYPE_INT, clut[11], "clut12", G_TYPE_INT, clut[12], "clut13",
2594 G_TYPE_INT, clut[13], "clut14", G_TYPE_INT, clut[14], "clut15",
2595 G_TYPE_INT, clut[15], NULL);
2597 gst_pad_push_event (stream->pad,
2598 gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM_STICKY, s));
2605 gst_matroska_demux_push_codec_data_all (GstMatroskaDemux * demux)
2609 GST_OBJECT_LOCK (demux);
2611 g_assert (demux->common.num_streams == demux->common.src->len);
2612 for (stream_nr = 0; stream_nr < demux->common.src->len; stream_nr++) {
2613 GstMatroskaTrackContext *stream;
2615 stream = g_ptr_array_index (demux->common.src, stream_nr);
2617 if (stream->send_stream_headers) {
2618 if (stream->stream_headers != NULL) {
2619 gst_matroska_demux_push_stream_headers (demux, stream);
2621 /* FIXME: perhaps we can just disable and skip this stream then */
2622 GST_ELEMENT_ERROR (demux, STREAM, DECODE, (NULL),
2623 ("Failed to extract stream headers from codec private data"));
2625 stream->send_stream_headers = FALSE;
2628 if (stream->send_dvd_event) {
2629 gst_matroska_demux_push_dvd_clut_change_event (demux, stream);
2630 /* FIXME: should we send this event again after (flushing) seek ? */
2631 stream->send_dvd_event = FALSE;
2635 GST_OBJECT_UNLOCK (demux);
2638 static GstFlowReturn
2639 gst_matroska_demux_add_mpeg_seq_header (GstElement * element,
2640 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2643 guint seq_header_len;
2644 guint32 header, tmp;
2646 if (stream->codec_state) {
2647 seq_header = stream->codec_state;
2648 seq_header_len = stream->codec_state_size;
2649 } else if (stream->codec_priv) {
2650 seq_header = stream->codec_priv;
2651 seq_header_len = stream->codec_priv_size;
2656 /* Sequence header only needed for keyframes */
2657 if (GST_BUFFER_FLAG_IS_SET (*buf, GST_BUFFER_FLAG_DELTA_UNIT))
2660 if (gst_buffer_get_size (*buf) < 4)
2663 gst_buffer_extract (*buf, 0, &tmp, sizeof (guint32));
2664 header = GUINT32_FROM_BE (tmp);
2666 /* Sequence start code, if not found prepend */
2667 if (header != 0x000001b3) {
2670 GST_DEBUG_OBJECT (element, "Prepending MPEG sequence header");
2672 newbuf = gst_buffer_new_wrapped (g_memdup (seq_header, seq_header_len),
2675 gst_buffer_copy_into (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
2676 GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_MEMORY, 0,
2677 gst_buffer_get_size (*buf));
2679 gst_buffer_unref (*buf);
2686 static GstFlowReturn
2687 gst_matroska_demux_add_wvpk_header (GstElement * element,
2688 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2690 GstMatroskaTrackAudioContext *audiocontext =
2691 (GstMatroskaTrackAudioContext *) stream;
2692 GstBuffer *newbuf = NULL;
2693 GstMapInfo map, outmap;
2694 guint8 *buf_data, *data;
2702 wvh.version = GST_READ_UINT16_LE (stream->codec_priv);
2705 wvh.total_samples = -1;
2706 wvh.block_index = audiocontext->wvpk_block_index;
2708 if (audiocontext->channels <= 2) {
2709 guint32 block_samples, tmp;
2710 gsize size = gst_buffer_get_size (*buf);
2712 gst_buffer_extract (*buf, 0, &tmp, sizeof (guint32));
2713 block_samples = GUINT32_FROM_LE (tmp);
2714 /* we need to reconstruct the header of the wavpack block */
2716 /* -20 because ck_size is the size of the wavpack block -8
2717 * and lace_size is the size of the wavpack block + 12
2718 * (the three guint32 of the header that already are in the buffer) */
2719 wvh.ck_size = size + sizeof (Wavpack4Header) - 20;
2721 /* block_samples, flags and crc are already in the buffer */
2722 newbuf = gst_buffer_new_allocate (NULL, sizeof (Wavpack4Header) - 12, NULL);
2724 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2730 GST_WRITE_UINT32_LE (data + 4, wvh.ck_size);
2731 GST_WRITE_UINT16_LE (data + 8, wvh.version);
2732 GST_WRITE_UINT8 (data + 10, wvh.track_no);
2733 GST_WRITE_UINT8 (data + 11, wvh.index_no);
2734 GST_WRITE_UINT32_LE (data + 12, wvh.total_samples);
2735 GST_WRITE_UINT32_LE (data + 16, wvh.block_index);
2737 /* Append data from buf: */
2738 gst_buffer_copy_into (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
2739 GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_MEMORY, 0, size);
2741 gst_buffer_unref (*buf);
2743 audiocontext->wvpk_block_index += block_samples;
2745 guint8 *outdata = NULL;
2747 gsize buf_size, size, out_size = 0;
2748 guint32 block_samples, flags, crc, blocksize;
2750 gst_buffer_map (*buf, &map, GST_MAP_READ);
2751 buf_data = map.data;
2752 buf_size = map.size;
2755 GST_ERROR_OBJECT (element, "Too small wavpack buffer");
2756 gst_buffer_unmap (*buf, &map);
2757 return GST_FLOW_ERROR;
2763 block_samples = GST_READ_UINT32_LE (data);
2768 flags = GST_READ_UINT32_LE (data);
2771 crc = GST_READ_UINT32_LE (data);
2774 blocksize = GST_READ_UINT32_LE (data);
2778 if (blocksize == 0 || size < blocksize)
2781 g_assert ((newbuf == NULL) == (outdata == NULL));
2783 if (newbuf == NULL) {
2784 out_size = sizeof (Wavpack4Header) + blocksize;
2785 newbuf = gst_buffer_new_allocate (NULL, out_size, NULL);
2787 gst_buffer_copy_into (newbuf, *buf,
2788 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS, 0, -1);
2791 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2792 outdata = outmap.data;
2794 gst_buffer_unmap (newbuf, &outmap);
2795 out_size += sizeof (Wavpack4Header) + blocksize;
2796 gst_buffer_set_size (newbuf, out_size);
2797 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2798 outdata = outmap.data;
2801 outdata[outpos] = 'w';
2802 outdata[outpos + 1] = 'v';
2803 outdata[outpos + 2] = 'p';
2804 outdata[outpos + 3] = 'k';
2807 GST_WRITE_UINT32_LE (outdata + outpos,
2808 blocksize + sizeof (Wavpack4Header) - 8);
2809 GST_WRITE_UINT16_LE (outdata + outpos + 4, wvh.version);
2810 GST_WRITE_UINT8 (outdata + outpos + 6, wvh.track_no);
2811 GST_WRITE_UINT8 (outdata + outpos + 7, wvh.index_no);
2812 GST_WRITE_UINT32_LE (outdata + outpos + 8, wvh.total_samples);
2813 GST_WRITE_UINT32_LE (outdata + outpos + 12, wvh.block_index);
2814 GST_WRITE_UINT32_LE (outdata + outpos + 16, block_samples);
2815 GST_WRITE_UINT32_LE (outdata + outpos + 20, flags);
2816 GST_WRITE_UINT32_LE (outdata + outpos + 24, crc);
2819 memmove (outdata + outpos, data, blocksize);
2820 outpos += blocksize;
2824 gst_buffer_unmap (*buf, &map);
2825 gst_buffer_unref (*buf);
2828 gst_buffer_unmap (newbuf, &outmap);
2831 audiocontext->wvpk_block_index += block_samples;
2837 /* @text must be null-terminated */
2839 gst_matroska_demux_subtitle_chunk_has_tag (GstElement * element,
2844 g_return_val_if_fail (text != NULL, FALSE);
2846 /* yes, this might all lead to false positives ... */
2847 tag = (gchar *) text;
2848 while ((tag = strchr (tag, '<'))) {
2850 if (*tag != '\0' && *(tag + 1) == '>') {
2851 /* some common convenience ones */
2852 /* maybe any character will do here ? */
2865 if (strstr (text, "<span"))
2871 static GstFlowReturn
2872 gst_matroska_demux_check_subtitle_buffer (GstElement * element,
2873 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2875 GstMatroskaTrackSubtitleContext *sub_stream;
2876 const gchar *encoding;
2881 gboolean needs_unmap = TRUE;
2883 sub_stream = (GstMatroskaTrackSubtitleContext *) stream;
2885 if (!gst_buffer_get_size (*buf) || !gst_buffer_map (*buf, &map, GST_MAP_READ))
2888 /* Need \0-terminator at the end */
2889 if (map.data[map.size - 1] != '\0') {
2890 newbuf = gst_buffer_new_and_alloc (map.size + 1);
2892 /* Copy old buffer and add a 0 at the end */
2893 gst_buffer_fill (newbuf, 0, map.data, map.size);
2894 gst_buffer_memset (newbuf, map.size, 0, 1);
2895 gst_buffer_unmap (*buf, &map);
2897 gst_buffer_copy_into (newbuf, *buf,
2898 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS |
2899 GST_BUFFER_COPY_META, 0, -1);
2900 gst_buffer_unref (*buf);
2902 gst_buffer_map (*buf, &map, GST_MAP_READ);
2905 if (!sub_stream->invalid_utf8) {
2906 if (g_utf8_validate ((gchar *) map.data, map.size - 1, NULL)) {
2909 GST_WARNING_OBJECT (element, "subtitle stream %" G_GUINT64_FORMAT
2910 " is not valid UTF-8, this is broken according to the matroska"
2911 " specification", stream->num);
2912 sub_stream->invalid_utf8 = TRUE;
2915 /* file with broken non-UTF8 subtitle, do the best we can do to fix it */
2916 encoding = g_getenv ("GST_SUBTITLE_ENCODING");
2917 if (encoding == NULL || *encoding == '\0') {
2918 /* if local encoding is UTF-8 and no encoding specified
2919 * via the environment variable, assume ISO-8859-15 */
2920 if (g_get_charset (&encoding)) {
2921 encoding = "ISO-8859-15";
2926 g_convert_with_fallback ((gchar *) map.data, map.size, "UTF-8", encoding,
2927 (char *) "*", NULL, NULL, &err);
2930 GST_LOG_OBJECT (element, "could not convert string from '%s' to UTF-8: %s",
2931 encoding, err->message);
2935 /* invalid input encoding, fall back to ISO-8859-15 (always succeeds) */
2936 encoding = "ISO-8859-15";
2938 g_convert_with_fallback ((gchar *) map.data, map.size, "UTF-8",
2939 encoding, (char *) "*", NULL, NULL, NULL);
2942 GST_LOG_OBJECT (element, "converted subtitle text from %s to UTF-8 %s",
2943 encoding, (err) ? "(using ISO-8859-15 as fallback)" : "");
2946 utf8 = g_strdup ("invalid subtitle");
2948 newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
2949 gst_buffer_unmap (*buf, &map);
2950 gst_buffer_copy_into (newbuf, *buf,
2951 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_META,
2953 gst_buffer_unref (*buf);
2956 gst_buffer_map (*buf, &map, GST_MAP_READ);
2960 if (sub_stream->check_markup) {
2961 /* caps claim markup text, so we need to escape text,
2962 * except if text is already markup and then needs no further escaping */
2963 sub_stream->seen_markup_tag = sub_stream->seen_markup_tag ||
2964 gst_matroska_demux_subtitle_chunk_has_tag (element, (gchar *) map.data);
2966 if (!sub_stream->seen_markup_tag) {
2967 utf8 = g_markup_escape_text ((gchar *) map.data, map.size);
2969 newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
2970 gst_buffer_unmap (*buf, &map);
2971 gst_buffer_copy_into (newbuf, *buf,
2972 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS |
2973 GST_BUFFER_COPY_META, 0, -1);
2974 gst_buffer_unref (*buf);
2977 needs_unmap = FALSE;
2982 gst_buffer_unmap (*buf, &map);
2987 static GstFlowReturn
2988 gst_matroska_demux_check_aac (GstElement * element,
2989 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2994 gst_buffer_extract (*buf, 0, data, 2);
2995 size = gst_buffer_get_size (*buf);
2997 if (size > 2 && data[0] == 0xff && (data[1] >> 4 == 0x0f)) {
3000 /* tss, ADTS data, remove codec_data
3001 * still assume it is at least parsed */
3002 stream->caps = gst_caps_make_writable (stream->caps);
3003 s = gst_caps_get_structure (stream->caps, 0);
3005 gst_structure_remove_field (s, "codec_data");
3006 gst_pad_set_caps (stream->pad, stream->caps);
3007 GST_DEBUG_OBJECT (element, "ADTS AAC audio data; removing codec-data, "
3008 "new caps: %" GST_PTR_FORMAT, stream->caps);
3011 /* disable subsequent checking */
3012 stream->postprocess_frame = NULL;
3018 gst_matroska_demux_align_buffer (GstMatroskaDemux * demux,
3019 GstBuffer * buffer, gsize alignment)
3023 gst_buffer_map (buffer, &map, GST_MAP_READ);
3025 if (map.size < sizeof (guintptr)) {
3026 gst_buffer_unmap (buffer, &map);
3030 if (((guintptr) map.data) & (alignment - 1)) {
3031 GstBuffer *new_buffer;
3032 GstAllocationParams params = { 0, alignment - 1, 0, 0, };
3034 new_buffer = gst_buffer_new_allocate (NULL,
3035 gst_buffer_get_size (buffer), ¶ms);
3037 /* Copy data "by hand", so ensure alignment is kept: */
3038 gst_buffer_fill (new_buffer, 0, map.data, map.size);
3040 gst_buffer_copy_into (new_buffer, buffer, GST_BUFFER_COPY_METADATA, 0, -1);
3041 GST_DEBUG_OBJECT (demux,
3042 "We want output aligned on %" G_GSIZE_FORMAT ", reallocated",
3045 gst_buffer_unmap (buffer, &map);
3046 gst_buffer_unref (buffer);
3051 gst_buffer_unmap (buffer, &map);
3055 static GstFlowReturn
3056 gst_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux,
3057 GstEbmlRead * ebml, guint64 cluster_time, guint64 cluster_offset,
3058 gboolean is_simpleblock)
3060 GstMatroskaTrackContext *stream = NULL;
3061 GstFlowReturn ret = GST_FLOW_OK;
3062 gboolean readblock = FALSE;
3064 guint64 block_duration = -1;
3065 GstBuffer *buf = NULL;
3067 gint stream_num = -1, n, laces = 0;
3069 gint *lace_size = NULL;
3072 gint64 referenceblock = 0;
3075 offset = gst_ebml_read_get_offset (ebml);
3077 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3078 if (!is_simpleblock) {
3079 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK) {
3083 id = GST_MATROSKA_ID_SIMPLEBLOCK;
3087 /* one block inside the group. Note, block parsing is one
3088 * of the harder things, so this code is a bit complicated.
3089 * See http://www.matroska.org/ for documentation. */
3090 case GST_MATROSKA_ID_SIMPLEBLOCK:
3091 case GST_MATROSKA_ID_BLOCK:
3097 gst_buffer_unmap (buf, &map);
3098 gst_buffer_unref (buf);
3101 if ((ret = gst_ebml_read_buffer (ebml, &id, &buf)) != GST_FLOW_OK)
3104 gst_buffer_map (buf, &map, GST_MAP_READ);
3108 /* first byte(s): blocknum */
3109 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
3114 /* fetch stream from num */
3115 stream_num = gst_matroska_read_common_stream_from_num (&demux->common,
3117 if (G_UNLIKELY (size < 3)) {
3118 GST_WARNING_OBJECT (demux, "Invalid size %u", size);
3119 /* non-fatal, try next block(group) */
3122 } else if (G_UNLIKELY (stream_num < 0 ||
3123 stream_num >= demux->common.num_streams)) {
3124 /* let's not give up on a stray invalid track number */
3125 GST_WARNING_OBJECT (demux,
3126 "Invalid stream %d for track number %" G_GUINT64_FORMAT
3127 "; ignoring block", stream_num, num);
3131 stream = g_ptr_array_index (demux->common.src, stream_num);
3133 /* time (relative to cluster time) */
3134 time = ((gint16) GST_READ_UINT16_BE (data));
3137 flags = GST_READ_UINT8 (data);
3141 GST_LOG_OBJECT (demux, "time %" G_GUINT64_FORMAT ", flags %d", time,
3144 switch ((flags & 0x06) >> 1) {
3145 case 0x0: /* no lacing */
3147 lace_size = g_new (gint, 1);
3148 lace_size[0] = size;
3151 case 0x1: /* xiph lacing */
3152 case 0x2: /* fixed-size lacing */
3153 case 0x3: /* EBML lacing */
3155 goto invalid_lacing;
3156 laces = GST_READ_UINT8 (data) + 1;
3159 lace_size = g_new0 (gint, laces);
3161 switch ((flags & 0x06) >> 1) {
3162 case 0x1: /* xiph lacing */ {
3163 guint temp, total = 0;
3165 for (n = 0; ret == GST_FLOW_OK && n < laces - 1; n++) {
3168 goto invalid_lacing;
3169 temp = GST_READ_UINT8 (data);
3170 lace_size[n] += temp;
3176 total += lace_size[n];
3178 lace_size[n] = size - total;
3182 case 0x2: /* fixed-size lacing */
3183 for (n = 0; n < laces; n++)
3184 lace_size[n] = size / laces;
3187 case 0x3: /* EBML lacing */ {
3190 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
3194 total = lace_size[0] = num;
3195 for (n = 1; ret == GST_FLOW_OK && n < laces - 1; n++) {
3199 if ((r = gst_matroska_ebmlnum_sint (data, size, &snum)) < 0)
3203 lace_size[n] = lace_size[n - 1] + snum;
3204 total += lace_size[n];
3207 lace_size[n] = size - total;
3214 if (ret != GST_FLOW_OK)
3221 case GST_MATROSKA_ID_BLOCKDURATION:{
3222 ret = gst_ebml_read_uint (ebml, &id, &block_duration);
3223 GST_DEBUG_OBJECT (demux, "BlockDuration: %" G_GUINT64_FORMAT,
3228 case GST_MATROSKA_ID_REFERENCEBLOCK:{
3229 ret = gst_ebml_read_sint (ebml, &id, &referenceblock);
3230 GST_DEBUG_OBJECT (demux, "ReferenceBlock: %" G_GINT64_FORMAT,
3235 case GST_MATROSKA_ID_CODECSTATE:{
3237 guint64 data_len = 0;
3240 gst_ebml_read_binary (ebml, &id, &data,
3241 &data_len)) != GST_FLOW_OK)
3244 if (G_UNLIKELY (stream == NULL)) {
3245 GST_WARNING_OBJECT (demux,
3246 "Unexpected CodecState subelement - ignoring");
3250 g_free (stream->codec_state);
3251 stream->codec_state = data;
3252 stream->codec_state_size = data_len;
3254 /* Decode if necessary */
3255 if (stream->encodings && stream->encodings->len > 0
3256 && stream->codec_state && stream->codec_state_size > 0) {
3257 if (!gst_matroska_decode_data (stream->encodings,
3258 &stream->codec_state, &stream->codec_state_size,
3259 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
3260 GST_WARNING_OBJECT (demux, "Decoding codec state failed");
3264 GST_DEBUG_OBJECT (demux, "CodecState of %" G_GSIZE_FORMAT " bytes",
3265 stream->codec_state_size);
3270 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3274 case GST_MATROSKA_ID_BLOCKVIRTUAL:
3275 case GST_MATROSKA_ID_BLOCKADDITIONS:
3276 case GST_MATROSKA_ID_REFERENCEPRIORITY:
3277 case GST_MATROSKA_ID_REFERENCEVIRTUAL:
3278 case GST_MATROSKA_ID_SLICES:
3279 GST_DEBUG_OBJECT (demux,
3280 "Skipping BlockGroup subelement 0x%x - ignoring", id);
3281 ret = gst_ebml_read_skip (ebml);
3289 /* reading a number or so could have failed */
3290 if (ret != GST_FLOW_OK)
3293 if (ret == GST_FLOW_OK && readblock) {
3294 gboolean invisible_frame = FALSE;
3295 gboolean delta_unit = FALSE;
3296 guint64 duration = 0;
3297 gint64 lace_time = 0;
3299 stream = g_ptr_array_index (demux->common.src, stream_num);
3301 if (cluster_time != GST_CLOCK_TIME_NONE) {
3302 /* FIXME: What to do with negative timestamps? Give timestamp 0 or -1?
3303 * Drop unless the lace contains timestamp 0? */
3304 if (time < 0 && (-time) > cluster_time) {
3307 if (stream->timecodescale == 1.0)
3308 lace_time = (cluster_time + time) * demux->common.time_scale;
3311 gst_util_guint64_to_gdouble ((cluster_time + time) *
3312 demux->common.time_scale) * stream->timecodescale;
3315 lace_time = GST_CLOCK_TIME_NONE;
3318 /* need to refresh segment info ASAP */
3319 if (GST_CLOCK_TIME_IS_VALID (lace_time) && demux->need_segment) {
3320 GstSegment *segment = &demux->common.segment;
3322 GstEvent *segment_event;
3324 if (!GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
3325 demux->stream_start_time = lace_time;
3326 GST_DEBUG_OBJECT (demux,
3327 "Setting stream start time to %" GST_TIME_FORMAT,
3328 GST_TIME_ARGS (lace_time));
3330 clace_time = MAX (lace_time, demux->stream_start_time);
3331 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.position) &&
3332 demux->common.segment.position != 0) {
3333 GST_DEBUG_OBJECT (demux,
3334 "using stored seek position %" GST_TIME_FORMAT,
3335 GST_TIME_ARGS (demux->common.segment.position));
3336 clace_time = demux->common.segment.position + demux->stream_start_time;
3337 segment->position = GST_CLOCK_TIME_NONE;
3339 segment->start = clace_time;
3340 segment->stop = GST_CLOCK_TIME_NONE;
3341 segment->time = segment->start - demux->stream_start_time;
3342 segment->position = segment->start - demux->stream_start_time;
3343 GST_DEBUG_OBJECT (demux,
3344 "generated segment starting at %" GST_TIME_FORMAT ": %"
3345 GST_SEGMENT_FORMAT, GST_TIME_ARGS (lace_time), segment);
3346 /* now convey our segment notion downstream */
3347 segment_event = gst_event_new_segment (segment);
3348 if (demux->segment_seqnum)
3349 gst_event_set_seqnum (segment_event, demux->segment_seqnum);
3350 gst_matroska_demux_send_event (demux, segment_event);
3351 demux->need_segment = FALSE;
3352 demux->segment_seqnum = 0;
3355 /* send pending codec data headers for all streams,
3356 * before we perform sync across all streams */
3357 gst_matroska_demux_push_codec_data_all (demux);
3359 if (block_duration != -1) {
3360 if (stream->timecodescale == 1.0)
3361 duration = gst_util_uint64_scale (block_duration,
3362 demux->common.time_scale, 1);
3365 gst_util_gdouble_to_guint64 (gst_util_guint64_to_gdouble
3366 (gst_util_uint64_scale (block_duration, demux->common.time_scale,
3367 1)) * stream->timecodescale);
3368 } else if (stream->default_duration) {
3369 duration = stream->default_duration * laces;
3371 /* else duration is diff between timecode of this and next block */
3373 /* For SimpleBlock, look at the keyframe bit in flags. Otherwise,
3374 a ReferenceBlock implies that this is not a keyframe. In either
3375 case, it only makes sense for video streams. */
3376 if (stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
3377 if ((is_simpleblock && !(flags & 0x80)) || referenceblock) {
3379 invisible_frame = ((flags & 0x08)) &&
3380 (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8) ||
3381 !strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP9));
3385 for (n = 0; n < laces; n++) {
3388 if (G_UNLIKELY (lace_size[n] > size)) {
3389 GST_WARNING_OBJECT (demux, "Invalid lace size");
3393 /* QoS for video track with an index. the assumption is that
3394 index entries point to keyframes, but if that is not true we
3395 will instad skip until the next keyframe. */
3396 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
3397 stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
3398 stream->index_table && demux->common.segment.rate > 0.0) {
3399 GstMatroskaTrackVideoContext *videocontext =
3400 (GstMatroskaTrackVideoContext *) stream;
3401 GstClockTime earliest_time;
3402 GstClockTime earliest_stream_time;
3404 GST_OBJECT_LOCK (demux);
3405 earliest_time = videocontext->earliest_time;
3406 GST_OBJECT_UNLOCK (demux);
3407 earliest_stream_time = gst_segment_to_position (&demux->common.segment,
3408 GST_FORMAT_TIME, earliest_time);
3410 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
3411 GST_CLOCK_TIME_IS_VALID (earliest_stream_time) &&
3412 lace_time <= earliest_stream_time) {
3413 /* find index entry (keyframe) <= earliest_stream_time */
3414 GstMatroskaIndex *entry =
3415 gst_util_array_binary_search (stream->index_table->data,
3416 stream->index_table->len, sizeof (GstMatroskaIndex),
3417 (GCompareDataFunc) gst_matroska_index_seek_find,
3418 GST_SEARCH_MODE_BEFORE, &earliest_stream_time, NULL);
3420 /* if that entry (keyframe) is after the current the current
3421 buffer, we can skip pushing (and thus decoding) all
3422 buffers until that keyframe. */
3423 if (entry && GST_CLOCK_TIME_IS_VALID (entry->time) &&
3424 entry->time > lace_time) {
3425 GST_LOG_OBJECT (demux, "Skipping lace before late keyframe");
3426 stream->set_discont = TRUE;
3432 sub = gst_buffer_copy_region (buf, GST_BUFFER_COPY_ALL,
3433 gst_buffer_get_size (buf) - size, lace_size[n]);
3434 GST_DEBUG_OBJECT (demux, "created subbuffer %p", sub);
3437 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
3439 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
3441 if (invisible_frame)
3442 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DECODE_ONLY);
3444 if (stream->encodings != NULL && stream->encodings->len > 0)
3445 sub = gst_matroska_decode_buffer (stream, sub);
3448 GST_WARNING_OBJECT (demux, "Decoding buffer failed");
3452 GST_BUFFER_TIMESTAMP (sub) = lace_time;
3454 if (GST_CLOCK_TIME_IS_VALID (lace_time)) {
3455 GstClockTime last_stop_end;
3457 /* Check if this stream is after segment stop */
3458 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop) &&
3459 lace_time >= demux->common.segment.stop) {
3460 GST_DEBUG_OBJECT (demux,
3461 "Stream %d after segment stop %" GST_TIME_FORMAT, stream->index,
3462 GST_TIME_ARGS (demux->common.segment.stop));
3463 gst_buffer_unref (sub);
3466 if (offset >= stream->to_offset
3467 || (GST_CLOCK_TIME_IS_VALID (demux->to_time)
3468 && lace_time > demux->to_time)) {
3469 GST_DEBUG_OBJECT (demux, "Stream %d after playback section",
3471 gst_buffer_unref (sub);
3475 /* handle gaps, e.g. non-zero start-time, or an cue index entry
3476 * that landed us with timestamps not quite intended */
3477 GST_OBJECT_LOCK (demux);
3478 if (demux->max_gap_time &&
3479 GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) &&
3480 demux->common.segment.rate > 0.0) {
3481 GstClockTimeDiff diff;
3483 /* only send segments with increasing start times,
3484 * otherwise if these go back and forth downstream (sinks) increase
3485 * accumulated time and running_time */
3486 diff = GST_CLOCK_DIFF (demux->last_stop_end, lace_time);
3487 if (diff > 0 && diff > demux->max_gap_time
3488 && lace_time > demux->common.segment.start
3489 && (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop)
3490 || lace_time < demux->common.segment.stop)) {
3492 GST_DEBUG_OBJECT (demux,
3493 "Gap of %" G_GINT64_FORMAT " ns detected in"
3494 "stream %d (%" GST_TIME_FORMAT " -> %" GST_TIME_FORMAT "). "
3495 "Sending updated SEGMENT events", diff,
3496 stream->index, GST_TIME_ARGS (stream->pos),
3497 GST_TIME_ARGS (lace_time));
3499 event = gst_event_new_gap (demux->last_stop_end, diff);
3500 GST_OBJECT_UNLOCK (demux);
3501 gst_pad_push_event (stream->pad, event);
3502 GST_OBJECT_LOCK (demux);
3506 if (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.position)
3507 || demux->common.segment.position < lace_time) {
3508 demux->common.segment.position = lace_time;
3510 GST_OBJECT_UNLOCK (demux);
3512 last_stop_end = lace_time;
3514 GST_BUFFER_DURATION (sub) = duration / laces;
3515 last_stop_end += GST_BUFFER_DURATION (sub);
3518 if (!GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) ||
3519 demux->last_stop_end < last_stop_end)
3520 demux->last_stop_end = last_stop_end;
3522 GST_OBJECT_LOCK (demux);
3523 if (demux->common.segment.duration == -1 ||
3524 demux->stream_start_time + demux->common.segment.duration <
3526 demux->common.segment.duration =
3527 last_stop_end - demux->stream_start_time;
3528 GST_OBJECT_UNLOCK (demux);
3529 if (!demux->invalid_duration) {
3530 gst_element_post_message (GST_ELEMENT_CAST (demux),
3531 gst_message_new_duration_changed (GST_OBJECT_CAST (demux)));
3532 demux->invalid_duration = TRUE;
3535 GST_OBJECT_UNLOCK (demux);
3539 stream->pos = lace_time;
3541 gst_matroska_demux_sync_streams (demux);
3543 if (stream->set_discont) {
3544 GST_DEBUG_OBJECT (demux, "marking DISCONT");
3545 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DISCONT);
3546 stream->set_discont = FALSE;
3548 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DISCONT);
3551 /* reverse playback book-keeping */
3552 if (!GST_CLOCK_TIME_IS_VALID (stream->from_time))
3553 stream->from_time = lace_time;
3554 if (stream->from_offset == -1)
3555 stream->from_offset = offset;
3557 GST_DEBUG_OBJECT (demux,
3558 "Pushing lace %d, data of size %" G_GSIZE_FORMAT
3559 " for stream %d, time=%" GST_TIME_FORMAT " and duration=%"
3560 GST_TIME_FORMAT, n, gst_buffer_get_size (sub), stream_num,
3561 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (sub)),
3562 GST_TIME_ARGS (GST_BUFFER_DURATION (sub)));
3565 if (demux->common.element_index) {
3566 if (stream->index_writer_id == -1)
3567 gst_index_get_writer_id (demux->common.element_index,
3568 GST_OBJECT (stream->pad), &stream->index_writer_id);
3570 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
3571 G_GUINT64_FORMAT " for writer id %d",
3572 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (sub)), cluster_offset,
3573 stream->index_writer_id);
3574 gst_index_add_association (demux->common.element_index,
3575 stream->index_writer_id, GST_BUFFER_FLAG_IS_SET (sub,
3576 GST_BUFFER_FLAG_DELTA_UNIT) ? 0 : GST_ASSOCIATION_FLAG_KEY_UNIT,
3577 GST_FORMAT_TIME, GST_BUFFER_TIMESTAMP (sub), GST_FORMAT_BYTES,
3578 cluster_offset, NULL);
3582 /* Postprocess the buffers depending on the codec used */
3583 if (stream->postprocess_frame) {
3584 GST_LOG_OBJECT (demux, "running post process");
3585 ret = stream->postprocess_frame (GST_ELEMENT (demux), stream, &sub);
3588 /* At this point, we have a sub-buffer pointing at data within a larger
3589 buffer. This data might not be aligned with anything. If the data is
3590 raw samples though, we want it aligned to the raw type (eg, 4 bytes
3591 for 32 bit samples, etc), or bad things will happen downstream as
3592 elements typically assume minimal alignment.
3593 Therefore, create an aligned copy if necessary. */
3594 g_assert (stream->alignment <= G_MEM_ALIGN);
3595 sub = gst_matroska_demux_align_buffer (demux, sub, stream->alignment);
3597 if (GST_BUFFER_PTS_IS_VALID (sub)) {
3598 stream->pos = GST_BUFFER_PTS (sub);
3599 if (GST_BUFFER_DURATION_IS_VALID (sub))
3600 stream->pos += GST_BUFFER_DURATION (sub);
3603 ret = gst_pad_push (stream->pad, sub);
3605 if (demux->common.segment.rate < 0) {
3606 if (lace_time > demux->common.segment.stop && ret == GST_FLOW_EOS) {
3607 /* In reverse playback we can get a GST_FLOW_EOS when
3608 * we are at the end of the segment, so we just need to jump
3609 * back to the previous section. */
3610 GST_DEBUG_OBJECT (demux, "downstream has reached end of segment");
3615 ret = gst_flow_combiner_update_flow (demux->flowcombiner, ret);
3618 size -= lace_size[n];
3619 if (lace_time != GST_CLOCK_TIME_NONE && duration)
3620 lace_time += duration / laces;
3622 lace_time = GST_CLOCK_TIME_NONE;
3628 gst_buffer_unmap (buf, &map);
3629 gst_buffer_unref (buf);
3641 ret = gst_flow_combiner_update_flow (demux->flowcombiner, ret);
3646 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Invalid lacing size"));
3647 /* non-fatal, try next block(group) */
3653 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Data error"));
3654 /* non-fatal, try next block(group) */
3660 /* return FALSE if block(group) should be skipped (due to a seek) */
3661 static inline gboolean
3662 gst_matroska_demux_seek_block (GstMatroskaDemux * demux)
3664 if (G_UNLIKELY (demux->seek_block)) {
3665 if (!(--demux->seek_block)) {
3668 GST_LOG_OBJECT (demux, "should skip block due to seek");
3676 static GstFlowReturn
3677 gst_matroska_demux_parse_contents_seekentry (GstMatroskaDemux * demux,
3681 guint64 seek_pos = (guint64) - 1;
3682 guint32 seek_id = 0;
3685 DEBUG_ELEMENT_START (demux, ebml, "Seek");
3687 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3688 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
3692 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3693 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3697 case GST_MATROSKA_ID_SEEKID:
3701 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
3704 GST_DEBUG_OBJECT (demux, "SeekID: %" G_GUINT64_FORMAT, t);
3709 case GST_MATROSKA_ID_SEEKPOSITION:
3713 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
3716 if (t > G_MAXINT64) {
3717 GST_WARNING_OBJECT (demux,
3718 "Too large SeekPosition %" G_GUINT64_FORMAT, t);
3722 GST_DEBUG_OBJECT (demux, "SeekPosition: %" G_GUINT64_FORMAT, t);
3728 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3734 if (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)
3737 if (!seek_id || seek_pos == (guint64) - 1) {
3738 GST_WARNING_OBJECT (demux, "Incomplete seekhead entry (0x%x/%"
3739 G_GUINT64_FORMAT ")", seek_id, seek_pos);
3744 case GST_MATROSKA_ID_SEEKHEAD:
3747 case GST_MATROSKA_ID_CUES:
3748 case GST_MATROSKA_ID_TAGS:
3749 case GST_MATROSKA_ID_TRACKS:
3750 case GST_MATROSKA_ID_SEGMENTINFO:
3751 case GST_MATROSKA_ID_ATTACHMENTS:
3752 case GST_MATROSKA_ID_CHAPTERS:
3754 guint64 before_pos, length;
3758 length = gst_matroska_read_common_get_length (&demux->common);
3759 before_pos = demux->common.offset;
3761 if (length == (guint64) - 1) {
3762 GST_DEBUG_OBJECT (demux, "no upstream length, skipping SeakHead entry");
3766 /* check for validity */
3767 if (seek_pos + demux->common.ebml_segment_start + 12 >= length) {
3768 GST_WARNING_OBJECT (demux,
3769 "SeekHead reference lies outside file!" " (%"
3770 G_GUINT64_FORMAT "+%" G_GUINT64_FORMAT "+12 >= %"
3771 G_GUINT64_FORMAT ")", seek_pos, demux->common.ebml_segment_start,
3776 /* only pick up index location when streaming */
3777 if (demux->streaming) {
3778 if (seek_id == GST_MATROSKA_ID_CUES) {
3779 demux->index_offset = seek_pos + demux->common.ebml_segment_start;
3780 GST_DEBUG_OBJECT (demux, "Cues located at offset %" G_GUINT64_FORMAT,
3781 demux->index_offset);
3787 demux->common.offset = seek_pos + demux->common.ebml_segment_start;
3790 if ((ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
3791 GST_ELEMENT_CAST (demux), &id, &length, &needed)) !=
3795 if (id != seek_id) {
3796 GST_WARNING_OBJECT (demux,
3797 "We looked for ID=0x%x but got ID=0x%x (pos=%" G_GUINT64_FORMAT ")",
3798 seek_id, id, seek_pos + demux->common.ebml_segment_start);
3801 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
3806 demux->common.offset = before_pos;
3810 case GST_MATROSKA_ID_CLUSTER:
3812 guint64 pos = seek_pos + demux->common.ebml_segment_start;
3814 GST_LOG_OBJECT (demux, "Cluster position");
3815 if (G_UNLIKELY (!demux->clusters))
3816 demux->clusters = g_array_sized_new (TRUE, TRUE, sizeof (guint64), 100);
3817 g_array_append_val (demux->clusters, pos);
3822 GST_DEBUG_OBJECT (demux, "Ignoring Seek entry for ID=0x%x", seek_id);
3825 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
3830 static GstFlowReturn
3831 gst_matroska_demux_parse_contents (GstMatroskaDemux * demux, GstEbmlRead * ebml)
3833 GstFlowReturn ret = GST_FLOW_OK;
3836 DEBUG_ELEMENT_START (demux, ebml, "SeekHead");
3838 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3839 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
3843 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3844 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3848 case GST_MATROSKA_ID_SEEKENTRY:
3850 ret = gst_matroska_demux_parse_contents_seekentry (demux, ebml);
3851 /* Ignore EOS and errors here */
3852 if (ret != GST_FLOW_OK) {
3853 GST_DEBUG_OBJECT (demux, "Ignoring %s", gst_flow_get_name (ret));
3860 ret = gst_matroska_read_common_parse_skip (&demux->common,
3861 ebml, "SeekHead", id);
3866 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
3868 /* Sort clusters by position for easier searching */
3869 if (demux->clusters)
3870 g_array_sort (demux->clusters, (GCompareFunc) gst_matroska_cluster_compare);
3875 #define GST_FLOW_OVERFLOW GST_FLOW_CUSTOM_ERROR
3877 #define MAX_BLOCK_SIZE (15 * 1024 * 1024)
3879 static inline GstFlowReturn
3880 gst_matroska_demux_check_read_size (GstMatroskaDemux * demux, guint64 bytes)
3882 if (G_UNLIKELY (bytes > MAX_BLOCK_SIZE)) {
3883 /* only a few blocks are expected/allowed to be large,
3884 * and will be recursed into, whereas others will be read and must fit */
3885 if (demux->streaming) {
3886 /* fatal in streaming case, as we can't step over easily */
3887 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
3888 ("reading large block of size %" G_GUINT64_FORMAT " not supported; "
3889 "file might be corrupt.", bytes));
3890 return GST_FLOW_ERROR;
3892 /* indicate higher level to quietly give up */
3893 GST_DEBUG_OBJECT (demux,
3894 "too large block of size %" G_GUINT64_FORMAT, bytes);
3895 return GST_FLOW_ERROR;
3902 /* returns TRUE if we truely are in error state, and should give up */
3903 static inline GstFlowReturn
3904 gst_matroska_demux_check_parse_error (GstMatroskaDemux * demux)
3906 if (!demux->streaming && demux->next_cluster_offset > 0) {
3907 /* just repositioning to where next cluster should be and try from there */
3908 GST_WARNING_OBJECT (demux, "parse error, trying next cluster expected at %"
3909 G_GUINT64_FORMAT, demux->next_cluster_offset);
3910 demux->common.offset = demux->next_cluster_offset;
3911 demux->next_cluster_offset = 0;
3917 /* sigh, one last attempt above and beyond call of duty ...;
3918 * search for cluster mark following current pos */
3919 pos = demux->common.offset;
3920 GST_WARNING_OBJECT (demux, "parse error, looking for next cluster");
3921 if ((ret = gst_matroska_demux_search_cluster (demux, &pos)) != GST_FLOW_OK) {
3922 /* did not work, give up */
3925 GST_DEBUG_OBJECT (demux, "... found at %" G_GUINT64_FORMAT, pos);
3926 /* try that position */
3927 demux->common.offset = pos;
3933 static inline GstFlowReturn
3934 gst_matroska_demux_flush (GstMatroskaDemux * demux, guint flush)
3936 GST_LOG_OBJECT (demux, "skipping %d bytes", flush);
3937 demux->common.offset += flush;
3938 if (demux->streaming) {
3941 /* hard to skip large blocks when streaming */
3942 ret = gst_matroska_demux_check_read_size (demux, flush);
3943 if (ret != GST_FLOW_OK)
3945 if (flush <= gst_adapter_available (demux->common.adapter))
3946 gst_adapter_flush (demux->common.adapter, flush);
3948 return GST_FLOW_EOS;
3953 /* initializes @ebml with @bytes from input stream at current offset.
3954 * Returns EOS if insufficient available,
3955 * ERROR if too much was attempted to read. */
3956 static inline GstFlowReturn
3957 gst_matroska_demux_take (GstMatroskaDemux * demux, guint64 bytes,
3960 GstBuffer *buffer = NULL;
3961 GstFlowReturn ret = GST_FLOW_OK;
3963 GST_LOG_OBJECT (demux, "taking %" G_GUINT64_FORMAT " bytes for parsing",
3965 ret = gst_matroska_demux_check_read_size (demux, bytes);
3966 if (G_UNLIKELY (ret != GST_FLOW_OK)) {
3967 if (!demux->streaming) {
3968 /* in pull mode, we can skip */
3969 if ((ret = gst_matroska_demux_flush (demux, bytes)) == GST_FLOW_OK)
3970 ret = GST_FLOW_OVERFLOW;
3972 /* otherwise fatal */
3973 ret = GST_FLOW_ERROR;
3977 if (demux->streaming) {
3978 if (gst_adapter_available (demux->common.adapter) >= bytes)
3979 buffer = gst_adapter_take_buffer (demux->common.adapter, bytes);
3983 ret = gst_matroska_read_common_peek_bytes (&demux->common,
3984 demux->common.offset, bytes, &buffer, NULL);
3985 if (G_LIKELY (buffer)) {
3986 gst_ebml_read_init (ebml, GST_ELEMENT_CAST (demux), buffer,
3987 demux->common.offset);
3988 demux->common.offset += bytes;
3995 gst_matroska_demux_check_seekability (GstMatroskaDemux * demux)
3998 gboolean seekable = FALSE;
3999 gint64 start = -1, stop = -1;
4001 query = gst_query_new_seeking (GST_FORMAT_BYTES);
4002 if (!gst_pad_peer_query (demux->common.sinkpad, query)) {
4003 GST_DEBUG_OBJECT (demux, "seeking query failed");
4007 gst_query_parse_seeking (query, NULL, &seekable, &start, &stop);
4009 /* try harder to query upstream size if we didn't get it the first time */
4010 if (seekable && stop == -1) {
4011 GST_DEBUG_OBJECT (demux, "doing duration query to fix up unset stop");
4012 gst_pad_peer_query_duration (demux->common.sinkpad, GST_FORMAT_BYTES,
4016 /* if upstream doesn't know the size, it's likely that it's not seekable in
4017 * practice even if it technically may be seekable */
4018 if (seekable && (start != 0 || stop <= start)) {
4019 GST_DEBUG_OBJECT (demux, "seekable but unknown start/stop -> disable");
4024 GST_INFO_OBJECT (demux, "seekable: %d (%" G_GUINT64_FORMAT " - %"
4025 G_GUINT64_FORMAT ")", seekable, start, stop);
4026 demux->seekable = seekable;
4028 gst_query_unref (query);
4031 static GstFlowReturn
4032 gst_matroska_demux_find_tracks (GstMatroskaDemux * demux)
4038 GstFlowReturn ret = GST_FLOW_OK;
4040 GST_WARNING_OBJECT (demux,
4041 "Found Cluster element before Tracks, searching Tracks");
4044 before_pos = demux->common.offset;
4046 /* Search Tracks element */
4048 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4049 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4050 if (ret != GST_FLOW_OK)
4053 if (id != GST_MATROSKA_ID_TRACKS) {
4054 /* we may be skipping large cluster here, so forego size check etc */
4055 /* ... but we can't skip undefined size; force error */
4056 if (length == G_MAXUINT64) {
4057 ret = gst_matroska_demux_check_read_size (demux, length);
4060 demux->common.offset += needed;
4061 demux->common.offset += length;
4066 /* will lead to track parsing ... */
4067 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4072 demux->common.offset = before_pos;
4077 #define GST_READ_CHECK(stmt) \
4079 if (G_UNLIKELY ((ret = (stmt)) != GST_FLOW_OK)) { \
4080 if (ret == GST_FLOW_OVERFLOW) { \
4081 ret = GST_FLOW_OK; \
4087 static GstFlowReturn
4088 gst_matroska_demux_parse_id (GstMatroskaDemux * demux, guint32 id,
4089 guint64 length, guint needed)
4091 GstEbmlRead ebml = { 0, };
4092 GstFlowReturn ret = GST_FLOW_OK;
4095 GST_LOG_OBJECT (demux, "Parsing Element id 0x%x, "
4096 "size %" G_GUINT64_FORMAT ", prefix %d", id, length, needed);
4098 /* if we plan to read and parse this element, we need prefix (id + length)
4099 * and the contents */
4100 /* mind about overflow wrap-around when dealing with undefined size */
4102 if (G_LIKELY (length != G_MAXUINT64))
4105 switch (demux->common.state) {
4106 case GST_MATROSKA_READ_STATE_START:
4108 case GST_EBML_ID_HEADER:
4109 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4110 ret = gst_matroska_read_common_parse_header (&demux->common, &ebml);
4111 if (ret != GST_FLOW_OK)
4113 demux->common.state = GST_MATROSKA_READ_STATE_SEGMENT;
4114 gst_matroska_demux_check_seekability (demux);
4117 goto invalid_header;
4121 case GST_MATROSKA_READ_STATE_SEGMENT:
4123 case GST_MATROSKA_ID_SEGMENT:
4124 /* eat segment prefix */
4125 GST_READ_CHECK (gst_matroska_demux_flush (demux, needed));
4126 GST_DEBUG_OBJECT (demux,
4127 "Found Segment start at offset %" G_GUINT64_FORMAT " with size %"
4128 G_GUINT64_FORMAT, demux->common.offset, length);
4129 /* seeks are from the beginning of the segment,
4130 * after the segment ID/length */
4131 demux->common.ebml_segment_start = demux->common.offset;
4133 length = G_MAXUINT64;
4134 demux->common.ebml_segment_length = length;
4135 demux->common.state = GST_MATROSKA_READ_STATE_HEADER;
4138 GST_WARNING_OBJECT (demux,
4139 "Expected a Segment ID (0x%x), but received 0x%x!",
4140 GST_MATROSKA_ID_SEGMENT, id);
4141 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4145 case GST_MATROSKA_READ_STATE_SCANNING:
4146 if (id != GST_MATROSKA_ID_CLUSTER &&
4147 id != GST_MATROSKA_ID_CLUSTERTIMECODE)
4150 case GST_MATROSKA_READ_STATE_HEADER:
4151 case GST_MATROSKA_READ_STATE_DATA:
4152 case GST_MATROSKA_READ_STATE_SEEK:
4154 case GST_MATROSKA_ID_SEGMENTINFO:
4155 if (!demux->common.segmentinfo_parsed) {
4156 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4157 ret = gst_matroska_read_common_parse_info (&demux->common,
4158 GST_ELEMENT_CAST (demux), &ebml);
4160 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4163 case GST_MATROSKA_ID_TRACKS:
4164 if (!demux->tracks_parsed) {
4165 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4166 ret = gst_matroska_demux_parse_tracks (demux, &ebml);
4168 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4171 case GST_MATROSKA_ID_CLUSTER:
4172 if (G_UNLIKELY (!demux->tracks_parsed)) {
4173 if (demux->streaming) {
4174 GST_DEBUG_OBJECT (demux, "Cluster before Track");
4175 goto not_streamable;
4177 ret = gst_matroska_demux_find_tracks (demux);
4178 if (!demux->tracks_parsed)
4182 if (G_UNLIKELY (demux->common.state
4183 == GST_MATROSKA_READ_STATE_HEADER)) {
4184 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
4185 demux->first_cluster_offset = demux->common.offset;
4186 GST_DEBUG_OBJECT (demux, "signaling no more pads");
4187 gst_element_no_more_pads (GST_ELEMENT (demux));
4188 /* send initial segment - we wait till we know the first
4189 incoming timestamp, so we can properly set the start of
4191 demux->need_segment = TRUE;
4193 demux->cluster_time = GST_CLOCK_TIME_NONE;
4194 demux->cluster_offset = demux->common.offset;
4195 if (G_UNLIKELY (!demux->seek_first && demux->seek_block)) {
4196 GST_DEBUG_OBJECT (demux, "seek target block %" G_GUINT64_FORMAT
4197 " not found in Cluster, trying next Cluster's first block instead",
4199 demux->seek_block = 0;
4201 demux->seek_first = FALSE;
4202 /* record next cluster for recovery */
4203 if (read != G_MAXUINT64)
4204 demux->next_cluster_offset = demux->cluster_offset + read;
4205 /* eat cluster prefix */
4206 gst_matroska_demux_flush (demux, needed);
4208 case GST_MATROSKA_ID_CLUSTERTIMECODE:
4212 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4213 if ((ret = gst_ebml_read_uint (&ebml, &id, &num)) != GST_FLOW_OK)
4215 GST_DEBUG_OBJECT (demux, "ClusterTimeCode: %" G_GUINT64_FORMAT, num);
4216 demux->cluster_time = num;
4218 if (demux->common.element_index) {
4219 if (demux->common.element_index_writer_id == -1)
4220 gst_index_get_writer_id (demux->common.element_index,
4221 GST_OBJECT (demux), &demux->common.element_index_writer_id);
4222 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
4223 G_GUINT64_FORMAT " for writer id %d",
4224 GST_TIME_ARGS (demux->cluster_time), demux->cluster_offset,
4225 demux->common.element_index_writer_id);
4226 gst_index_add_association (demux->common.element_index,
4227 demux->common.element_index_writer_id,
4228 GST_ASSOCIATION_FLAG_KEY_UNIT,
4229 GST_FORMAT_TIME, demux->cluster_time,
4230 GST_FORMAT_BYTES, demux->cluster_offset, NULL);
4235 case GST_MATROSKA_ID_BLOCKGROUP:
4236 if (!gst_matroska_demux_seek_block (demux))
4238 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4239 DEBUG_ELEMENT_START (demux, &ebml, "BlockGroup");
4240 if ((ret = gst_ebml_read_master (&ebml, &id)) == GST_FLOW_OK) {
4241 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4242 &ebml, demux->cluster_time, demux->cluster_offset, FALSE);
4244 DEBUG_ELEMENT_STOP (demux, &ebml, "BlockGroup", ret);
4246 case GST_MATROSKA_ID_SIMPLEBLOCK:
4247 if (!gst_matroska_demux_seek_block (demux))
4249 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4250 DEBUG_ELEMENT_START (demux, &ebml, "SimpleBlock");
4251 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4252 &ebml, demux->cluster_time, demux->cluster_offset, TRUE);
4253 DEBUG_ELEMENT_STOP (demux, &ebml, "SimpleBlock", ret);
4255 case GST_MATROSKA_ID_ATTACHMENTS:
4256 if (!demux->common.attachments_parsed) {
4257 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4258 ret = gst_matroska_read_common_parse_attachments (&demux->common,
4259 GST_ELEMENT_CAST (demux), &ebml);
4261 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4264 case GST_MATROSKA_ID_TAGS:
4265 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4266 ret = gst_matroska_read_common_parse_metadata (&demux->common,
4267 GST_ELEMENT_CAST (demux), &ebml);
4269 case GST_MATROSKA_ID_CHAPTERS:
4270 if (!demux->common.chapters_parsed) {
4271 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4273 gst_matroska_read_common_parse_chapters (&demux->common, &ebml);
4275 if (demux->common.toc) {
4276 gst_matroska_demux_send_event (demux,
4277 gst_event_new_toc (demux->common.toc, FALSE));
4280 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4282 case GST_MATROSKA_ID_SEEKHEAD:
4283 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4284 ret = gst_matroska_demux_parse_contents (demux, &ebml);
4286 case GST_MATROSKA_ID_CUES:
4287 if (demux->common.index_parsed) {
4288 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4291 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4292 ret = gst_matroska_read_common_parse_index (&demux->common, &ebml);
4293 /* only push based; delayed index building */
4294 if (ret == GST_FLOW_OK
4295 && demux->common.state == GST_MATROSKA_READ_STATE_SEEK) {
4298 GST_OBJECT_LOCK (demux);
4299 event = demux->seek_event;
4300 demux->seek_event = NULL;
4301 GST_OBJECT_UNLOCK (demux);
4304 /* unlikely to fail, since we managed to seek to this point */
4305 if (!gst_matroska_demux_handle_seek_event (demux, NULL, event))
4307 /* resume data handling, main thread clear to seek again */
4308 GST_OBJECT_LOCK (demux);
4309 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
4310 GST_OBJECT_UNLOCK (demux);
4313 case GST_MATROSKA_ID_POSITION:
4314 case GST_MATROSKA_ID_PREVSIZE:
4315 case GST_MATROSKA_ID_ENCRYPTEDBLOCK:
4316 case GST_MATROSKA_ID_SILENTTRACKS:
4317 GST_DEBUG_OBJECT (demux,
4318 "Skipping Cluster subelement 0x%x - ignoring", id);
4322 GST_DEBUG_OBJECT (demux, "skipping Element 0x%x", id);
4323 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4329 if (ret == GST_FLOW_PARSE)
4333 gst_ebml_read_clear (&ebml);
4339 /* simply exit, maybe not enough data yet */
4340 /* no ebml to clear if read error */
4345 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4346 ("Failed to parse Element 0x%x", id));
4347 ret = GST_FLOW_ERROR;
4352 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4353 ("File layout does not permit streaming"));
4354 ret = GST_FLOW_ERROR;
4359 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4360 ("No Tracks element found"));
4361 ret = GST_FLOW_ERROR;
4366 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Invalid header"));
4367 ret = GST_FLOW_ERROR;
4372 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Failed to seek"));
4373 ret = GST_FLOW_ERROR;
4379 gst_matroska_demux_loop (GstPad * pad)
4381 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (pad));
4387 /* If we have to close a segment, send a new segment to do this now */
4388 if (G_LIKELY (demux->common.state == GST_MATROSKA_READ_STATE_DATA)) {
4389 if (G_UNLIKELY (demux->new_segment)) {
4390 gst_matroska_demux_send_event (demux, demux->new_segment);
4391 demux->new_segment = NULL;
4395 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4396 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4397 if (ret == GST_FLOW_EOS) {
4399 } else if (ret == GST_FLOW_FLUSHING) {
4401 } else if (ret != GST_FLOW_OK) {
4402 ret = gst_matroska_demux_check_parse_error (demux);
4404 /* Only handle EOS as no error if we're outside the segment already */
4405 if (ret == GST_FLOW_EOS && (demux->common.ebml_segment_length != G_MAXUINT64
4406 && demux->common.offset >=
4407 demux->common.ebml_segment_start +
4408 demux->common.ebml_segment_length))
4410 else if (ret != GST_FLOW_OK)
4416 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
4417 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
4420 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4421 if (ret == GST_FLOW_EOS)
4423 if (ret != GST_FLOW_OK)
4426 /* check if we're at the end of a configured segment */
4427 if (G_LIKELY (demux->common.src->len)) {
4430 g_assert (demux->common.num_streams == demux->common.src->len);
4431 for (i = 0; i < demux->common.src->len; i++) {
4432 GstMatroskaTrackContext *context = g_ptr_array_index (demux->common.src,
4434 GST_DEBUG_OBJECT (context->pad, "pos %" GST_TIME_FORMAT,
4435 GST_TIME_ARGS (context->pos));
4436 if (context->eos == FALSE)
4440 GST_INFO_OBJECT (demux, "All streams are EOS");
4446 if (G_UNLIKELY (demux->cached_length == G_MAXUINT64 ||
4447 demux->common.offset >= demux->cached_length)) {
4448 demux->cached_length = gst_matroska_read_common_get_length (&demux->common);
4449 if (demux->common.offset == demux->cached_length) {
4450 GST_LOG_OBJECT (demux, "Reached end of stream");
4461 if (demux->common.segment.rate < 0.0) {
4462 ret = gst_matroska_demux_seek_to_previous_keyframe (demux);
4463 if (ret == GST_FLOW_OK)
4470 const gchar *reason = gst_flow_get_name (ret);
4471 gboolean push_eos = FALSE;
4473 GST_LOG_OBJECT (demux, "pausing task, reason %s", reason);
4474 gst_pad_pause_task (demux->common.sinkpad);
4476 if (ret == GST_FLOW_EOS) {
4477 /* perform EOS logic */
4479 /* If we were in the headers, make sure we send no-more-pads.
4480 This will ensure decodebin2 does not get stuck thinking
4481 the chain is not complete yet, and waiting indefinitely. */
4482 if (G_UNLIKELY (demux->common.state == GST_MATROSKA_READ_STATE_HEADER)) {
4483 if (demux->common.src->len == 0) {
4484 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
4485 ("No pads created"));
4487 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL),
4488 ("Failed to finish reading headers"));
4490 gst_element_no_more_pads (GST_ELEMENT (demux));
4493 if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
4496 /* for segment playback we need to post when (in stream time)
4497 * we stopped, this is either stop (when set) or the duration. */
4498 if ((stop = demux->common.segment.stop) == -1)
4499 stop = demux->last_stop_end;
4501 GST_LOG_OBJECT (demux, "Sending segment done, at end of segment");
4502 gst_element_post_message (GST_ELEMENT (demux),
4503 gst_message_new_segment_done (GST_OBJECT (demux), GST_FORMAT_TIME,
4505 gst_matroska_demux_send_event (demux,
4506 gst_event_new_segment_done (GST_FORMAT_TIME, stop));
4510 } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS) {
4511 /* for fatal errors we post an error message */
4512 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
4513 ("stream stopped, reason %s", reason));
4517 /* send EOS, and prevent hanging if no streams yet */
4518 GST_LOG_OBJECT (demux, "Sending EOS, at end of stream");
4519 if (!gst_matroska_demux_send_event (demux, gst_event_new_eos ()) &&
4520 (ret == GST_FLOW_EOS)) {
4521 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4522 (NULL), ("got eos but no streams (yet)"));
4530 * Create and push a flushing seek event upstream
4533 perform_seek_to_offset (GstMatroskaDemux * demux, gdouble rate, guint64 offset,
4539 GST_DEBUG_OBJECT (demux, "Seeking to %" G_GUINT64_FORMAT, offset);
4542 gst_event_new_seek (rate, GST_FORMAT_BYTES,
4543 GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, GST_SEEK_TYPE_SET, offset,
4544 GST_SEEK_TYPE_NONE, -1);
4545 gst_event_set_seqnum (event, seqnum);
4547 res = gst_pad_push_event (demux->common.sinkpad, event);
4549 /* segment event will update offset */
4553 static GstFlowReturn
4554 gst_matroska_demux_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
4556 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4558 GstFlowReturn ret = GST_FLOW_OK;
4563 if (G_UNLIKELY (GST_BUFFER_IS_DISCONT (buffer))) {
4564 GST_DEBUG_OBJECT (demux, "got DISCONT");
4565 gst_adapter_clear (demux->common.adapter);
4566 GST_OBJECT_LOCK (demux);
4567 gst_matroska_read_common_reset_streams (&demux->common,
4568 GST_CLOCK_TIME_NONE, FALSE);
4569 GST_OBJECT_UNLOCK (demux);
4572 gst_adapter_push (demux->common.adapter, buffer);
4576 available = gst_adapter_available (demux->common.adapter);
4578 ret = gst_matroska_read_common_peek_id_length_push (&demux->common,
4579 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4580 if (G_UNLIKELY (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)) {
4581 if (demux->common.ebml_segment_length != G_MAXUINT64
4582 && demux->common.offset >=
4583 demux->common.ebml_segment_start + demux->common.ebml_segment_length)
4588 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
4589 "size %" G_GUINT64_FORMAT ", needed %d, available %d",
4590 demux->common.offset, id, length, needed, available);
4592 if (needed > available)
4595 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4596 if (ret == GST_FLOW_EOS) {
4597 /* need more data */
4599 } else if (ret != GST_FLOW_OK) {
4606 gst_matroska_demux_handle_sink_event (GstPad * pad, GstObject * parent,
4609 gboolean res = TRUE;
4610 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4612 GST_DEBUG_OBJECT (demux,
4613 "have event type %s: %p on sink pad", GST_EVENT_TYPE_NAME (event), event);
4615 switch (GST_EVENT_TYPE (event)) {
4616 case GST_EVENT_SEGMENT:
4618 const GstSegment *segment;
4620 /* some debug output */
4621 gst_event_parse_segment (event, &segment);
4622 /* FIXME: do we need to update segment base here (like accum in 0.10)? */
4623 GST_DEBUG_OBJECT (demux,
4624 "received format %d segment %" GST_SEGMENT_FORMAT, segment->format,
4627 if (demux->common.state < GST_MATROSKA_READ_STATE_DATA) {
4628 GST_DEBUG_OBJECT (demux, "still starting");
4632 /* we only expect a BYTE segment, e.g. following a seek */
4633 if (segment->format != GST_FORMAT_BYTES) {
4634 GST_DEBUG_OBJECT (demux, "unsupported segment format, ignoring");
4638 GST_DEBUG_OBJECT (demux, "clearing segment state");
4639 GST_OBJECT_LOCK (demux);
4640 /* clear current segment leftover */
4641 gst_adapter_clear (demux->common.adapter);
4642 /* and some streaming setup */
4643 demux->common.offset = segment->start;
4644 /* accumulate base based on current position */
4645 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.position))
4646 demux->common.segment.base +=
4647 (MAX (demux->common.segment.position, demux->stream_start_time)
4648 - demux->stream_start_time) / fabs (demux->common.segment.rate);
4649 /* do not know where we are;
4650 * need to come across a cluster and generate segment */
4651 demux->common.segment.position = GST_CLOCK_TIME_NONE;
4652 demux->cluster_time = GST_CLOCK_TIME_NONE;
4653 demux->cluster_offset = 0;
4654 demux->need_segment = TRUE;
4655 demux->segment_seqnum = gst_event_get_seqnum (event);
4656 /* but keep some of the upstream segment */
4657 demux->common.segment.rate = segment->rate;
4658 /* also check if need to keep some of the requested seek position */
4659 if (demux->seek_offset == segment->start) {
4660 GST_DEBUG_OBJECT (demux, "position matches requested seek");
4661 demux->common.segment.position = demux->requested_seek_time;
4663 GST_DEBUG_OBJECT (demux, "unexpected segment position");
4665 demux->requested_seek_time = GST_CLOCK_TIME_NONE;
4666 demux->seek_offset = -1;
4667 GST_OBJECT_UNLOCK (demux);
4669 /* chain will send initial segment after pads have been added,
4670 * or otherwise come up with one */
4671 GST_DEBUG_OBJECT (demux, "eating event");
4672 gst_event_unref (event);
4678 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
4679 gst_event_unref (event);
4680 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4681 (NULL), ("got eos and didn't receive a complete header object"));
4682 } else if (demux->common.num_streams == 0) {
4683 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4684 (NULL), ("got eos but no streams (yet)"));
4686 gst_matroska_demux_send_event (demux, event);
4690 case GST_EVENT_FLUSH_STOP:
4694 gst_adapter_clear (demux->common.adapter);
4695 GST_OBJECT_LOCK (demux);
4696 gst_matroska_read_common_reset_streams (&demux->common,
4697 GST_CLOCK_TIME_NONE, TRUE);
4698 dur = demux->common.segment.duration;
4699 gst_segment_init (&demux->common.segment, GST_FORMAT_TIME);
4700 demux->common.segment.duration = dur;
4701 demux->cluster_time = GST_CLOCK_TIME_NONE;
4702 demux->cluster_offset = 0;
4703 GST_OBJECT_UNLOCK (demux);
4707 res = gst_pad_event_default (pad, parent, event);
4715 gst_matroska_demux_sink_activate (GstPad * sinkpad, GstObject * parent)
4717 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4719 gboolean pull_mode = FALSE;
4721 query = gst_query_new_scheduling ();
4723 if (gst_pad_peer_query (sinkpad, query))
4724 pull_mode = gst_query_has_scheduling_mode_with_flags (query,
4725 GST_PAD_MODE_PULL, GST_SCHEDULING_FLAG_SEEKABLE);
4727 gst_query_unref (query);
4730 GST_DEBUG ("going to pull mode");
4731 demux->streaming = FALSE;
4732 return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PULL, TRUE);
4734 GST_DEBUG ("going to push (streaming) mode");
4735 demux->streaming = TRUE;
4736 return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PUSH, TRUE);
4741 gst_matroska_demux_sink_activate_mode (GstPad * sinkpad, GstObject * parent,
4742 GstPadMode mode, gboolean active)
4745 case GST_PAD_MODE_PULL:
4747 /* if we have a scheduler we can start the task */
4748 gst_pad_start_task (sinkpad, (GstTaskFunction) gst_matroska_demux_loop,
4751 gst_pad_stop_task (sinkpad);
4754 case GST_PAD_MODE_PUSH:
4762 gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext *
4763 videocontext, const gchar * codec_id, guint8 * data, guint size,
4764 gchar ** codec_name, guint32 * riff_fourcc)
4766 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) videocontext;
4767 GstCaps *caps = NULL;
4769 g_assert (videocontext != NULL);
4770 g_assert (codec_name != NULL);
4775 /* TODO: check if we have all codec types from matroska-ids.h
4776 * check if we have to do more special things with codec_private
4779 * GST_MATROSKA_CODEC_ID_VIDEO_QUICKTIME
4780 * GST_MATROSKA_CODEC_ID_VIDEO_SNOW
4783 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VFW_FOURCC)) {
4784 gst_riff_strf_vids *vids = NULL;
4787 GstBuffer *buf = NULL;
4789 vids = (gst_riff_strf_vids *) data;
4791 /* assure size is big enough */
4793 GST_WARNING ("Too small BITMAPINFOHEADER (%d bytes)", size);
4796 if (size < sizeof (gst_riff_strf_vids)) {
4797 vids = g_new (gst_riff_strf_vids, 1);
4798 memcpy (vids, data, size);
4801 /* little-endian -> byte-order */
4802 vids->size = GUINT32_FROM_LE (vids->size);
4803 vids->width = GUINT32_FROM_LE (vids->width);
4804 vids->height = GUINT32_FROM_LE (vids->height);
4805 vids->planes = GUINT16_FROM_LE (vids->planes);
4806 vids->bit_cnt = GUINT16_FROM_LE (vids->bit_cnt);
4807 vids->compression = GUINT32_FROM_LE (vids->compression);
4808 vids->image_size = GUINT32_FROM_LE (vids->image_size);
4809 vids->xpels_meter = GUINT32_FROM_LE (vids->xpels_meter);
4810 vids->ypels_meter = GUINT32_FROM_LE (vids->ypels_meter);
4811 vids->num_colors = GUINT32_FROM_LE (vids->num_colors);
4812 vids->imp_colors = GUINT32_FROM_LE (vids->imp_colors);
4814 if (size > sizeof (gst_riff_strf_vids)) { /* some extra_data */
4815 gsize offset = sizeof (gst_riff_strf_vids);
4818 gst_buffer_new_wrapped (g_memdup ((guint8 *) vids + offset,
4819 size - offset), size - offset);
4823 *riff_fourcc = vids->compression;
4825 caps = gst_riff_create_video_caps (vids->compression, NULL, vids,
4826 buf, NULL, codec_name);
4829 GST_WARNING ("Unhandled RIFF fourcc %" GST_FOURCC_FORMAT,
4830 GST_FOURCC_ARGS (vids->compression));
4834 gst_buffer_unref (buf);
4836 if (vids != (gst_riff_strf_vids *) data)
4839 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_UNCOMPRESSED)) {
4841 GstVideoFormat format;
4843 gst_video_info_init (&info);
4844 switch (videocontext->fourcc) {
4845 case GST_MAKE_FOURCC ('I', '4', '2', '0'):
4846 format = GST_VIDEO_FORMAT_I420;
4848 case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
4849 format = GST_VIDEO_FORMAT_YUY2;
4851 case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
4852 format = GST_VIDEO_FORMAT_YV12;
4854 case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
4855 format = GST_VIDEO_FORMAT_UYVY;
4857 case GST_MAKE_FOURCC ('A', 'Y', 'U', 'V'):
4858 format = GST_VIDEO_FORMAT_AYUV;
4860 case GST_MAKE_FOURCC ('Y', '8', '0', '0'):
4861 case GST_MAKE_FOURCC ('Y', '8', ' ', ' '):
4862 format = GST_VIDEO_FORMAT_GRAY8;
4864 case GST_MAKE_FOURCC ('R', 'G', 'B', 24):
4865 format = GST_VIDEO_FORMAT_RGB;
4867 case GST_MAKE_FOURCC ('B', 'G', 'R', 24):
4868 format = GST_VIDEO_FORMAT_BGR;
4871 GST_DEBUG ("Unknown fourcc %" GST_FOURCC_FORMAT,
4872 GST_FOURCC_ARGS (videocontext->fourcc));
4876 gst_video_info_set_format (&info, format, videocontext->pixel_width,
4877 videocontext->pixel_height);
4878 caps = gst_video_info_to_caps (&info);
4879 *codec_name = gst_pb_utils_get_codec_description (caps);
4880 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_SP)) {
4881 caps = gst_caps_new_simple ("video/x-divx",
4882 "divxversion", G_TYPE_INT, 4, NULL);
4883 *codec_name = g_strdup ("MPEG-4 simple profile");
4884 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP) ||
4885 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AP)) {
4886 caps = gst_caps_new_simple ("video/mpeg",
4887 "mpegversion", G_TYPE_INT, 4,
4888 "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
4892 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
4893 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
4894 gst_buffer_unref (priv);
4896 gst_codec_utils_mpeg4video_caps_set_level_and_profile (caps, data, size);
4898 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP))
4899 *codec_name = g_strdup ("MPEG-4 advanced simple profile");
4901 *codec_name = g_strdup ("MPEG-4 advanced profile");
4902 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MSMPEG4V3)) {
4904 caps = gst_caps_new_full (gst_structure_new ("video/x-divx",
4905 "divxversion", G_TYPE_INT, 3, NULL),
4906 gst_structure_new ("video/x-msmpeg",
4907 "msmpegversion", G_TYPE_INT, 43, NULL), NULL);
4909 caps = gst_caps_new_simple ("video/x-msmpeg",
4910 "msmpegversion", G_TYPE_INT, 43, NULL);
4911 *codec_name = g_strdup ("Microsoft MPEG-4 v.3");
4912 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1) ||
4913 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG2)) {
4916 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1))
4921 caps = gst_caps_new_simple ("video/mpeg",
4922 "systemstream", G_TYPE_BOOLEAN, FALSE,
4923 "mpegversion", G_TYPE_INT, mpegversion, NULL);
4924 *codec_name = g_strdup_printf ("MPEG-%d video", mpegversion);
4925 context->postprocess_frame = gst_matroska_demux_add_mpeg_seq_header;
4926 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MJPEG)) {
4927 caps = gst_caps_new_empty_simple ("image/jpeg");
4928 *codec_name = g_strdup ("Motion-JPEG");
4929 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AVC)) {
4930 caps = gst_caps_new_empty_simple ("video/x-h264");
4934 /* First byte is the version, second is the profile indication, and third
4935 * is the 5 contraint_set_flags and 3 reserved bits. Fourth byte is the
4936 * level indication. */
4937 gst_codec_utils_h264_caps_set_level_and_profile (caps, data + 1,
4940 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
4941 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
4942 gst_buffer_unref (priv);
4944 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "avc",
4945 "alignment", G_TYPE_STRING, "au", NULL);
4947 GST_WARNING ("No codec data found, assuming output is byte-stream");
4948 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
4951 *codec_name = g_strdup ("H264");
4952 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEGH_HEVC)) {
4953 caps = gst_caps_new_empty_simple ("video/x-h265");
4957 gst_codec_utils_h265_caps_set_level_tier_and_profile (caps, data + 1,
4960 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
4961 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
4962 gst_buffer_unref (priv);
4964 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "hvc1",
4965 "alignment", G_TYPE_STRING, "au", NULL);
4967 GST_WARNING ("No codec data found, assuming output is byte-stream");
4968 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
4971 *codec_name = g_strdup ("HEVC");
4972 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1)) ||
4973 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2)) ||
4974 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3)) ||
4975 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))) {
4976 gint rmversion = -1;
4978 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1))
4980 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2))
4982 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3))
4984 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))
4987 caps = gst_caps_new_simple ("video/x-pn-realvideo",
4988 "rmversion", G_TYPE_INT, rmversion, NULL);
4989 GST_DEBUG ("data:%p, size:0x%x", data, size);
4990 /* We need to extract the extradata ! */
4991 if (data && (size >= 0x22)) {
4996 subformat = GST_READ_UINT32_BE (data + 0x1a);
4997 rformat = GST_READ_UINT32_BE (data + 0x1e);
5000 gst_buffer_new_wrapped (g_memdup (data + 0x1a, size - 0x1a),
5002 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, "format",
5003 G_TYPE_INT, rformat, "subformat", G_TYPE_INT, subformat, NULL);
5004 gst_buffer_unref (priv);
5007 *codec_name = g_strdup_printf ("RealVideo %d.0", rmversion);
5008 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_THEORA)) {
5009 caps = gst_caps_new_empty_simple ("video/x-theora");
5010 context->stream_headers =
5011 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
5012 context->codec_priv_size);
5013 /* FIXME: mark stream as broken and skip if there are no stream headers */
5014 context->send_stream_headers = TRUE;
5015 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_DIRAC)) {
5016 caps = gst_caps_new_empty_simple ("video/x-dirac");
5017 *codec_name = g_strdup_printf ("Dirac");
5018 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8)) {
5019 caps = gst_caps_new_empty_simple ("video/x-vp8");
5020 *codec_name = g_strdup_printf ("On2 VP8");
5021 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP9)) {
5022 caps = gst_caps_new_empty_simple ("video/x-vp9");
5023 *codec_name = g_strdup_printf ("On2 VP9");
5025 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
5031 GstStructure *structure;
5033 for (i = 0; i < gst_caps_get_size (caps); i++) {
5034 structure = gst_caps_get_structure (caps, i);
5036 /* FIXME: use the real unit here! */
5037 GST_DEBUG ("video size %dx%d, target display size %dx%d (any unit)",
5038 videocontext->pixel_width,
5039 videocontext->pixel_height,
5040 videocontext->display_width, videocontext->display_height);
5042 /* pixel width and height are the w and h of the video in pixels */
5043 if (videocontext->pixel_width > 0 && videocontext->pixel_height > 0) {
5044 gint w = videocontext->pixel_width;
5045 gint h = videocontext->pixel_height;
5047 gst_structure_set (structure,
5048 "width", G_TYPE_INT, w, "height", G_TYPE_INT, h, NULL);
5051 if (videocontext->display_width > 0 || videocontext->display_height > 0) {
5054 if (videocontext->display_width <= 0)
5055 videocontext->display_width = videocontext->pixel_width;
5056 if (videocontext->display_height <= 0)
5057 videocontext->display_height = videocontext->pixel_height;
5059 /* calculate the pixel aspect ratio using the display and pixel w/h */
5060 n = videocontext->display_width * videocontext->pixel_height;
5061 d = videocontext->display_height * videocontext->pixel_width;
5062 GST_DEBUG ("setting PAR to %d/%d", n, d);
5063 gst_structure_set (structure, "pixel-aspect-ratio",
5065 videocontext->display_width * videocontext->pixel_height,
5066 videocontext->display_height * videocontext->pixel_width, NULL);
5069 if (videocontext->default_fps > 0.0) {
5072 gst_util_double_to_fraction (videocontext->default_fps, &fps_n, &fps_d);
5074 GST_DEBUG ("using default fps %d/%d", fps_n, fps_d);
5076 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION, fps_n,
5078 } else if (context->default_duration > 0) {
5081 gst_video_guess_framerate (context->default_duration, &fps_n, &fps_d);
5083 GST_INFO ("using default duration %" G_GUINT64_FORMAT
5084 " framerate %d/%d", context->default_duration, fps_n, fps_d);
5086 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
5087 fps_n, fps_d, NULL);
5089 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
5093 if (videocontext->parent.flags & GST_MATROSKA_VIDEOTRACK_INTERLACED)
5094 gst_structure_set (structure, "interlace-mode", G_TYPE_STRING,
5098 caps = gst_caps_simplify (caps);
5105 * Some AAC specific code... *sigh*
5106 * FIXME: maybe we should use '15' and code the sample rate explicitly
5107 * if the sample rate doesn't match the predefined rates exactly? (tpm)
5111 aac_rate_idx (gint rate)
5115 else if (75132 <= rate)
5117 else if (55426 <= rate)
5119 else if (46009 <= rate)
5121 else if (37566 <= rate)
5123 else if (27713 <= rate)
5125 else if (23004 <= rate)
5127 else if (18783 <= rate)
5129 else if (13856 <= rate)
5131 else if (11502 <= rate)
5133 else if (9391 <= rate)
5140 aac_profile_idx (const gchar * codec_id)
5144 if (strlen (codec_id) <= 12)
5146 else if (!strncmp (&codec_id[12], "MAIN", 4))
5148 else if (!strncmp (&codec_id[12], "LC", 2))
5150 else if (!strncmp (&codec_id[12], "SSR", 3))
5159 round_up_pow2 (guint n)
5170 #define AAC_SYNC_EXTENSION_TYPE 0x02b7
5173 gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext *
5174 audiocontext, const gchar * codec_id, guint8 * data, guint size,
5175 gchar ** codec_name, guint16 * riff_audio_fmt)
5177 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) audiocontext;
5178 GstCaps *caps = NULL;
5180 g_assert (audiocontext != NULL);
5181 g_assert (codec_name != NULL);
5184 *riff_audio_fmt = 0;
5186 /* TODO: check if we have all codec types from matroska-ids.h
5187 * check if we have to do more special things with codec_private
5188 * check if we need bitdepth in different places too
5189 * implement channel position magic
5191 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID9
5192 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID10
5193 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDMC
5194 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDM2
5197 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1) ||
5198 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2) ||
5199 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L3)) {
5202 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1))
5204 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2))
5209 caps = gst_caps_new_simple ("audio/mpeg",
5210 "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, layer, NULL);
5211 *codec_name = g_strdup_printf ("MPEG-1 layer %d", layer);
5212 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE) ||
5213 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_LE)) {
5216 GstAudioFormat format;
5218 sign = (audiocontext->bitdepth != 8);
5219 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE))
5220 endianness = G_BIG_ENDIAN;
5222 endianness = G_LITTLE_ENDIAN;
5224 format = gst_audio_format_build_integer (sign, endianness,
5225 audiocontext->bitdepth, audiocontext->bitdepth);
5227 /* FIXME: Channel mask and reordering */
5228 caps = gst_caps_new_simple ("audio/x-raw",
5229 "format", G_TYPE_STRING, gst_audio_format_to_string (format),
5230 "layout", G_TYPE_STRING, "interleaved", NULL);
5232 *codec_name = g_strdup_printf ("Raw %d-bit PCM audio",
5233 audiocontext->bitdepth);
5234 context->alignment = GST_ROUND_UP_8 (audiocontext->bitdepth) / 8;
5235 context->alignment = round_up_pow2 (context->alignment);
5236 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_FLOAT)) {
5237 const gchar *format;
5238 if (audiocontext->bitdepth == 32)
5242 /* FIXME: Channel mask and reordering */
5243 caps = gst_caps_new_simple ("audio/x-raw",
5244 "format", G_TYPE_STRING, format,
5245 "layout", G_TYPE_STRING, "interleaved", NULL);
5246 *codec_name = g_strdup_printf ("Raw %d-bit floating-point audio",
5247 audiocontext->bitdepth);
5248 context->alignment = audiocontext->bitdepth / 8;
5249 context->alignment = round_up_pow2 (context->alignment);
5250 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AC3,
5251 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AC3))) {
5252 caps = gst_caps_new_simple ("audio/x-ac3",
5253 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5254 *codec_name = g_strdup ("AC-3 audio");
5255 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_EAC3,
5256 strlen (GST_MATROSKA_CODEC_ID_AUDIO_EAC3))) {
5257 caps = gst_caps_new_simple ("audio/x-eac3",
5258 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5259 *codec_name = g_strdup ("E-AC-3 audio");
5260 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TRUEHD,
5261 strlen (GST_MATROSKA_CODEC_ID_AUDIO_TRUEHD))) {
5262 caps = gst_caps_new_empty_simple ("audio/x-true-hd");
5263 *codec_name = g_strdup ("Dolby TrueHD");
5264 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_DTS)) {
5265 caps = gst_caps_new_empty_simple ("audio/x-dts");
5266 *codec_name = g_strdup ("DTS audio");
5267 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_VORBIS)) {
5268 caps = gst_caps_new_empty_simple ("audio/x-vorbis");
5269 context->stream_headers =
5270 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
5271 context->codec_priv_size);
5272 /* FIXME: mark stream as broken and skip if there are no stream headers */
5273 context->send_stream_headers = TRUE;
5274 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_FLAC)) {
5275 caps = gst_caps_new_empty_simple ("audio/x-flac");
5276 context->stream_headers =
5277 gst_matroska_parse_flac_stream_headers (context->codec_priv,
5278 context->codec_priv_size);
5279 /* FIXME: mark stream as broken and skip if there are no stream headers */
5280 context->send_stream_headers = TRUE;
5281 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_SPEEX)) {
5282 caps = gst_caps_new_empty_simple ("audio/x-speex");
5283 context->stream_headers =
5284 gst_matroska_parse_speex_stream_headers (context->codec_priv,
5285 context->codec_priv_size);
5286 /* FIXME: mark stream as broken and skip if there are no stream headers */
5287 context->send_stream_headers = TRUE;
5288 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_OPUS)) {
5289 caps = gst_caps_new_empty_simple ("audio/x-opus");
5290 *codec_name = g_strdup ("Opus");
5291 context->stream_headers =
5292 gst_matroska_parse_opus_stream_headers (context->codec_priv,
5293 context->codec_priv_size);
5294 if (context->stream_headers) {
5295 /* There was a valid header. Multistream headers are more than
5296 * 19 bytes, as they include an extra channel mapping table. */
5297 gboolean multistream = (context->codec_priv_size > 19);
5298 gst_caps_set_simple (caps, "multistream", G_TYPE_BOOLEAN, multistream,
5301 /* FIXME: mark stream as broken and skip if there are no stream headers */
5302 context->send_stream_headers = TRUE;
5303 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_ACM)) {
5304 gst_riff_strf_auds auds;
5306 if (data && size >= 18) {
5307 GstBuffer *codec_data = NULL;
5309 /* little-endian -> byte-order */
5310 auds.format = GST_READ_UINT16_LE (data);
5311 auds.channels = GST_READ_UINT16_LE (data + 2);
5312 auds.rate = GST_READ_UINT32_LE (data + 4);
5313 auds.av_bps = GST_READ_UINT32_LE (data + 8);
5314 auds.blockalign = GST_READ_UINT16_LE (data + 12);
5315 auds.bits_per_sample = GST_READ_UINT16_LE (data + 16);
5317 /* 18 is the waveformatex size */
5319 codec_data = gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY,
5320 data + 18, size - 18, 0, size - 18, NULL, NULL);
5324 *riff_audio_fmt = auds.format;
5326 /* FIXME: Handle reorder map */
5327 caps = gst_riff_create_audio_caps (auds.format, NULL, &auds, NULL,
5328 codec_data, codec_name, NULL);
5330 gst_buffer_unref (codec_data);
5333 GST_WARNING ("Unhandled RIFF audio format 0x%02x", auds.format);
5336 GST_WARNING ("Invalid codec data size (%d expected, got %d)", 18, size);
5338 } else if (g_str_has_prefix (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC)) {
5339 GstBuffer *priv = NULL;
5341 gint rate_idx, profile;
5342 guint8 *data = NULL;
5344 /* unspecified AAC profile with opaque private codec data */
5345 if (strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC) == 0) {
5346 if (context->codec_priv_size >= 2) {
5347 guint obj_type, freq_index, explicit_freq_bytes = 0;
5349 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
5351 freq_index = (GST_READ_UINT16_BE (context->codec_priv) & 0x780) >> 7;
5352 obj_type = (GST_READ_UINT16_BE (context->codec_priv) & 0xF800) >> 11;
5353 if (freq_index == 15)
5354 explicit_freq_bytes = 3;
5355 GST_DEBUG ("obj_type = %u, freq_index = %u", obj_type, freq_index);
5356 priv = gst_buffer_new_wrapped (g_memdup (context->codec_priv,
5357 context->codec_priv_size), context->codec_priv_size);
5358 /* assume SBR if samplerate <= 24kHz */
5359 if (obj_type == 5 || (freq_index >= 6 && freq_index != 15) ||
5360 (context->codec_priv_size == (5 + explicit_freq_bytes))) {
5361 audiocontext->samplerate *= 2;
5364 GST_WARNING ("Opaque A_AAC codec ID, but no codec private data");
5365 /* this is pretty broken;
5366 * maybe we need to make up some default private,
5367 * or maybe ADTS data got dumped in.
5368 * Let's set up some private data now, and check actual data later */
5369 /* just try this and see what happens ... */
5370 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
5371 context->postprocess_frame = gst_matroska_demux_check_aac;
5375 /* make up decoder-specific data if it is not supplied */
5379 priv = gst_buffer_new_allocate (NULL, 5, NULL);
5380 gst_buffer_map (priv, &map, GST_MAP_WRITE);
5382 rate_idx = aac_rate_idx (audiocontext->samplerate);
5383 profile = aac_profile_idx (codec_id);
5385 data[0] = ((profile + 1) << 3) | ((rate_idx & 0xE) >> 1);
5386 data[1] = ((rate_idx & 0x1) << 7) | (audiocontext->channels << 3);
5388 if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2,
5389 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2))) {
5391 gst_buffer_unmap (priv, &map);
5392 gst_buffer_set_size (priv, 2);
5393 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4,
5394 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4))) {
5397 if (g_strrstr (codec_id, "SBR")) {
5398 /* HE-AAC (aka SBR AAC) */
5399 audiocontext->samplerate *= 2;
5400 rate_idx = aac_rate_idx (audiocontext->samplerate);
5401 data[2] = AAC_SYNC_EXTENSION_TYPE >> 3;
5402 data[3] = ((AAC_SYNC_EXTENSION_TYPE & 0x07) << 5) | 5;
5403 data[4] = (1 << 7) | (rate_idx << 3);
5404 gst_buffer_unmap (priv, &map);
5406 gst_buffer_unmap (priv, &map);
5407 gst_buffer_set_size (priv, 2);
5410 gst_buffer_unmap (priv, &map);
5411 gst_buffer_unref (priv);
5413 GST_ERROR ("Unknown AAC profile and no codec private data");
5418 caps = gst_caps_new_simple ("audio/mpeg",
5419 "mpegversion", G_TYPE_INT, mpegversion,
5420 "framed", G_TYPE_BOOLEAN, TRUE,
5421 "stream-format", G_TYPE_STRING, "raw", NULL);
5422 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5423 if (context->codec_priv && context->codec_priv_size > 0)
5424 gst_codec_utils_aac_caps_set_level_and_profile (caps,
5425 context->codec_priv, context->codec_priv_size);
5426 *codec_name = g_strdup_printf ("MPEG-%d AAC audio", mpegversion);
5427 gst_buffer_unref (priv);
5429 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TTA)) {
5430 caps = gst_caps_new_simple ("audio/x-tta",
5431 "width", G_TYPE_INT, audiocontext->bitdepth, NULL);
5432 *codec_name = g_strdup ("TTA audio");
5433 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_WAVPACK4)) {
5434 caps = gst_caps_new_simple ("audio/x-wavpack",
5435 "width", G_TYPE_INT, audiocontext->bitdepth,
5436 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5437 *codec_name = g_strdup ("Wavpack audio");
5438 context->postprocess_frame = gst_matroska_demux_add_wvpk_header;
5439 audiocontext->wvpk_block_index = 0;
5440 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4)) ||
5441 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_28_8)) ||
5442 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))) {
5443 gint raversion = -1;
5445 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4))
5447 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))
5452 caps = gst_caps_new_simple ("audio/x-pn-realaudio",
5453 "raversion", G_TYPE_INT, raversion, NULL);
5454 /* Extract extra information from caps, mapping varies based on codec */
5455 if (data && (size >= 0x50)) {
5462 guint extra_data_size;
5464 GST_ERROR ("real audio raversion:%d", raversion);
5465 if (raversion == 8) {
5467 flavor = GST_READ_UINT16_BE (data + 22);
5468 packet_size = GST_READ_UINT32_BE (data + 24);
5469 height = GST_READ_UINT16_BE (data + 40);
5470 leaf_size = GST_READ_UINT16_BE (data + 44);
5471 sample_width = GST_READ_UINT16_BE (data + 58);
5472 extra_data_size = GST_READ_UINT32_BE (data + 74);
5475 ("flavor:%d, packet_size:%d, height:%d, leaf_size:%d, sample_width:%d, extra_data_size:%d",
5476 flavor, packet_size, height, leaf_size, sample_width,
5478 gst_caps_set_simple (caps, "flavor", G_TYPE_INT, flavor, "packet_size",
5479 G_TYPE_INT, packet_size, "height", G_TYPE_INT, height, "leaf_size",
5480 G_TYPE_INT, leaf_size, "width", G_TYPE_INT, sample_width, NULL);
5482 if ((size - 78) >= extra_data_size) {
5483 priv = gst_buffer_new_wrapped (g_memdup (data + 78, extra_data_size),
5485 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5486 gst_buffer_unref (priv);
5491 *codec_name = g_strdup_printf ("RealAudio %d.0", raversion);
5492 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_SIPR)) {
5493 caps = gst_caps_new_empty_simple ("audio/x-sipro");
5494 *codec_name = g_strdup ("Sipro/ACELP.NET Voice Codec");
5495 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_RALF)) {
5496 caps = gst_caps_new_empty_simple ("audio/x-ralf-mpeg4-generic");
5497 *codec_name = g_strdup ("Real Audio Lossless");
5498 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_ATRC)) {
5499 caps = gst_caps_new_empty_simple ("audio/x-vnd.sony.atrac3");
5500 *codec_name = g_strdup ("Sony ATRAC3");
5502 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
5507 if (audiocontext->samplerate > 0 && audiocontext->channels > 0) {
5510 for (i = 0; i < gst_caps_get_size (caps); i++) {
5511 gst_structure_set (gst_caps_get_structure (caps, i),
5512 "channels", G_TYPE_INT, audiocontext->channels,
5513 "rate", G_TYPE_INT, audiocontext->samplerate, NULL);
5517 caps = gst_caps_simplify (caps);
5524 gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
5525 subtitlecontext, const gchar * codec_id, gpointer data, guint size)
5527 GstCaps *caps = NULL;
5528 GstMatroskaTrackContext *context =
5529 (GstMatroskaTrackContext *) subtitlecontext;
5531 /* for backwards compatibility */
5532 if (!g_ascii_strcasecmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASCII))
5533 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8;
5534 else if (!g_ascii_strcasecmp (codec_id, "S_SSA"))
5535 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_SSA;
5536 else if (!g_ascii_strcasecmp (codec_id, "S_ASS"))
5537 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_ASS;
5538 else if (!g_ascii_strcasecmp (codec_id, "S_USF"))
5539 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_USF;
5541 /* TODO: Add GST_MATROSKA_CODEC_ID_SUBTITLE_BMP support
5542 * Check if we have to do something with codec_private */
5543 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8)) {
5544 /* well, plain text simply does not have a lot of markup ... */
5545 caps = gst_caps_new_simple ("text/x-raw", "format", G_TYPE_STRING,
5546 "pango-markup", NULL);
5547 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5548 subtitlecontext->check_markup = TRUE;
5549 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_SSA)) {
5550 caps = gst_caps_new_empty_simple ("application/x-ssa");
5551 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5552 subtitlecontext->check_markup = FALSE;
5553 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASS)) {
5554 caps = gst_caps_new_empty_simple ("application/x-ass");
5555 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5556 subtitlecontext->check_markup = FALSE;
5557 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_USF)) {
5558 caps = gst_caps_new_empty_simple ("application/x-usf");
5559 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5560 subtitlecontext->check_markup = FALSE;
5561 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB)) {
5562 caps = gst_caps_new_empty_simple ("subpicture/x-dvd");
5563 ((GstMatroskaTrackContext *) subtitlecontext)->send_dvd_event = TRUE;
5564 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_HDMVPGS)) {
5565 caps = gst_caps_new_empty_simple ("subpicture/x-pgs");
5566 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_KATE)) {
5567 caps = gst_caps_new_empty_simple ("subtitle/x-kate");
5568 context->stream_headers =
5569 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
5570 context->codec_priv_size);
5571 /* FIXME: mark stream as broken and skip if there are no stream headers */
5572 context->send_stream_headers = TRUE;
5574 GST_DEBUG ("Unknown subtitle stream: codec_id='%s'", codec_id);
5575 caps = gst_caps_new_empty_simple ("application/x-subtitle-unknown");
5578 if (data != NULL && size > 0) {
5581 buf = gst_buffer_new_wrapped (g_memdup (data, size), size);
5582 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, buf, NULL);
5583 gst_buffer_unref (buf);
5591 gst_matroska_demux_set_index (GstElement * element, GstIndex * index)
5593 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5595 GST_OBJECT_LOCK (demux);
5596 if (demux->common.element_index)
5597 gst_object_unref (demux->common.element_index);
5598 demux->common.element_index = index ? gst_object_ref (index) : NULL;
5599 GST_OBJECT_UNLOCK (demux);
5600 GST_DEBUG_OBJECT (demux, "Set index %" GST_PTR_FORMAT,
5601 demux->common.element_index);
5605 gst_matroska_demux_get_index (GstElement * element)
5607 GstIndex *result = NULL;
5608 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5610 GST_OBJECT_LOCK (demux);
5611 if (demux->common.element_index)
5612 result = gst_object_ref (demux->common.element_index);
5613 GST_OBJECT_UNLOCK (demux);
5615 GST_DEBUG_OBJECT (demux, "Returning index %" GST_PTR_FORMAT, result);
5621 static GstStateChangeReturn
5622 gst_matroska_demux_change_state (GstElement * element,
5623 GstStateChange transition)
5625 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5626 GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
5628 /* handle upwards state changes here */
5629 switch (transition) {
5634 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
5636 /* handle downwards state changes */
5637 switch (transition) {
5638 case GST_STATE_CHANGE_PAUSED_TO_READY:
5639 gst_matroska_demux_reset (GST_ELEMENT (demux));
5649 gst_matroska_demux_set_property (GObject * object,
5650 guint prop_id, const GValue * value, GParamSpec * pspec)
5652 GstMatroskaDemux *demux;
5654 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
5655 demux = GST_MATROSKA_DEMUX (object);
5658 case ARG_MAX_GAP_TIME:
5659 GST_OBJECT_LOCK (demux);
5660 demux->max_gap_time = g_value_get_uint64 (value);
5661 GST_OBJECT_UNLOCK (demux);
5664 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
5670 gst_matroska_demux_get_property (GObject * object,
5671 guint prop_id, GValue * value, GParamSpec * pspec)
5673 GstMatroskaDemux *demux;
5675 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
5676 demux = GST_MATROSKA_DEMUX (object);
5679 case ARG_MAX_GAP_TIME:
5680 GST_OBJECT_LOCK (demux);
5681 g_value_set_uint64 (value, demux->max_gap_time);
5682 GST_OBJECT_UNLOCK (demux);
5685 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
5691 gst_matroska_demux_plugin_init (GstPlugin * plugin)
5695 /* parser helper separate debug */
5696 GST_DEBUG_CATEGORY_INIT (ebmlread_debug, "ebmlread",
5697 0, "EBML stream helper class");
5699 /* create an elementfactory for the matroska_demux element */
5700 if (!gst_element_register (plugin, "matroskademux",
5701 GST_RANK_PRIMARY, GST_TYPE_MATROSKA_DEMUX))