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);
269 gst_matroska_demux_reset (GST_ELEMENT (demux));
270 demux->flowcombiner = gst_flow_combiner_new ();
274 gst_matroska_demux_reset (GstElement * element)
276 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
278 GST_DEBUG_OBJECT (demux, "Resetting state");
280 gst_matroska_read_common_reset (GST_ELEMENT (demux), &demux->common);
282 demux->num_a_streams = 0;
283 demux->num_t_streams = 0;
284 demux->num_v_streams = 0;
286 demux->have_group_id = FALSE;
287 demux->group_id = G_MAXUINT;
290 demux->tracks_parsed = FALSE;
292 if (demux->clusters) {
293 g_array_free (demux->clusters, TRUE);
294 demux->clusters = NULL;
297 g_list_foreach (demux->seek_parsed,
298 (GFunc) gst_matroska_read_common_free_parsed_el, NULL);
299 g_list_free (demux->seek_parsed);
300 demux->seek_parsed = NULL;
302 demux->last_stop_end = GST_CLOCK_TIME_NONE;
303 demux->seek_block = 0;
304 demux->stream_start_time = GST_CLOCK_TIME_NONE;
305 demux->to_time = GST_CLOCK_TIME_NONE;
306 demux->cluster_time = GST_CLOCK_TIME_NONE;
307 demux->cluster_offset = 0;
308 demux->next_cluster_offset = 0;
309 demux->index_offset = 0;
310 demux->seekable = FALSE;
311 demux->need_segment = FALSE;
312 demux->segment_seqnum = 0;
313 demux->requested_seek_time = GST_CLOCK_TIME_NONE;
314 demux->seek_offset = -1;
315 demux->building_index = FALSE;
316 if (demux->seek_event) {
317 gst_event_unref (demux->seek_event);
318 demux->seek_event = NULL;
321 demux->seek_index = NULL;
322 demux->seek_entry = 0;
324 if (demux->new_segment) {
325 gst_event_unref (demux->new_segment);
326 demux->new_segment = NULL;
329 demux->invalid_duration = FALSE;
333 gst_matroska_decode_buffer (GstMatroskaTrackContext * context, GstBuffer * buf)
339 g_return_val_if_fail (GST_IS_BUFFER (buf), NULL);
341 GST_DEBUG ("decoding buffer %p", buf);
343 gst_buffer_map (buf, &map, GST_MAP_READ);
347 g_return_val_if_fail (size > 0, buf);
349 if (gst_matroska_decode_data (context->encodings, &data, &size,
350 GST_MATROSKA_TRACK_ENCODING_SCOPE_FRAME, FALSE)) {
351 gst_buffer_unmap (buf, &map);
352 gst_buffer_unref (buf);
353 return gst_buffer_new_wrapped (data, size);
355 GST_DEBUG ("decode data failed");
356 gst_buffer_unmap (buf, &map);
357 gst_buffer_unref (buf);
363 gst_matroska_demux_add_stream_headers_to_caps (GstMatroskaDemux * demux,
364 GstBufferList * list, GstCaps * caps)
367 GValue arr_val = G_VALUE_INIT;
368 GValue buf_val = G_VALUE_INIT;
371 g_assert (gst_caps_is_writable (caps));
373 g_value_init (&arr_val, GST_TYPE_ARRAY);
374 g_value_init (&buf_val, GST_TYPE_BUFFER);
376 num = gst_buffer_list_length (list);
377 for (i = 0; i < num; ++i) {
378 g_value_set_boxed (&buf_val, gst_buffer_list_get (list, i));
379 gst_value_array_append_value (&arr_val, &buf_val);
382 s = gst_caps_get_structure (caps, 0);
383 gst_structure_take_value (s, "streamheader", &arr_val);
384 g_value_unset (&buf_val);
388 gst_matroska_demux_add_stream (GstMatroskaDemux * demux, GstEbmlRead * ebml)
390 GstElementClass *klass = GST_ELEMENT_GET_CLASS (demux);
391 GstMatroskaTrackContext *context;
392 GstPadTemplate *templ = NULL;
393 GstStreamFlags stream_flags;
394 GstCaps *caps = NULL;
395 gchar *padname = NULL;
397 guint32 id, riff_fourcc = 0;
398 guint16 riff_audio_fmt = 0;
399 GstTagList *list = NULL;
400 GstEvent *stream_start;
404 DEBUG_ELEMENT_START (demux, ebml, "TrackEntry");
406 /* start with the master */
407 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
408 DEBUG_ELEMENT_STOP (demux, ebml, "TrackEntry", ret);
412 /* allocate generic... if we know the type, we'll g_renew()
413 * with the precise type */
414 context = g_new0 (GstMatroskaTrackContext, 1);
415 g_ptr_array_add (demux->common.src, context);
416 context->index = demux->common.num_streams;
417 context->index_writer_id = -1;
418 context->type = 0; /* no type yet */
419 context->default_duration = 0;
421 context->set_discont = TRUE;
422 context->timecodescale = 1.0;
424 GST_MATROSKA_TRACK_ENABLED | GST_MATROSKA_TRACK_DEFAULT |
425 GST_MATROSKA_TRACK_LACING;
426 context->from_time = GST_CLOCK_TIME_NONE;
427 context->from_offset = -1;
428 context->to_offset = G_MAXINT64;
429 context->alignment = 1;
430 demux->common.num_streams++;
431 g_assert (demux->common.src->len == demux->common.num_streams);
433 GST_DEBUG_OBJECT (demux, "Stream number %d", context->index);
435 /* try reading the trackentry headers */
436 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
437 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
441 /* track number (unique stream ID) */
442 case GST_MATROSKA_ID_TRACKNUMBER:{
445 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
449 GST_ERROR_OBJECT (demux, "Invalid TrackNumber 0");
450 ret = GST_FLOW_ERROR;
452 } else if (!gst_matroska_read_common_tracknumber_unique (&demux->common,
454 GST_ERROR_OBJECT (demux, "TrackNumber %" G_GUINT64_FORMAT
455 " is not unique", num);
456 ret = GST_FLOW_ERROR;
460 GST_DEBUG_OBJECT (demux, "TrackNumber: %" G_GUINT64_FORMAT, num);
464 /* track UID (unique identifier) */
465 case GST_MATROSKA_ID_TRACKUID:{
468 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
472 GST_ERROR_OBJECT (demux, "Invalid TrackUID 0");
473 ret = GST_FLOW_ERROR;
477 GST_DEBUG_OBJECT (demux, "TrackUID: %" G_GUINT64_FORMAT, num);
482 /* track type (video, audio, combined, subtitle, etc.) */
483 case GST_MATROSKA_ID_TRACKTYPE:{
486 if ((ret = gst_ebml_read_uint (ebml, &id, &track_type)) != GST_FLOW_OK) {
490 if (context->type != 0 && context->type != track_type) {
491 GST_WARNING_OBJECT (demux,
492 "More than one tracktype defined in a TrackEntry - skipping");
494 } else if (track_type < 1 || track_type > 254) {
495 GST_WARNING_OBJECT (demux, "Invalid TrackType %" G_GUINT64_FORMAT,
500 GST_DEBUG_OBJECT (demux, "TrackType: %" G_GUINT64_FORMAT, track_type);
502 /* ok, so we're actually going to reallocate this thing */
503 switch (track_type) {
504 case GST_MATROSKA_TRACK_TYPE_VIDEO:
505 gst_matroska_track_init_video_context (&context);
507 case GST_MATROSKA_TRACK_TYPE_AUDIO:
508 gst_matroska_track_init_audio_context (&context);
510 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
511 gst_matroska_track_init_subtitle_context (&context);
513 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
514 case GST_MATROSKA_TRACK_TYPE_LOGO:
515 case GST_MATROSKA_TRACK_TYPE_BUTTONS:
516 case GST_MATROSKA_TRACK_TYPE_CONTROL:
518 GST_WARNING_OBJECT (demux,
519 "Unknown or unsupported TrackType %" G_GUINT64_FORMAT,
524 g_ptr_array_index (demux->common.src, demux->common.num_streams - 1)
529 /* tracktype specific stuff for video */
530 case GST_MATROSKA_ID_TRACKVIDEO:{
531 GstMatroskaTrackVideoContext *videocontext;
533 DEBUG_ELEMENT_START (demux, ebml, "TrackVideo");
535 if (!gst_matroska_track_init_video_context (&context)) {
536 GST_WARNING_OBJECT (demux,
537 "TrackVideo element in non-video track - ignoring track");
538 ret = GST_FLOW_ERROR;
540 } else if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
543 videocontext = (GstMatroskaTrackVideoContext *) context;
544 g_ptr_array_index (demux->common.src, demux->common.num_streams - 1)
547 while (ret == GST_FLOW_OK &&
548 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
549 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
553 /* Should be one level up but some broken muxers write it here. */
554 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
557 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
561 GST_WARNING_OBJECT (demux, "Invalid TrackDefaultDuration 0");
565 GST_DEBUG_OBJECT (demux,
566 "TrackDefaultDuration: %" G_GUINT64_FORMAT, num);
567 context->default_duration = num;
571 /* video framerate */
572 /* NOTE: This one is here only for backward compatibility.
573 * Use _TRACKDEFAULDURATION one level up. */
574 case GST_MATROSKA_ID_VIDEOFRAMERATE:{
577 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
581 GST_WARNING_OBJECT (demux, "Invalid TrackVideoFPS %lf", num);
585 GST_DEBUG_OBJECT (demux, "TrackVideoFrameRate: %lf", num);
586 if (context->default_duration == 0)
587 context->default_duration =
588 gst_gdouble_to_guint64 ((gdouble) GST_SECOND * (1.0 / num));
589 videocontext->default_fps = num;
593 /* width of the size to display the video at */
594 case GST_MATROSKA_ID_VIDEODISPLAYWIDTH:{
597 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
601 GST_WARNING_OBJECT (demux, "Invalid TrackVideoDisplayWidth 0");
605 GST_DEBUG_OBJECT (demux,
606 "TrackVideoDisplayWidth: %" G_GUINT64_FORMAT, num);
607 videocontext->display_width = num;
611 /* height of the size to display the video at */
612 case GST_MATROSKA_ID_VIDEODISPLAYHEIGHT:{
615 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
619 GST_WARNING_OBJECT (demux, "Invalid TrackVideoDisplayHeight 0");
623 GST_DEBUG_OBJECT (demux,
624 "TrackVideoDisplayHeight: %" G_GUINT64_FORMAT, num);
625 videocontext->display_height = num;
629 /* width of the video in the file */
630 case GST_MATROSKA_ID_VIDEOPIXELWIDTH:{
633 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
637 GST_WARNING_OBJECT (demux, "Invalid TrackVideoPixelWidth 0");
641 GST_DEBUG_OBJECT (demux,
642 "TrackVideoPixelWidth: %" G_GUINT64_FORMAT, num);
643 videocontext->pixel_width = num;
647 /* height of the video in the file */
648 case GST_MATROSKA_ID_VIDEOPIXELHEIGHT:{
651 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
655 GST_WARNING_OBJECT (demux, "Invalid TrackVideoPixelHeight 0");
659 GST_DEBUG_OBJECT (demux,
660 "TrackVideoPixelHeight: %" G_GUINT64_FORMAT, num);
661 videocontext->pixel_height = num;
665 /* whether the video is interlaced */
666 case GST_MATROSKA_ID_VIDEOFLAGINTERLACED:{
669 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
673 context->flags |= GST_MATROSKA_VIDEOTRACK_INTERLACED;
675 context->flags &= ~GST_MATROSKA_VIDEOTRACK_INTERLACED;
676 GST_DEBUG_OBJECT (demux, "TrackVideoInterlaced: %d",
677 (context->flags & GST_MATROSKA_VIDEOTRACK_INTERLACED) ? 1 :
682 /* aspect ratio behaviour */
683 case GST_MATROSKA_ID_VIDEOASPECTRATIOTYPE:{
686 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
689 if (num != GST_MATROSKA_ASPECT_RATIO_MODE_FREE &&
690 num != GST_MATROSKA_ASPECT_RATIO_MODE_KEEP &&
691 num != GST_MATROSKA_ASPECT_RATIO_MODE_FIXED) {
692 GST_WARNING_OBJECT (demux,
693 "Unknown TrackVideoAspectRatioType 0x%x", (guint) num);
696 GST_DEBUG_OBJECT (demux,
697 "TrackVideoAspectRatioType: %" G_GUINT64_FORMAT, num);
698 videocontext->asr_mode = num;
702 /* colourspace (only matters for raw video) fourcc */
703 case GST_MATROSKA_ID_VIDEOCOLOURSPACE:{
708 gst_ebml_read_binary (ebml, &id, &data,
709 &datalen)) != GST_FLOW_OK)
714 GST_WARNING_OBJECT (demux,
715 "Invalid TrackVideoColourSpace length %" G_GUINT64_FORMAT,
720 memcpy (&videocontext->fourcc, data, 4);
721 GST_DEBUG_OBJECT (demux,
722 "TrackVideoColourSpace: %" GST_FOURCC_FORMAT,
723 GST_FOURCC_ARGS (videocontext->fourcc));
729 GST_WARNING_OBJECT (demux,
730 "Unknown TrackVideo subelement 0x%x - ignoring", id);
732 case GST_MATROSKA_ID_VIDEOSTEREOMODE:
733 case GST_MATROSKA_ID_VIDEODISPLAYUNIT:
734 case GST_MATROSKA_ID_VIDEOPIXELCROPBOTTOM:
735 case GST_MATROSKA_ID_VIDEOPIXELCROPTOP:
736 case GST_MATROSKA_ID_VIDEOPIXELCROPLEFT:
737 case GST_MATROSKA_ID_VIDEOPIXELCROPRIGHT:
738 case GST_MATROSKA_ID_VIDEOGAMMAVALUE:
739 ret = gst_ebml_read_skip (ebml);
744 DEBUG_ELEMENT_STOP (demux, ebml, "TrackVideo", ret);
748 /* tracktype specific stuff for audio */
749 case GST_MATROSKA_ID_TRACKAUDIO:{
750 GstMatroskaTrackAudioContext *audiocontext;
752 DEBUG_ELEMENT_START (demux, ebml, "TrackAudio");
754 if (!gst_matroska_track_init_audio_context (&context)) {
755 GST_WARNING_OBJECT (demux,
756 "TrackAudio element in non-audio track - ignoring track");
757 ret = GST_FLOW_ERROR;
761 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
764 audiocontext = (GstMatroskaTrackAudioContext *) context;
765 g_ptr_array_index (demux->common.src, demux->common.num_streams - 1)
768 while (ret == GST_FLOW_OK &&
769 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
770 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
775 case GST_MATROSKA_ID_AUDIOSAMPLINGFREQ:{
778 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
783 GST_WARNING_OBJECT (demux,
784 "Invalid TrackAudioSamplingFrequency %lf", num);
788 GST_DEBUG_OBJECT (demux, "TrackAudioSamplingFrequency: %lf", num);
789 audiocontext->samplerate = num;
794 case GST_MATROSKA_ID_AUDIOBITDEPTH:{
797 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
801 GST_WARNING_OBJECT (demux, "Invalid TrackAudioBitDepth 0");
805 GST_DEBUG_OBJECT (demux, "TrackAudioBitDepth: %" G_GUINT64_FORMAT,
807 audiocontext->bitdepth = num;
812 case GST_MATROSKA_ID_AUDIOCHANNELS:{
815 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
819 GST_WARNING_OBJECT (demux, "Invalid TrackAudioChannels 0");
823 GST_DEBUG_OBJECT (demux, "TrackAudioChannels: %" G_GUINT64_FORMAT,
825 audiocontext->channels = num;
830 GST_WARNING_OBJECT (demux,
831 "Unknown TrackAudio subelement 0x%x - ignoring", id);
833 case GST_MATROSKA_ID_AUDIOCHANNELPOSITIONS:
834 case GST_MATROSKA_ID_AUDIOOUTPUTSAMPLINGFREQ:
835 ret = gst_ebml_read_skip (ebml);
840 DEBUG_ELEMENT_STOP (demux, ebml, "TrackAudio", ret);
845 /* codec identifier */
846 case GST_MATROSKA_ID_CODECID:{
849 if ((ret = gst_ebml_read_ascii (ebml, &id, &text)) != GST_FLOW_OK)
852 GST_DEBUG_OBJECT (demux, "CodecID: %s", GST_STR_NULL (text));
853 context->codec_id = text;
857 /* codec private data */
858 case GST_MATROSKA_ID_CODECPRIVATE:{
863 gst_ebml_read_binary (ebml, &id, &data, &size)) != GST_FLOW_OK)
866 context->codec_priv = data;
867 context->codec_priv_size = size;
869 GST_DEBUG_OBJECT (demux, "CodecPrivate of size %" G_GUINT64_FORMAT,
874 /* name of the codec */
875 case GST_MATROSKA_ID_CODECNAME:{
878 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
881 GST_DEBUG_OBJECT (demux, "CodecName: %s", GST_STR_NULL (text));
882 context->codec_name = text;
886 /* name of this track */
887 case GST_MATROSKA_ID_TRACKNAME:{
890 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
893 context->name = text;
894 GST_DEBUG_OBJECT (demux, "TrackName: %s", GST_STR_NULL (text));
898 /* language (matters for audio/subtitles, mostly) */
899 case GST_MATROSKA_ID_TRACKLANGUAGE:{
902 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
906 context->language = text;
909 if (strlen (context->language) >= 4 && context->language[3] == '-')
910 context->language[3] = '\0';
912 GST_DEBUG_OBJECT (demux, "TrackLanguage: %s",
913 GST_STR_NULL (context->language));
917 /* whether this is actually used */
918 case GST_MATROSKA_ID_TRACKFLAGENABLED:{
921 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
925 context->flags |= GST_MATROSKA_TRACK_ENABLED;
927 context->flags &= ~GST_MATROSKA_TRACK_ENABLED;
929 GST_DEBUG_OBJECT (demux, "TrackEnabled: %d",
930 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
934 /* whether it's the default for this track type */
935 case GST_MATROSKA_ID_TRACKFLAGDEFAULT:{
938 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
942 context->flags |= GST_MATROSKA_TRACK_DEFAULT;
944 context->flags &= ~GST_MATROSKA_TRACK_DEFAULT;
946 GST_DEBUG_OBJECT (demux, "TrackDefault: %d",
947 (context->flags & GST_MATROSKA_TRACK_DEFAULT) ? 1 : 0);
951 /* whether the track must be used during playback */
952 case GST_MATROSKA_ID_TRACKFLAGFORCED:{
955 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
959 context->flags |= GST_MATROSKA_TRACK_FORCED;
961 context->flags &= ~GST_MATROSKA_TRACK_FORCED;
963 GST_DEBUG_OBJECT (demux, "TrackForced: %d",
964 (context->flags & GST_MATROSKA_TRACK_FORCED) ? 1 : 0);
968 /* lacing (like MPEG, where blocks don't end/start on frame
970 case GST_MATROSKA_ID_TRACKFLAGLACING:{
973 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
977 context->flags |= GST_MATROSKA_TRACK_LACING;
979 context->flags &= ~GST_MATROSKA_TRACK_LACING;
981 GST_DEBUG_OBJECT (demux, "TrackLacing: %d",
982 (context->flags & GST_MATROSKA_TRACK_LACING) ? 1 : 0);
986 /* default length (in time) of one data block in this track */
987 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
990 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
995 GST_WARNING_OBJECT (demux, "Invalid TrackDefaultDuration 0");
999 GST_DEBUG_OBJECT (demux, "TrackDefaultDuration: %" G_GUINT64_FORMAT,
1001 context->default_duration = num;
1005 case GST_MATROSKA_ID_CONTENTENCODINGS:{
1006 ret = gst_matroska_read_common_read_track_encodings (&demux->common,
1011 case GST_MATROSKA_ID_TRACKTIMECODESCALE:{
1014 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
1018 GST_WARNING_OBJECT (demux, "Invalid TrackTimeCodeScale %lf", num);
1022 GST_DEBUG_OBJECT (demux, "TrackTimeCodeScale: %lf", num);
1023 context->timecodescale = num;
1028 GST_WARNING ("Unknown TrackEntry subelement 0x%x - ignoring", id);
1031 /* we ignore these because they're nothing useful (i.e. crap)
1032 * or simply not implemented yet. */
1033 case GST_MATROSKA_ID_TRACKMINCACHE:
1034 case GST_MATROSKA_ID_TRACKMAXCACHE:
1035 case GST_MATROSKA_ID_MAXBLOCKADDITIONID:
1036 case GST_MATROSKA_ID_TRACKATTACHMENTLINK:
1037 case GST_MATROSKA_ID_TRACKOVERLAY:
1038 case GST_MATROSKA_ID_TRACKTRANSLATE:
1039 case GST_MATROSKA_ID_TRACKOFFSET:
1040 case GST_MATROSKA_ID_CODECSETTINGS:
1041 case GST_MATROSKA_ID_CODECINFOURL:
1042 case GST_MATROSKA_ID_CODECDOWNLOADURL:
1043 case GST_MATROSKA_ID_CODECDECODEALL:
1044 ret = gst_ebml_read_skip (ebml);
1049 DEBUG_ELEMENT_STOP (demux, ebml, "TrackEntry", ret);
1051 /* Decode codec private data if necessary */
1052 if (context->encodings && context->encodings->len > 0 && context->codec_priv
1053 && context->codec_priv_size > 0) {
1054 if (!gst_matroska_decode_data (context->encodings,
1055 &context->codec_priv, &context->codec_priv_size,
1056 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
1057 GST_WARNING_OBJECT (demux, "Decoding codec private data failed");
1058 ret = GST_FLOW_ERROR;
1062 if (context->type == 0 || context->codec_id == NULL || (ret != GST_FLOW_OK
1063 && ret != GST_FLOW_EOS)) {
1064 if (ret == GST_FLOW_OK || ret == GST_FLOW_EOS)
1065 GST_WARNING_OBJECT (ebml, "Unknown stream/codec in track entry header");
1067 demux->common.num_streams--;
1068 g_ptr_array_remove_index (demux->common.src, demux->common.num_streams);
1069 g_assert (demux->common.src->len == demux->common.num_streams);
1071 gst_matroska_track_free (context);
1077 /* now create the GStreamer connectivity */
1078 switch (context->type) {
1079 case GST_MATROSKA_TRACK_TYPE_VIDEO:{
1080 GstMatroskaTrackVideoContext *videocontext =
1081 (GstMatroskaTrackVideoContext *) context;
1083 padname = g_strdup_printf ("video_%u", demux->num_v_streams++);
1084 templ = gst_element_class_get_pad_template (klass, "video_%u");
1085 caps = gst_matroska_demux_video_caps (videocontext,
1086 context->codec_id, context->codec_priv,
1087 context->codec_priv_size, &codec, &riff_fourcc);
1090 list = gst_tag_list_new (GST_TAG_VIDEO_CODEC, codec, NULL);
1096 case GST_MATROSKA_TRACK_TYPE_AUDIO:{
1097 GstMatroskaTrackAudioContext *audiocontext =
1098 (GstMatroskaTrackAudioContext *) context;
1100 padname = g_strdup_printf ("audio_%u", demux->num_a_streams++);
1101 templ = gst_element_class_get_pad_template (klass, "audio_%u");
1102 caps = gst_matroska_demux_audio_caps (audiocontext,
1103 context->codec_id, context->codec_priv, context->codec_priv_size,
1104 &codec, &riff_audio_fmt);
1107 list = gst_tag_list_new (GST_TAG_AUDIO_CODEC, codec, NULL);
1113 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:{
1114 GstMatroskaTrackSubtitleContext *subtitlecontext =
1115 (GstMatroskaTrackSubtitleContext *) context;
1117 padname = g_strdup_printf ("subtitle_%u", demux->num_t_streams++);
1118 templ = gst_element_class_get_pad_template (klass, "subtitle_%u");
1119 caps = gst_matroska_demux_subtitle_caps (subtitlecontext,
1120 context->codec_id, context->codec_priv, context->codec_priv_size);
1124 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1125 case GST_MATROSKA_TRACK_TYPE_LOGO:
1126 case GST_MATROSKA_TRACK_TYPE_BUTTONS:
1127 case GST_MATROSKA_TRACK_TYPE_CONTROL:
1129 /* we should already have quit by now */
1130 g_assert_not_reached ();
1133 if ((context->language == NULL || *context->language == '\0') &&
1134 (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO ||
1135 context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
1136 GST_LOG ("stream %d: language=eng (assuming default)", context->index);
1137 context->language = g_strdup ("eng");
1140 if (context->language) {
1144 list = gst_tag_list_new_empty ();
1146 /* Matroska contains ISO 639-2B codes, we want ISO 639-1 */
1147 lang = gst_tag_get_language_code (context->language);
1148 gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
1149 GST_TAG_LANGUAGE_CODE, (lang) ? lang : context->language, NULL);
1153 GST_WARNING_OBJECT (demux, "could not determine caps for stream with "
1154 "codec_id='%s'", context->codec_id);
1155 switch (context->type) {
1156 case GST_MATROSKA_TRACK_TYPE_VIDEO:
1157 caps = gst_caps_new_empty_simple ("video/x-unknown");
1159 case GST_MATROSKA_TRACK_TYPE_AUDIO:
1160 caps = gst_caps_new_empty_simple ("audio/x-unknown");
1162 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
1163 caps = gst_caps_new_empty_simple ("application/x-subtitle-unknown");
1165 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1167 caps = gst_caps_new_empty_simple ("application/x-matroska-unknown");
1170 gst_caps_set_simple (caps, "codec-id", G_TYPE_STRING, context->codec_id,
1173 /* add any unrecognised riff fourcc / audio format, but after codec-id */
1174 if (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO && riff_audio_fmt != 0)
1175 gst_caps_set_simple (caps, "format", G_TYPE_INT, riff_audio_fmt, NULL);
1176 else if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO && riff_fourcc != 0) {
1177 gchar *fstr = g_strdup_printf ("%" GST_FOURCC_FORMAT,
1178 GST_FOURCC_ARGS (riff_fourcc));
1179 gst_caps_set_simple (caps, "fourcc", G_TYPE_STRING, fstr, NULL);
1182 } else if (context->stream_headers != NULL) {
1183 gst_matroska_demux_add_stream_headers_to_caps (demux,
1184 context->stream_headers, caps);
1187 /* the pad in here */
1188 context->pad = gst_pad_new_from_template (templ, padname);
1189 context->caps = caps;
1191 gst_pad_set_event_function (context->pad,
1192 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_event));
1193 gst_pad_set_query_function (context->pad,
1194 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_query));
1196 GST_INFO_OBJECT (demux, "Adding pad '%s' with caps %" GST_PTR_FORMAT,
1199 context->pending_tags = list;
1201 gst_pad_set_element_private (context->pad, context);
1203 gst_pad_use_fixed_caps (context->pad);
1204 gst_pad_set_active (context->pad, TRUE);
1207 gst_pad_create_stream_id_printf (context->pad, GST_ELEMENT_CAST (demux),
1208 "%03" G_GUINT64_FORMAT, context->uid);
1210 gst_pad_get_sticky_event (demux->common.sinkpad, GST_EVENT_STREAM_START,
1213 if (gst_event_parse_group_id (stream_start, &demux->group_id))
1214 demux->have_group_id = TRUE;
1216 demux->have_group_id = FALSE;
1217 gst_event_unref (stream_start);
1218 } else if (!demux->have_group_id) {
1219 demux->have_group_id = TRUE;
1220 demux->group_id = gst_util_group_id_next ();
1223 stream_start = gst_event_new_stream_start (stream_id);
1225 if (demux->have_group_id)
1226 gst_event_set_group_id (stream_start, demux->group_id);
1227 stream_flags = GST_STREAM_FLAG_NONE;
1228 if (context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)
1229 stream_flags |= GST_STREAM_FLAG_SPARSE;
1230 if (context->flags & GST_MATROSKA_TRACK_DEFAULT)
1231 stream_flags |= GST_STREAM_FLAG_SELECT;
1232 gst_event_set_stream_flags (stream_start, stream_flags);
1233 gst_pad_push_event (context->pad, stream_start);
1234 gst_pad_set_caps (context->pad, context->caps);
1236 gst_element_add_pad (GST_ELEMENT (demux), context->pad);
1237 gst_flow_combiner_add_pad (demux->flowcombiner, context->pad);
1246 gst_matroska_demux_query (GstMatroskaDemux * demux, GstPad * pad,
1249 gboolean res = FALSE;
1250 GstMatroskaTrackContext *context = NULL;
1253 context = gst_pad_get_element_private (pad);
1256 switch (GST_QUERY_TYPE (query)) {
1257 case GST_QUERY_POSITION:
1261 gst_query_parse_position (query, &format, NULL);
1264 if (format == GST_FORMAT_TIME) {
1265 GST_OBJECT_LOCK (demux);
1267 gst_query_set_position (query, GST_FORMAT_TIME,
1268 MAX (context->pos, demux->stream_start_time) -
1269 demux->stream_start_time);
1271 gst_query_set_position (query, GST_FORMAT_TIME,
1272 MAX (demux->common.segment.position, demux->stream_start_time) -
1273 demux->stream_start_time);
1274 GST_OBJECT_UNLOCK (demux);
1275 } else if (format == GST_FORMAT_DEFAULT && context
1276 && context->default_duration) {
1277 GST_OBJECT_LOCK (demux);
1278 gst_query_set_position (query, GST_FORMAT_DEFAULT,
1279 context->pos / context->default_duration);
1280 GST_OBJECT_UNLOCK (demux);
1282 GST_DEBUG_OBJECT (demux,
1283 "only position query in TIME and DEFAULT format is supported");
1289 case GST_QUERY_DURATION:
1293 gst_query_parse_duration (query, &format, NULL);
1296 if (format == GST_FORMAT_TIME) {
1297 GST_OBJECT_LOCK (demux);
1298 gst_query_set_duration (query, GST_FORMAT_TIME,
1299 demux->common.segment.duration);
1300 GST_OBJECT_UNLOCK (demux);
1301 } else if (format == GST_FORMAT_DEFAULT && context
1302 && context->default_duration) {
1303 GST_OBJECT_LOCK (demux);
1304 gst_query_set_duration (query, GST_FORMAT_DEFAULT,
1305 demux->common.segment.duration / context->default_duration);
1306 GST_OBJECT_UNLOCK (demux);
1308 GST_DEBUG_OBJECT (demux,
1309 "only duration query in TIME and DEFAULT format is supported");
1315 case GST_QUERY_SEEKING:
1319 gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
1320 GST_OBJECT_LOCK (demux);
1321 if (fmt == GST_FORMAT_TIME) {
1324 if (demux->streaming) {
1325 /* assuming we'll be able to get an index ... */
1326 seekable = demux->seekable;
1331 gst_query_set_seeking (query, GST_FORMAT_TIME, seekable,
1332 0, demux->common.segment.duration);
1335 GST_OBJECT_UNLOCK (demux);
1338 case GST_QUERY_SEGMENT:
1343 format = demux->common.segment.format;
1346 gst_segment_to_stream_time (&demux->common.segment, format,
1347 demux->common.segment.start);
1348 if ((stop = demux->common.segment.stop) == -1)
1349 stop = demux->common.segment.duration;
1352 gst_segment_to_stream_time (&demux->common.segment, format, stop);
1354 gst_query_set_segment (query, demux->common.segment.rate, format, start,
1361 res = gst_pad_query_default (pad, (GstObject *) demux, query);
1364 GST_ELEMENT_CLASS (parent_class)->query (GST_ELEMENT_CAST (demux),
1373 gst_matroska_demux_element_query (GstElement * element, GstQuery * query)
1375 return gst_matroska_demux_query (GST_MATROSKA_DEMUX (element), NULL, query);
1379 gst_matroska_demux_handle_src_query (GstPad * pad, GstObject * parent,
1382 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
1384 return gst_matroska_demux_query (demux, pad, query);
1387 /* returns FALSE if there are no pads to deliver event to,
1388 * otherwise TRUE (whatever the outcome of event sending),
1389 * takes ownership of the passed event! */
1391 gst_matroska_demux_send_event (GstMatroskaDemux * demux, GstEvent * event)
1393 gboolean is_segment;
1394 gboolean ret = FALSE;
1397 g_return_val_if_fail (event != NULL, FALSE);
1399 GST_DEBUG_OBJECT (demux, "Sending event of type %s to all source pads",
1400 GST_EVENT_TYPE_NAME (event));
1402 is_segment = (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT);
1404 g_assert (demux->common.src->len == demux->common.num_streams);
1405 for (i = 0; i < demux->common.src->len; i++) {
1406 GstMatroskaTrackContext *stream;
1408 stream = g_ptr_array_index (demux->common.src, i);
1409 gst_event_ref (event);
1410 gst_pad_push_event (stream->pad, event);
1413 /* FIXME: send global tags before stream tags */
1414 if (G_UNLIKELY (is_segment && stream->pending_tags != NULL)) {
1415 GST_DEBUG_OBJECT (demux, "Sending pending_tags %p for pad %s:%s : %"
1416 GST_PTR_FORMAT, stream->pending_tags,
1417 GST_DEBUG_PAD_NAME (stream->pad), stream->pending_tags);
1418 gst_pad_push_event (stream->pad,
1419 gst_event_new_tag (stream->pending_tags));
1420 stream->pending_tags = NULL;
1424 if (G_UNLIKELY (is_segment && demux->common.global_tags != NULL)) {
1425 GstEvent *tag_event;
1426 gst_tag_list_add (demux->common.global_tags, GST_TAG_MERGE_REPLACE,
1427 GST_TAG_CONTAINER_FORMAT, "Matroska", NULL);
1428 GST_DEBUG_OBJECT (demux, "Sending global_tags %p : %" GST_PTR_FORMAT,
1429 demux->common.global_tags, demux->common.global_tags);
1431 tag_event = gst_event_new_tag (demux->common.global_tags);
1433 for (i = 0; i < demux->common.src->len; i++) {
1434 GstMatroskaTrackContext *stream;
1436 stream = g_ptr_array_index (demux->common.src, i);
1437 gst_pad_push_event (stream->pad, gst_event_ref (tag_event));
1440 gst_event_unref (tag_event);
1441 demux->common.global_tags = NULL;
1444 gst_event_unref (event);
1449 gst_matroska_demux_element_send_event (GstElement * element, GstEvent * event)
1451 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
1454 g_return_val_if_fail (event != NULL, FALSE);
1456 if (GST_EVENT_TYPE (event) == GST_EVENT_SEEK) {
1457 res = gst_matroska_demux_handle_seek_event (demux, NULL, event);
1459 GST_WARNING_OBJECT (demux, "Unhandled event of type %s",
1460 GST_EVENT_TYPE_NAME (event));
1463 gst_event_unref (event);
1468 gst_matroska_demux_move_to_entry (GstMatroskaDemux * demux,
1469 GstMatroskaIndex * entry, gboolean reset, gboolean update)
1473 GST_OBJECT_LOCK (demux);
1476 /* seek (relative to matroska segment) */
1477 /* position might be invalid; will error when streaming resumes ... */
1478 demux->common.offset = entry->pos + demux->common.ebml_segment_start;
1479 demux->next_cluster_offset = 0;
1481 GST_DEBUG_OBJECT (demux,
1482 "Seeked to offset %" G_GUINT64_FORMAT ", block %d, " "time %"
1483 GST_TIME_FORMAT, entry->pos + demux->common.ebml_segment_start,
1484 entry->block, GST_TIME_ARGS (entry->time));
1486 /* update the time */
1487 gst_matroska_read_common_reset_streams (&demux->common, entry->time, TRUE);
1488 demux->common.segment.position = entry->time;
1489 demux->seek_block = entry->block;
1490 demux->seek_first = TRUE;
1491 demux->last_stop_end = GST_CLOCK_TIME_NONE;
1494 for (i = 0; i < demux->common.src->len; i++) {
1495 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
1498 stream->to_offset = G_MAXINT64;
1500 if (stream->from_offset != -1)
1501 stream->to_offset = stream->from_offset;
1503 stream->from_offset = -1;
1504 stream->from_time = GST_CLOCK_TIME_NONE;
1507 GST_OBJECT_UNLOCK (demux);
1513 gst_matroska_cluster_compare (gint64 * i1, gint64 * i2)
1523 /* searches for a cluster start from @pos,
1524 * return GST_FLOW_OK and cluster position in @pos if found */
1525 static GstFlowReturn
1526 gst_matroska_demux_search_cluster (GstMatroskaDemux * demux, gint64 * pos)
1528 gint64 newpos = *pos;
1530 GstFlowReturn ret = GST_FLOW_OK;
1531 const guint chunk = 64 * 1024;
1532 GstBuffer *buf = NULL;
1534 gpointer data = NULL;
1540 orig_offset = demux->common.offset;
1542 GST_LOG_OBJECT (demux, "searching cluster following offset %" G_GINT64_FORMAT,
1545 if (demux->clusters) {
1548 cpos = gst_util_array_binary_search (demux->clusters->data,
1549 demux->clusters->len, sizeof (gint64),
1550 (GCompareDataFunc) gst_matroska_cluster_compare,
1551 GST_SEARCH_MODE_AFTER, pos, NULL);
1554 GST_DEBUG_OBJECT (demux,
1555 "cluster reported at offset %" G_GINT64_FORMAT, *cpos);
1556 demux->common.offset = *cpos;
1557 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1558 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1559 if (ret == GST_FLOW_OK && id == GST_MATROSKA_ID_CLUSTER) {
1566 /* read in at newpos and scan for ebml cluster id */
1568 GstByteReader reader;
1572 gst_buffer_unmap (buf, &map);
1573 gst_buffer_unref (buf);
1576 ret = gst_pad_pull_range (demux->common.sinkpad, newpos, chunk, &buf);
1577 if (ret != GST_FLOW_OK)
1579 GST_DEBUG_OBJECT (demux,
1580 "read buffer size %" G_GSIZE_FORMAT " at offset %" G_GINT64_FORMAT,
1581 gst_buffer_get_size (buf), newpos);
1582 gst_buffer_map (buf, &map, GST_MAP_READ);
1585 gst_byte_reader_init (&reader, data, size);
1587 cluster_pos = gst_byte_reader_masked_scan_uint32 (&reader, 0xffffffff,
1588 GST_MATROSKA_ID_CLUSTER, 0, gst_byte_reader_get_remaining (&reader));
1589 if (cluster_pos >= 0) {
1590 newpos += cluster_pos;
1591 /* prepare resuming at next byte */
1592 if (!gst_byte_reader_skip (&reader, cluster_pos + 1)) {
1593 GST_DEBUG_OBJECT (demux, "Need more data -> continue");
1596 GST_DEBUG_OBJECT (demux,
1597 "found cluster ebml id at offset %" G_GINT64_FORMAT, newpos);
1598 /* extra checks whether we really sync'ed to a cluster:
1599 * - either it is the first and only cluster
1600 * - either there is a cluster after this one
1601 * - either cluster length is undefined
1603 /* ok if first cluster (there may not a subsequent one) */
1604 if (newpos == demux->first_cluster_offset) {
1605 GST_DEBUG_OBJECT (demux, "cluster is first cluster -> OK");
1608 demux->common.offset = newpos;
1609 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1610 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1611 if (ret != GST_FLOW_OK) {
1612 GST_DEBUG_OBJECT (demux, "need more data -> continue");
1615 g_assert (id == GST_MATROSKA_ID_CLUSTER);
1616 GST_DEBUG_OBJECT (demux, "cluster size %" G_GUINT64_FORMAT ", prefix %d",
1618 /* ok if undefined length or first cluster */
1619 if (length == GST_EBML_SIZE_UNKNOWN || length == G_MAXUINT64) {
1620 GST_DEBUG_OBJECT (demux, "cluster has undefined length -> OK");
1624 demux->common.offset += length + needed;
1625 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1626 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1627 if (ret != GST_FLOW_OK)
1629 GST_DEBUG_OBJECT (demux, "next element is %scluster",
1630 id == GST_MATROSKA_ID_CLUSTER ? "" : "not ");
1631 if (id == GST_MATROSKA_ID_CLUSTER)
1633 /* not ok, resume */
1636 /* partial cluster id may have been in tail of buffer */
1637 newpos += MAX (gst_byte_reader_get_remaining (&reader), 4) - 3;
1642 gst_buffer_unmap (buf, &map);
1643 gst_buffer_unref (buf);
1648 demux->common.offset = orig_offset;
1653 /* bisect and scan through file for cluster starting before @time,
1654 * returns fake index entry with corresponding info on cluster */
1655 static GstMatroskaIndex *
1656 gst_matroska_demux_search_pos (GstMatroskaDemux * demux, GstClockTime time)
1658 GstMatroskaIndex *entry = NULL;
1659 GstMatroskaReadState current_state;
1660 GstClockTime otime, prev_cluster_time, current_cluster_time, cluster_time;
1661 gint64 opos, newpos, startpos = 0, current_offset;
1662 gint64 prev_cluster_offset = -1, current_cluster_offset, cluster_offset;
1663 const guint chunk = 64 * 1024;
1669 /* (under)estimate new position, resync using cluster ebml id,
1670 * and scan forward to appropriate cluster
1671 * (and re-estimate if need to go backward) */
1673 prev_cluster_time = GST_CLOCK_TIME_NONE;
1675 /* store some current state */
1676 current_state = demux->common.state;
1677 g_return_val_if_fail (current_state == GST_MATROSKA_READ_STATE_DATA, NULL);
1679 current_cluster_offset = demux->cluster_offset;
1680 current_cluster_time = demux->cluster_time;
1681 current_offset = demux->common.offset;
1683 demux->common.state = GST_MATROSKA_READ_STATE_SCANNING;
1685 /* estimate using start and current position */
1686 GST_OBJECT_LOCK (demux);
1687 opos = demux->common.offset - demux->common.ebml_segment_start;
1688 otime = demux->common.segment.position;
1689 GST_OBJECT_UNLOCK (demux);
1692 time = MAX (time, demux->stream_start_time);
1694 /* avoid division by zero in first estimation below */
1695 if (otime <= demux->stream_start_time)
1699 GST_LOG_OBJECT (demux,
1700 "opos: %" G_GUINT64_FORMAT ", otime: %" GST_TIME_FORMAT ", %"
1701 GST_TIME_FORMAT " in stream time (start %" GST_TIME_FORMAT "), time %"
1702 GST_TIME_FORMAT, opos, GST_TIME_ARGS (otime),
1703 GST_TIME_ARGS (otime - demux->stream_start_time),
1704 GST_TIME_ARGS (demux->stream_start_time), GST_TIME_ARGS (time));
1706 if (otime <= demux->stream_start_time) {
1710 gst_util_uint64_scale (opos - demux->common.ebml_segment_start,
1711 time - demux->stream_start_time,
1712 otime - demux->stream_start_time) - chunk;
1716 /* favour undershoot */
1717 newpos = newpos * 90 / 100;
1718 newpos += demux->common.ebml_segment_start;
1720 GST_DEBUG_OBJECT (demux,
1721 "estimated offset for %" GST_TIME_FORMAT ": %" G_GINT64_FORMAT,
1722 GST_TIME_ARGS (time), newpos);
1724 /* and at least start scanning before previous scan start to avoid looping */
1725 startpos = startpos * 90 / 100;
1726 if (startpos && startpos < newpos)
1729 /* read in at newpos and scan for ebml cluster id */
1733 ret = gst_matroska_demux_search_cluster (demux, &newpos);
1734 if (ret == GST_FLOW_EOS) {
1735 /* heuristic HACK */
1736 newpos = startpos * 80 / 100;
1737 GST_DEBUG_OBJECT (demux, "EOS; "
1738 "new estimated offset for %" GST_TIME_FORMAT ": %" G_GINT64_FORMAT,
1739 GST_TIME_ARGS (time), newpos);
1742 } else if (ret != GST_FLOW_OK) {
1749 /* then start scanning and parsing for cluster time,
1750 * re-estimate if overshoot, otherwise next cluster and so on */
1751 demux->common.offset = newpos;
1752 demux->cluster_time = cluster_time = GST_CLOCK_TIME_NONE;
1754 guint64 cluster_size = 0;
1756 /* peek and parse some elements */
1757 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1758 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1759 if (ret != GST_FLOW_OK)
1761 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
1762 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
1764 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
1765 if (ret != GST_FLOW_OK)
1768 if (id == GST_MATROSKA_ID_CLUSTER) {
1769 cluster_time = GST_CLOCK_TIME_NONE;
1770 if (length == G_MAXUINT64)
1773 cluster_size = length + needed;
1775 if (demux->cluster_time != GST_CLOCK_TIME_NONE &&
1776 cluster_time == GST_CLOCK_TIME_NONE) {
1777 cluster_time = demux->cluster_time * demux->common.time_scale;
1778 cluster_offset = demux->cluster_offset;
1779 GST_DEBUG_OBJECT (demux, "found cluster at offset %" G_GINT64_FORMAT
1780 " with time %" GST_TIME_FORMAT, cluster_offset,
1781 GST_TIME_ARGS (cluster_time));
1782 if (cluster_time > time) {
1783 GST_DEBUG_OBJECT (demux, "overshot target");
1784 /* cluster overshoots */
1785 if (cluster_offset == demux->first_cluster_offset) {
1786 /* but no prev one */
1787 GST_DEBUG_OBJECT (demux, "but using first cluster anyway");
1788 prev_cluster_time = cluster_time;
1789 prev_cluster_offset = cluster_offset;
1792 if (prev_cluster_time != GST_CLOCK_TIME_NONE) {
1793 /* prev cluster did not overshoot, so prev cluster is target */
1796 /* re-estimate using this new position info */
1797 opos = cluster_offset;
1798 otime = cluster_time;
1802 /* cluster undershoots, goto next one */
1803 prev_cluster_time = cluster_time;
1804 prev_cluster_offset = cluster_offset;
1805 /* skip cluster if length is defined,
1806 * otherwise will be skippingly parsed into */
1808 GST_DEBUG_OBJECT (demux, "skipping to next cluster");
1809 demux->common.offset = cluster_offset + cluster_size;
1810 demux->cluster_time = GST_CLOCK_TIME_NONE;
1812 GST_DEBUG_OBJECT (demux, "parsing/skipping cluster elements");
1819 if (ret == GST_FLOW_EOS) {
1820 if (prev_cluster_time != GST_CLOCK_TIME_NONE)
1826 entry = g_new0 (GstMatroskaIndex, 1);
1827 entry->time = prev_cluster_time;
1828 entry->pos = prev_cluster_offset - demux->common.ebml_segment_start;
1829 GST_DEBUG_OBJECT (demux, "simulated index entry; time %" GST_TIME_FORMAT
1830 ", pos %" G_GUINT64_FORMAT, GST_TIME_ARGS (entry->time), entry->pos);
1834 /* restore some state */
1835 demux->cluster_offset = current_cluster_offset;
1836 demux->cluster_time = current_cluster_time;
1837 demux->common.offset = current_offset;
1838 demux->common.state = current_state;
1844 gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
1845 GstPad * pad, GstEvent * event)
1847 GstMatroskaIndex *entry = NULL;
1848 GstMatroskaIndex scan_entry;
1850 GstSeekType cur_type, stop_type;
1852 gboolean flush, keyunit, before, after, snap_next;
1855 GstMatroskaTrackContext *track = NULL;
1856 GstSegment seeksegment = { 0, };
1857 gboolean update = TRUE;
1858 gboolean pad_locked = FALSE;
1862 track = gst_pad_get_element_private (pad);
1864 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
1866 seqnum = gst_event_get_seqnum (event);
1868 /* we can only seek on time */
1869 if (format != GST_FORMAT_TIME) {
1870 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
1874 /* copy segment, we need this because we still need the old
1875 * segment when we close the current segment. */
1876 memcpy (&seeksegment, &demux->common.segment, sizeof (GstSegment));
1878 /* pull mode without index means that the actual duration is not known,
1879 * we might be playing a file that's still being recorded
1880 * so, invalidate our current duration, which is only a moving target,
1881 * and should not be used to clamp anything */
1882 if (!demux->streaming && !demux->common.index && demux->invalid_duration) {
1883 seeksegment.duration = GST_CLOCK_TIME_NONE;
1887 GST_DEBUG_OBJECT (demux, "configuring seek");
1888 gst_segment_do_seek (&seeksegment, rate, format, flags,
1889 cur_type, cur, stop_type, stop, &update);
1890 /* compensate for clip start time, but only for SET seeks,
1891 * otherwise it is already part of the segments */
1892 if (GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
1893 if (cur_type == GST_SEEK_TYPE_SET) {
1895 seeksegment.position += demux->stream_start_time;
1896 seeksegment.start += demux->stream_start_time;
1898 if (stop_type == GST_SEEK_TYPE_SET
1899 && GST_CLOCK_TIME_IS_VALID (seeksegment.stop)) {
1901 seeksegment.position += demux->stream_start_time;
1902 seeksegment.stop += demux->stream_start_time;
1907 /* restore segment duration (if any effect),
1908 * would be determined again when parsing, but anyway ... */
1909 seeksegment.duration = demux->common.segment.duration;
1911 flush = ! !(flags & GST_SEEK_FLAG_FLUSH);
1912 keyunit = ! !(flags & GST_SEEK_FLAG_KEY_UNIT);
1913 after = ! !(flags & GST_SEEK_FLAG_SNAP_AFTER);
1914 before = ! !(flags & GST_SEEK_FLAG_SNAP_BEFORE);
1916 /* always do full update if flushing,
1917 * otherwise problems might arise downstream with missing keyframes etc */
1918 update = update || flush;
1920 GST_DEBUG_OBJECT (demux, "New segment %" GST_SEGMENT_FORMAT, &seeksegment);
1922 /* check sanity before we start flushing and all that */
1923 snap_next = after && !before;
1924 if (seeksegment.rate < 0)
1925 snap_next = !snap_next;
1926 GST_OBJECT_LOCK (demux);
1927 track = gst_matroska_read_common_get_seek_track (&demux->common, track);
1928 if ((entry = gst_matroska_read_common_do_index_seek (&demux->common, track,
1929 seeksegment.position, &demux->seek_index, &demux->seek_entry,
1930 snap_next)) == NULL) {
1931 /* pull mode without index can scan later on */
1932 if (demux->streaming) {
1933 GST_DEBUG_OBJECT (demux, "No matching seek entry in index");
1934 GST_OBJECT_UNLOCK (demux);
1936 } else if (rate < 0.0) {
1937 /* FIXME: We should build an index during playback or when scanning
1938 * that can be used here. The reverse playback code requires seek_index
1939 * and seek_entry to be set!
1941 GST_DEBUG_OBJECT (demux,
1942 "No matching seek entry in index, needed for reverse playback");
1943 GST_OBJECT_UNLOCK (demux);
1947 GST_DEBUG_OBJECT (demux, "Seek position looks sane");
1948 GST_OBJECT_UNLOCK (demux);
1951 /* only have to update some segment,
1952 * but also still have to honour flush and so on */
1953 GST_DEBUG_OBJECT (demux, "... no update");
1954 /* bad goto, bad ... */
1958 if (demux->streaming)
1963 GstEvent *flush_event = gst_event_new_flush_start ();
1964 gst_event_set_seqnum (flush_event, seqnum);
1965 GST_DEBUG_OBJECT (demux, "Starting flush");
1966 gst_pad_push_event (demux->common.sinkpad, gst_event_ref (flush_event));
1967 gst_matroska_demux_send_event (demux, flush_event);
1969 GST_DEBUG_OBJECT (demux, "Non-flushing seek, pausing task");
1970 gst_pad_pause_task (demux->common.sinkpad);
1974 GST_PAD_STREAM_LOCK (demux->common.sinkpad);
1979 /* now grab the stream lock so that streaming cannot continue, for
1980 * non flushing seeks when the element is in PAUSED this could block
1982 GST_DEBUG_OBJECT (demux, "Waiting for streaming to stop");
1983 GST_PAD_STREAM_LOCK (demux->common.sinkpad);
1986 /* pull mode without index can do some scanning */
1987 if (!demux->streaming && !entry) {
1988 GstEvent *flush_event;
1990 /* need to stop flushing upstream as we need it next */
1992 flush_event = gst_event_new_flush_stop (TRUE);
1993 gst_event_set_seqnum (flush_event, seqnum);
1994 gst_pad_push_event (demux->common.sinkpad, flush_event);
1996 entry = gst_matroska_demux_search_pos (demux, seeksegment.position);
1997 /* keep local copy */
1999 scan_entry = *entry;
2001 entry = &scan_entry;
2003 GST_DEBUG_OBJECT (demux, "Scan failed to find matching position");
2005 flush_event = gst_event_new_flush_stop (TRUE);
2006 gst_event_set_seqnum (flush_event, seqnum);
2007 gst_matroska_demux_send_event (demux, flush_event);
2015 GST_DEBUG_OBJECT (demux, "seek to key unit, adjusting segment start from %"
2016 GST_TIME_FORMAT " to %" GST_TIME_FORMAT,
2017 GST_TIME_ARGS (seeksegment.start), GST_TIME_ARGS (entry->time));
2018 seeksegment.start = MAX (entry->time, demux->stream_start_time);
2019 seeksegment.position = seeksegment.start;
2020 seeksegment.time = seeksegment.start - demux->stream_start_time;
2023 if (demux->streaming) {
2024 GST_OBJECT_LOCK (demux);
2025 /* track real position we should start at */
2026 GST_DEBUG_OBJECT (demux, "storing segment start");
2027 demux->requested_seek_time = seeksegment.position;
2028 demux->seek_offset = entry->pos + demux->common.ebml_segment_start;
2029 GST_OBJECT_UNLOCK (demux);
2030 /* need to seek to cluster start to pick up cluster time */
2031 /* upstream takes care of flushing and all that
2032 * ... and newsegment event handling takes care of the rest */
2033 return perform_seek_to_offset (demux, rate,
2034 entry->pos + demux->common.ebml_segment_start, seqnum);
2039 GstEvent *flush_event = gst_event_new_flush_stop (TRUE);
2040 gst_event_set_seqnum (flush_event, seqnum);
2041 GST_DEBUG_OBJECT (demux, "Stopping flush");
2042 gst_pad_push_event (demux->common.sinkpad, gst_event_ref (flush_event));
2043 gst_matroska_demux_send_event (demux, flush_event);
2046 GST_OBJECT_LOCK (demux);
2047 /* now update the real segment info */
2048 GST_DEBUG_OBJECT (demux, "Committing new seek segment");
2049 memcpy (&demux->common.segment, &seeksegment, sizeof (GstSegment));
2050 GST_OBJECT_UNLOCK (demux);
2052 /* update some (segment) state */
2053 if (!gst_matroska_demux_move_to_entry (demux, entry, TRUE, update))
2056 /* notify start of new segment */
2057 if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
2060 msg = gst_message_new_segment_start (GST_OBJECT (demux),
2061 GST_FORMAT_TIME, demux->common.segment.start);
2062 gst_message_set_seqnum (msg, seqnum);
2063 gst_element_post_message (GST_ELEMENT (demux), msg);
2066 GST_OBJECT_LOCK (demux);
2067 if (demux->new_segment)
2068 gst_event_unref (demux->new_segment);
2070 /* On port from 0.10, discarded !update (for segment.update) here, FIXME? */
2071 demux->new_segment = gst_event_new_segment (&demux->common.segment);
2072 gst_event_set_seqnum (demux->new_segment, seqnum);
2073 if (demux->common.segment.rate < 0 && demux->common.segment.stop == -1)
2074 demux->to_time = demux->common.segment.position;
2076 demux->to_time = GST_CLOCK_TIME_NONE;
2077 GST_OBJECT_UNLOCK (demux);
2079 /* restart our task since it might have been stopped when we did the
2081 gst_pad_start_task (demux->common.sinkpad,
2082 (GstTaskFunction) gst_matroska_demux_loop, demux->common.sinkpad, NULL);
2084 /* streaming can continue now */
2086 GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
2094 GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
2096 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Got a seek error"));
2102 * Handle whether we can perform the seek event or if we have to let the chain
2103 * function handle seeks to build the seek indexes first.
2106 gst_matroska_demux_handle_seek_push (GstMatroskaDemux * demux, GstPad * pad,
2110 GstSeekType cur_type, stop_type;
2115 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
2120 /* we can only seek on time */
2121 if (format != GST_FORMAT_TIME) {
2122 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
2126 if (stop_type != GST_SEEK_TYPE_NONE && stop != GST_CLOCK_TIME_NONE) {
2127 GST_DEBUG_OBJECT (demux, "Seek end-time not supported in streaming mode");
2131 if (!(flags & GST_SEEK_FLAG_FLUSH)) {
2132 GST_DEBUG_OBJECT (demux,
2133 "Non-flushing seek not supported in streaming mode");
2137 if (flags & GST_SEEK_FLAG_SEGMENT) {
2138 GST_DEBUG_OBJECT (demux, "Segment seek not supported in streaming mode");
2142 /* check for having parsed index already */
2143 if (!demux->common.index_parsed) {
2144 gboolean building_index;
2147 if (!demux->index_offset) {
2148 GST_DEBUG_OBJECT (demux, "no index (location); no seek in push mode");
2152 GST_OBJECT_LOCK (demux);
2153 /* handle the seek event in the chain function */
2154 demux->common.state = GST_MATROSKA_READ_STATE_SEEK;
2155 /* no more seek can be issued until state reset to _DATA */
2157 /* copy the event */
2158 if (demux->seek_event)
2159 gst_event_unref (demux->seek_event);
2160 demux->seek_event = gst_event_ref (event);
2162 /* set the building_index flag so that only one thread can setup the
2163 * structures for index seeking. */
2164 building_index = demux->building_index;
2165 if (!building_index) {
2166 demux->building_index = TRUE;
2167 offset = demux->index_offset;
2169 GST_OBJECT_UNLOCK (demux);
2171 if (!building_index) {
2172 /* seek to the first subindex or legacy index */
2173 GST_INFO_OBJECT (demux, "Seeking to Cues at %" G_GUINT64_FORMAT, offset);
2174 return perform_seek_to_offset (demux, rate, offset,
2175 gst_event_get_seqnum (event));
2178 /* well, we are handling it already */
2182 /* delegate to tweaked regular seek */
2183 return gst_matroska_demux_handle_seek_event (demux, pad, event);
2187 gst_matroska_demux_handle_src_event (GstPad * pad, GstObject * parent,
2190 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
2191 gboolean res = TRUE;
2193 switch (GST_EVENT_TYPE (event)) {
2194 case GST_EVENT_SEEK:
2195 /* no seeking until we are (safely) ready */
2196 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
2197 GST_DEBUG_OBJECT (demux, "not ready for seeking yet");
2200 if (!demux->streaming)
2201 res = gst_matroska_demux_handle_seek_event (demux, pad, event);
2203 res = gst_matroska_demux_handle_seek_push (demux, pad, event);
2204 gst_event_unref (event);
2209 GstMatroskaTrackContext *context = gst_pad_get_element_private (pad);
2210 if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
2211 GstMatroskaTrackVideoContext *videocontext =
2212 (GstMatroskaTrackVideoContext *) context;
2214 GstClockTimeDiff diff;
2215 GstClockTime timestamp;
2217 gst_event_parse_qos (event, NULL, &proportion, &diff, ×tamp);
2219 GST_OBJECT_LOCK (demux);
2220 videocontext->earliest_time = timestamp + diff;
2221 GST_OBJECT_UNLOCK (demux);
2224 gst_event_unref (event);
2228 case GST_EVENT_TOC_SELECT:
2231 GstTocEntry *entry = NULL;
2232 GstEvent *seek_event;
2235 if (!demux->common.toc) {
2236 GST_DEBUG_OBJECT (demux, "no TOC to select");
2239 gst_event_parse_toc_select (event, &uid);
2241 GST_OBJECT_LOCK (demux);
2242 entry = gst_toc_find_entry (demux->common.toc, uid);
2243 if (entry == NULL) {
2244 GST_OBJECT_UNLOCK (demux);
2245 GST_WARNING_OBJECT (demux, "no TOC entry with given UID: %s", uid);
2248 gst_toc_entry_get_start_stop_times (entry, &start_pos, NULL);
2249 GST_OBJECT_UNLOCK (demux);
2250 seek_event = gst_event_new_seek (1.0,
2252 GST_SEEK_FLAG_FLUSH,
2253 GST_SEEK_TYPE_SET, start_pos, GST_SEEK_TYPE_SET, -1);
2254 res = gst_matroska_demux_handle_seek_event (demux, pad, seek_event);
2255 gst_event_unref (seek_event);
2259 GST_WARNING_OBJECT (demux, "received empty TOC select event");
2263 gst_event_unref (event);
2267 /* events we don't need to handle */
2268 case GST_EVENT_NAVIGATION:
2269 gst_event_unref (event);
2273 case GST_EVENT_LATENCY:
2275 res = gst_pad_push_event (demux->common.sinkpad, event);
2282 static GstFlowReturn
2283 gst_matroska_demux_seek_to_previous_keyframe (GstMatroskaDemux * demux)
2285 GstFlowReturn ret = GST_FLOW_EOS;
2286 gboolean done = TRUE;
2289 g_return_val_if_fail (demux->seek_index, GST_FLOW_EOS);
2290 g_return_val_if_fail (demux->seek_entry < demux->seek_index->len,
2293 GST_DEBUG_OBJECT (demux, "locating previous keyframe");
2295 if (!demux->seek_entry) {
2296 GST_DEBUG_OBJECT (demux, "no earlier index entry");
2300 for (i = 0; i < demux->common.src->len; i++) {
2301 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
2303 GST_DEBUG_OBJECT (demux, "segment start %" GST_TIME_FORMAT
2304 ", stream %d at %" GST_TIME_FORMAT,
2305 GST_TIME_ARGS (demux->common.segment.start), stream->index,
2306 GST_TIME_ARGS (stream->from_time));
2307 if (GST_CLOCK_TIME_IS_VALID (stream->from_time)) {
2308 if (stream->from_time > demux->common.segment.start) {
2309 GST_DEBUG_OBJECT (demux, "stream %d not finished yet", stream->index);
2313 /* nothing pushed for this stream;
2314 * likely seek entry did not start at keyframe, so all was skipped.
2315 * So we need an earlier entry */
2321 GstMatroskaIndex *entry;
2323 entry = &g_array_index (demux->seek_index, GstMatroskaIndex,
2324 --demux->seek_entry);
2325 if (!gst_matroska_demux_move_to_entry (demux, entry, FALSE, TRUE))
2335 static GstFlowReturn
2336 gst_matroska_demux_parse_tracks (GstMatroskaDemux * demux, GstEbmlRead * ebml)
2338 GstFlowReturn ret = GST_FLOW_OK;
2341 DEBUG_ELEMENT_START (demux, ebml, "Tracks");
2343 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2344 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
2348 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
2349 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
2353 /* one track within the "all-tracks" header */
2354 case GST_MATROSKA_ID_TRACKENTRY:
2355 ret = gst_matroska_demux_add_stream (demux, ebml);
2359 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
2364 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
2366 demux->tracks_parsed = TRUE;
2372 * Read signed/unsigned "EBML" numbers.
2373 * Return: number of bytes processed.
2377 gst_matroska_ebmlnum_uint (guint8 * data, guint size, guint64 * num)
2379 gint len_mask = 0x80, read = 1, n = 1, num_ffs = 0;
2387 while (read <= 8 && !(total & len_mask)) {
2394 if ((total &= (len_mask - 1)) == len_mask - 1)
2399 if (data[n] == 0xff)
2401 total = (total << 8) | data[n];
2405 if (read == num_ffs && total != 0)
2414 gst_matroska_ebmlnum_sint (guint8 * data, guint size, gint64 * num)
2419 /* read as unsigned number first */
2420 if ((res = gst_matroska_ebmlnum_uint (data, size, &unum)) < 0)
2424 if (unum == G_MAXUINT64)
2427 *num = unum - ((1 << ((7 * res) - 1)) - 1);
2433 * Mostly used for subtitles. We add void filler data for each
2434 * lagging stream to make sure we don't deadlock.
2438 gst_matroska_demux_sync_streams (GstMatroskaDemux * demux)
2442 GST_OBJECT_LOCK (demux);
2444 GST_LOG_OBJECT (demux, "Sync to %" GST_TIME_FORMAT,
2445 GST_TIME_ARGS (demux->common.segment.position));
2447 g_assert (demux->common.num_streams == demux->common.src->len);
2448 for (stream_nr = 0; stream_nr < demux->common.src->len; stream_nr++) {
2449 GstMatroskaTrackContext *context;
2451 context = g_ptr_array_index (demux->common.src, stream_nr);
2453 GST_LOG_OBJECT (demux,
2454 "Checking for resync on stream %d (%" GST_TIME_FORMAT ")", stream_nr,
2455 GST_TIME_ARGS (context->pos));
2457 if (G_LIKELY (context->type != GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
2458 GST_LOG_OBJECT (demux, "Skipping sync on non-subtitle stream");
2462 /* does it lag? 0.5 seconds is a random threshold...
2463 * lag need only be considered if we have advanced into requested segment */
2464 if (GST_CLOCK_TIME_IS_VALID (context->pos) &&
2465 GST_CLOCK_TIME_IS_VALID (demux->common.segment.position) &&
2466 demux->common.segment.position > demux->common.segment.start &&
2467 context->pos + (GST_SECOND / 2) < demux->common.segment.position) {
2470 guint64 start = context->pos;
2471 guint64 stop = demux->common.segment.position - (GST_SECOND / 2);
2473 GST_DEBUG_OBJECT (demux,
2474 "Synchronizing stream %d with other by advancing time from %"
2475 GST_TIME_FORMAT " to %" GST_TIME_FORMAT, stream_nr,
2476 GST_TIME_ARGS (start), GST_TIME_ARGS (stop));
2478 context->pos = stop;
2480 event = gst_event_new_gap (start, stop - start);
2481 GST_OBJECT_UNLOCK (demux);
2482 gst_pad_push_event (context->pad, event);
2483 GST_OBJECT_LOCK (demux);
2487 GST_OBJECT_UNLOCK (demux);
2490 static GstFlowReturn
2491 gst_matroska_demux_push_stream_headers (GstMatroskaDemux * demux,
2492 GstMatroskaTrackContext * stream)
2494 GstFlowReturn ret = GST_FLOW_OK;
2497 num = gst_buffer_list_length (stream->stream_headers);
2498 for (i = 0; i < num; ++i) {
2501 buf = gst_buffer_list_get (stream->stream_headers, i);
2502 buf = gst_buffer_copy (buf);
2504 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
2506 if (stream->set_discont) {
2507 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
2508 stream->set_discont = FALSE;
2510 GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DISCONT);
2513 /* push out all headers in one go and use last flow return */
2514 ret = gst_pad_push (stream->pad, buf);
2517 /* don't need these any longer */
2518 gst_buffer_list_unref (stream->stream_headers);
2519 stream->stream_headers = NULL;
2522 ret = gst_flow_combiner_update_flow (demux->flowcombiner, ret);
2528 gst_matroska_demux_push_dvd_clut_change_event (GstMatroskaDemux * demux,
2529 GstMatroskaTrackContext * stream)
2533 g_assert (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB));
2535 if (!stream->codec_priv)
2538 /* ideally, VobSub private data should be parsed and stored more convenient
2539 * elsewhere, but for now, only interested in a small part */
2541 /* make sure we have terminating 0 */
2542 buf = g_strndup (stream->codec_priv, stream->codec_priv_size);
2544 /* just locate and parse palette part */
2545 start = strstr (buf, "palette:");
2550 guint8 r, g, b, y, u, v;
2553 while (g_ascii_isspace (*start))
2555 for (i = 0; i < 16; i++) {
2556 if (sscanf (start, "%06x", &col) != 1)
2559 while ((*start == ',') || g_ascii_isspace (*start))
2561 /* sigh, need to convert this from vobsub pseudo-RGB to YUV */
2562 r = (col >> 16) & 0xff;
2563 g = (col >> 8) & 0xff;
2565 y = CLAMP ((0.1494 * r + 0.6061 * g + 0.2445 * b) * 219 / 255 + 16, 0,
2567 u = CLAMP (0.6066 * r - 0.4322 * g - 0.1744 * b + 128, 0, 255);
2568 v = CLAMP (-0.08435 * r - 0.3422 * g + 0.4266 * b + 128, 0, 255);
2569 clut[i] = (y << 16) | (u << 8) | v;
2572 /* got them all without problems; build and send event */
2576 s = gst_structure_new ("application/x-gst-dvd", "event", G_TYPE_STRING,
2577 "dvd-spu-clut-change", "clut00", G_TYPE_INT, clut[0], "clut01",
2578 G_TYPE_INT, clut[1], "clut02", G_TYPE_INT, clut[2], "clut03",
2579 G_TYPE_INT, clut[3], "clut04", G_TYPE_INT, clut[4], "clut05",
2580 G_TYPE_INT, clut[5], "clut06", G_TYPE_INT, clut[6], "clut07",
2581 G_TYPE_INT, clut[7], "clut08", G_TYPE_INT, clut[8], "clut09",
2582 G_TYPE_INT, clut[9], "clut10", G_TYPE_INT, clut[10], "clut11",
2583 G_TYPE_INT, clut[11], "clut12", G_TYPE_INT, clut[12], "clut13",
2584 G_TYPE_INT, clut[13], "clut14", G_TYPE_INT, clut[14], "clut15",
2585 G_TYPE_INT, clut[15], NULL);
2587 gst_pad_push_event (stream->pad,
2588 gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM_STICKY, s));
2595 gst_matroska_demux_push_codec_data_all (GstMatroskaDemux * demux)
2599 GST_OBJECT_LOCK (demux);
2601 g_assert (demux->common.num_streams == demux->common.src->len);
2602 for (stream_nr = 0; stream_nr < demux->common.src->len; stream_nr++) {
2603 GstMatroskaTrackContext *stream;
2605 stream = g_ptr_array_index (demux->common.src, stream_nr);
2607 if (stream->send_stream_headers) {
2608 if (stream->stream_headers != NULL) {
2609 gst_matroska_demux_push_stream_headers (demux, stream);
2611 /* FIXME: perhaps we can just disable and skip this stream then */
2612 GST_ELEMENT_ERROR (demux, STREAM, DECODE, (NULL),
2613 ("Failed to extract stream headers from codec private data"));
2615 stream->send_stream_headers = FALSE;
2618 if (stream->send_dvd_event) {
2619 gst_matroska_demux_push_dvd_clut_change_event (demux, stream);
2620 /* FIXME: should we send this event again after (flushing) seek ? */
2621 stream->send_dvd_event = FALSE;
2625 GST_OBJECT_UNLOCK (demux);
2628 static GstFlowReturn
2629 gst_matroska_demux_add_mpeg_seq_header (GstElement * element,
2630 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2633 guint seq_header_len;
2634 guint32 header, tmp;
2636 if (stream->codec_state) {
2637 seq_header = stream->codec_state;
2638 seq_header_len = stream->codec_state_size;
2639 } else if (stream->codec_priv) {
2640 seq_header = stream->codec_priv;
2641 seq_header_len = stream->codec_priv_size;
2646 /* Sequence header only needed for keyframes */
2647 if (GST_BUFFER_FLAG_IS_SET (*buf, GST_BUFFER_FLAG_DELTA_UNIT))
2650 if (gst_buffer_get_size (*buf) < 4)
2653 gst_buffer_extract (*buf, 0, &tmp, sizeof (guint32));
2654 header = GUINT32_FROM_BE (tmp);
2656 /* Sequence start code, if not found prepend */
2657 if (header != 0x000001b3) {
2660 GST_DEBUG_OBJECT (element, "Prepending MPEG sequence header");
2662 newbuf = gst_buffer_new_wrapped (g_memdup (seq_header, seq_header_len),
2665 gst_buffer_copy_into (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
2666 GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_MEMORY, 0,
2667 gst_buffer_get_size (*buf));
2669 gst_buffer_unref (*buf);
2676 static GstFlowReturn
2677 gst_matroska_demux_add_wvpk_header (GstElement * element,
2678 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2680 GstMatroskaTrackAudioContext *audiocontext =
2681 (GstMatroskaTrackAudioContext *) stream;
2682 GstBuffer *newbuf = NULL;
2683 GstMapInfo map, outmap;
2684 guint8 *buf_data, *data;
2692 wvh.version = GST_READ_UINT16_LE (stream->codec_priv);
2695 wvh.total_samples = -1;
2696 wvh.block_index = audiocontext->wvpk_block_index;
2698 if (audiocontext->channels <= 2) {
2699 guint32 block_samples, tmp;
2700 gsize size = gst_buffer_get_size (*buf);
2702 gst_buffer_extract (*buf, 0, &tmp, sizeof (guint32));
2703 block_samples = GUINT32_FROM_LE (tmp);
2704 /* we need to reconstruct the header of the wavpack block */
2706 /* -20 because ck_size is the size of the wavpack block -8
2707 * and lace_size is the size of the wavpack block + 12
2708 * (the three guint32 of the header that already are in the buffer) */
2709 wvh.ck_size = size + sizeof (Wavpack4Header) - 20;
2711 /* block_samples, flags and crc are already in the buffer */
2712 newbuf = gst_buffer_new_allocate (NULL, sizeof (Wavpack4Header) - 12, NULL);
2714 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2720 GST_WRITE_UINT32_LE (data + 4, wvh.ck_size);
2721 GST_WRITE_UINT16_LE (data + 8, wvh.version);
2722 GST_WRITE_UINT8 (data + 10, wvh.track_no);
2723 GST_WRITE_UINT8 (data + 11, wvh.index_no);
2724 GST_WRITE_UINT32_LE (data + 12, wvh.total_samples);
2725 GST_WRITE_UINT32_LE (data + 16, wvh.block_index);
2727 /* Append data from buf: */
2728 gst_buffer_copy_into (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
2729 GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_MEMORY, 0, size);
2731 gst_buffer_unref (*buf);
2733 audiocontext->wvpk_block_index += block_samples;
2735 guint8 *outdata = NULL;
2737 gsize buf_size, size, out_size = 0;
2738 guint32 block_samples, flags, crc, blocksize;
2740 gst_buffer_map (*buf, &map, GST_MAP_READ);
2741 buf_data = map.data;
2742 buf_size = map.size;
2745 GST_ERROR_OBJECT (element, "Too small wavpack buffer");
2746 gst_buffer_unmap (*buf, &map);
2747 return GST_FLOW_ERROR;
2753 block_samples = GST_READ_UINT32_LE (data);
2758 flags = GST_READ_UINT32_LE (data);
2761 crc = GST_READ_UINT32_LE (data);
2764 blocksize = GST_READ_UINT32_LE (data);
2768 if (blocksize == 0 || size < blocksize)
2771 g_assert ((newbuf == NULL) == (outdata == NULL));
2773 if (newbuf == NULL) {
2774 out_size = sizeof (Wavpack4Header) + blocksize;
2775 newbuf = gst_buffer_new_allocate (NULL, out_size, NULL);
2777 gst_buffer_copy_into (newbuf, *buf,
2778 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS, 0, -1);
2781 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2782 outdata = outmap.data;
2784 gst_buffer_unmap (newbuf, &outmap);
2785 out_size += sizeof (Wavpack4Header) + blocksize;
2786 gst_buffer_set_size (newbuf, out_size);
2787 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2788 outdata = outmap.data;
2791 outdata[outpos] = 'w';
2792 outdata[outpos + 1] = 'v';
2793 outdata[outpos + 2] = 'p';
2794 outdata[outpos + 3] = 'k';
2797 GST_WRITE_UINT32_LE (outdata + outpos,
2798 blocksize + sizeof (Wavpack4Header) - 8);
2799 GST_WRITE_UINT16_LE (outdata + outpos + 4, wvh.version);
2800 GST_WRITE_UINT8 (outdata + outpos + 6, wvh.track_no);
2801 GST_WRITE_UINT8 (outdata + outpos + 7, wvh.index_no);
2802 GST_WRITE_UINT32_LE (outdata + outpos + 8, wvh.total_samples);
2803 GST_WRITE_UINT32_LE (outdata + outpos + 12, wvh.block_index);
2804 GST_WRITE_UINT32_LE (outdata + outpos + 16, block_samples);
2805 GST_WRITE_UINT32_LE (outdata + outpos + 20, flags);
2806 GST_WRITE_UINT32_LE (outdata + outpos + 24, crc);
2809 memmove (outdata + outpos, data, blocksize);
2810 outpos += blocksize;
2814 gst_buffer_unmap (*buf, &map);
2815 gst_buffer_unref (*buf);
2818 gst_buffer_unmap (newbuf, &outmap);
2821 audiocontext->wvpk_block_index += block_samples;
2827 /* @text must be null-terminated */
2829 gst_matroska_demux_subtitle_chunk_has_tag (GstElement * element,
2834 g_return_val_if_fail (text != NULL, FALSE);
2836 /* yes, this might all lead to false positives ... */
2837 tag = (gchar *) text;
2838 while ((tag = strchr (tag, '<'))) {
2840 if (*tag != '\0' && *(tag + 1) == '>') {
2841 /* some common convenience ones */
2842 /* maybe any character will do here ? */
2855 if (strstr (text, "<span"))
2861 static GstFlowReturn
2862 gst_matroska_demux_check_subtitle_buffer (GstElement * element,
2863 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2865 GstMatroskaTrackSubtitleContext *sub_stream;
2866 const gchar *encoding;
2871 gboolean needs_unmap = TRUE;
2873 sub_stream = (GstMatroskaTrackSubtitleContext *) stream;
2875 if (!gst_buffer_get_size (*buf) || !gst_buffer_map (*buf, &map, GST_MAP_READ))
2878 /* Need \0-terminator at the end */
2879 if (map.data[map.size - 1] != '\0') {
2880 newbuf = gst_buffer_new_and_alloc (map.size + 1);
2882 /* Copy old buffer and add a 0 at the end */
2883 gst_buffer_fill (newbuf, 0, map.data, map.size);
2884 gst_buffer_memset (newbuf, map.size, 0, 1);
2885 gst_buffer_unmap (*buf, &map);
2887 gst_buffer_copy_into (newbuf, *buf,
2888 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS |
2889 GST_BUFFER_COPY_META, 0, -1);
2890 gst_buffer_unref (*buf);
2892 gst_buffer_map (*buf, &map, GST_MAP_READ);
2895 if (!sub_stream->invalid_utf8) {
2896 if (g_utf8_validate ((gchar *) map.data, map.size - 1, NULL)) {
2899 GST_WARNING_OBJECT (element, "subtitle stream %" G_GUINT64_FORMAT
2900 " is not valid UTF-8, this is broken according to the matroska"
2901 " specification", stream->num);
2902 sub_stream->invalid_utf8 = TRUE;
2905 /* file with broken non-UTF8 subtitle, do the best we can do to fix it */
2906 encoding = g_getenv ("GST_SUBTITLE_ENCODING");
2907 if (encoding == NULL || *encoding == '\0') {
2908 /* if local encoding is UTF-8 and no encoding specified
2909 * via the environment variable, assume ISO-8859-15 */
2910 if (g_get_charset (&encoding)) {
2911 encoding = "ISO-8859-15";
2916 g_convert_with_fallback ((gchar *) map.data, map.size, "UTF-8", encoding,
2917 (char *) "*", NULL, NULL, &err);
2920 GST_LOG_OBJECT (element, "could not convert string from '%s' to UTF-8: %s",
2921 encoding, err->message);
2925 /* invalid input encoding, fall back to ISO-8859-15 (always succeeds) */
2926 encoding = "ISO-8859-15";
2928 g_convert_with_fallback ((gchar *) map.data, map.size, "UTF-8",
2929 encoding, (char *) "*", NULL, NULL, NULL);
2932 GST_LOG_OBJECT (element, "converted subtitle text from %s to UTF-8 %s",
2933 encoding, (err) ? "(using ISO-8859-15 as fallback)" : "");
2936 utf8 = g_strdup ("invalid subtitle");
2938 newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
2939 gst_buffer_unmap (*buf, &map);
2940 gst_buffer_copy_into (newbuf, *buf,
2941 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_META,
2943 gst_buffer_unref (*buf);
2946 gst_buffer_map (*buf, &map, GST_MAP_READ);
2950 if (sub_stream->check_markup) {
2951 /* caps claim markup text, so we need to escape text,
2952 * except if text is already markup and then needs no further escaping */
2953 sub_stream->seen_markup_tag = sub_stream->seen_markup_tag ||
2954 gst_matroska_demux_subtitle_chunk_has_tag (element, (gchar *) map.data);
2956 if (!sub_stream->seen_markup_tag) {
2957 utf8 = g_markup_escape_text ((gchar *) map.data, map.size);
2959 newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
2960 gst_buffer_unmap (*buf, &map);
2961 gst_buffer_copy_into (newbuf, *buf,
2962 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS |
2963 GST_BUFFER_COPY_META, 0, -1);
2964 gst_buffer_unref (*buf);
2967 needs_unmap = FALSE;
2972 gst_buffer_unmap (*buf, &map);
2977 static GstFlowReturn
2978 gst_matroska_demux_check_aac (GstElement * element,
2979 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2984 gst_buffer_extract (*buf, 0, data, 2);
2985 size = gst_buffer_get_size (*buf);
2987 if (size > 2 && data[0] == 0xff && (data[1] >> 4 == 0x0f)) {
2990 /* tss, ADTS data, remove codec_data
2991 * still assume it is at least parsed */
2992 stream->caps = gst_caps_make_writable (stream->caps);
2993 s = gst_caps_get_structure (stream->caps, 0);
2995 gst_structure_remove_field (s, "codec_data");
2996 gst_pad_set_caps (stream->pad, stream->caps);
2997 GST_DEBUG_OBJECT (element, "ADTS AAC audio data; removing codec-data, "
2998 "new caps: %" GST_PTR_FORMAT, stream->caps);
3001 /* disable subsequent checking */
3002 stream->postprocess_frame = NULL;
3008 gst_matroska_demux_align_buffer (GstMatroskaDemux * demux,
3009 GstBuffer * buffer, gsize alignment)
3013 gst_buffer_map (buffer, &map, GST_MAP_READ);
3015 if (map.size < sizeof (guintptr)) {
3016 gst_buffer_unmap (buffer, &map);
3020 if (((guintptr) map.data) & (alignment - 1)) {
3021 GstBuffer *new_buffer;
3022 GstAllocationParams params = { 0, alignment - 1, 0, 0, };
3024 new_buffer = gst_buffer_new_allocate (NULL,
3025 gst_buffer_get_size (buffer), ¶ms);
3027 /* Copy data "by hand", so ensure alignment is kept: */
3028 gst_buffer_fill (new_buffer, 0, map.data, map.size);
3030 gst_buffer_copy_into (new_buffer, buffer, GST_BUFFER_COPY_METADATA, 0, -1);
3031 GST_DEBUG_OBJECT (demux,
3032 "We want output aligned on %" G_GSIZE_FORMAT ", reallocated",
3035 gst_buffer_unmap (buffer, &map);
3036 gst_buffer_unref (buffer);
3041 gst_buffer_unmap (buffer, &map);
3045 static GstFlowReturn
3046 gst_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux,
3047 GstEbmlRead * ebml, guint64 cluster_time, guint64 cluster_offset,
3048 gboolean is_simpleblock)
3050 GstMatroskaTrackContext *stream = NULL;
3051 GstFlowReturn ret = GST_FLOW_OK;
3052 gboolean readblock = FALSE;
3054 guint64 block_duration = -1;
3055 GstBuffer *buf = NULL;
3057 gint stream_num = -1, n, laces = 0;
3059 gint *lace_size = NULL;
3062 gint64 referenceblock = 0;
3065 offset = gst_ebml_read_get_offset (ebml);
3067 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3068 if (!is_simpleblock) {
3069 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK) {
3073 id = GST_MATROSKA_ID_SIMPLEBLOCK;
3077 /* one block inside the group. Note, block parsing is one
3078 * of the harder things, so this code is a bit complicated.
3079 * See http://www.matroska.org/ for documentation. */
3080 case GST_MATROSKA_ID_SIMPLEBLOCK:
3081 case GST_MATROSKA_ID_BLOCK:
3087 gst_buffer_unmap (buf, &map);
3088 gst_buffer_unref (buf);
3091 if ((ret = gst_ebml_read_buffer (ebml, &id, &buf)) != GST_FLOW_OK)
3094 gst_buffer_map (buf, &map, GST_MAP_READ);
3098 /* first byte(s): blocknum */
3099 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
3104 /* fetch stream from num */
3105 stream_num = gst_matroska_read_common_stream_from_num (&demux->common,
3107 if (G_UNLIKELY (size < 3)) {
3108 GST_WARNING_OBJECT (demux, "Invalid size %u", size);
3109 /* non-fatal, try next block(group) */
3112 } else if (G_UNLIKELY (stream_num < 0 ||
3113 stream_num >= demux->common.num_streams)) {
3114 /* let's not give up on a stray invalid track number */
3115 GST_WARNING_OBJECT (demux,
3116 "Invalid stream %d for track number %" G_GUINT64_FORMAT
3117 "; ignoring block", stream_num, num);
3121 stream = g_ptr_array_index (demux->common.src, stream_num);
3123 /* time (relative to cluster time) */
3124 time = ((gint16) GST_READ_UINT16_BE (data));
3127 flags = GST_READ_UINT8 (data);
3131 GST_LOG_OBJECT (demux, "time %" G_GUINT64_FORMAT ", flags %d", time,
3134 switch ((flags & 0x06) >> 1) {
3135 case 0x0: /* no lacing */
3137 lace_size = g_new (gint, 1);
3138 lace_size[0] = size;
3141 case 0x1: /* xiph lacing */
3142 case 0x2: /* fixed-size lacing */
3143 case 0x3: /* EBML lacing */
3145 goto invalid_lacing;
3146 laces = GST_READ_UINT8 (data) + 1;
3149 lace_size = g_new0 (gint, laces);
3151 switch ((flags & 0x06) >> 1) {
3152 case 0x1: /* xiph lacing */ {
3153 guint temp, total = 0;
3155 for (n = 0; ret == GST_FLOW_OK && n < laces - 1; n++) {
3158 goto invalid_lacing;
3159 temp = GST_READ_UINT8 (data);
3160 lace_size[n] += temp;
3166 total += lace_size[n];
3168 lace_size[n] = size - total;
3172 case 0x2: /* fixed-size lacing */
3173 for (n = 0; n < laces; n++)
3174 lace_size[n] = size / laces;
3177 case 0x3: /* EBML lacing */ {
3180 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
3184 total = lace_size[0] = num;
3185 for (n = 1; ret == GST_FLOW_OK && n < laces - 1; n++) {
3189 if ((r = gst_matroska_ebmlnum_sint (data, size, &snum)) < 0)
3193 lace_size[n] = lace_size[n - 1] + snum;
3194 total += lace_size[n];
3197 lace_size[n] = size - total;
3204 if (ret != GST_FLOW_OK)
3211 case GST_MATROSKA_ID_BLOCKDURATION:{
3212 ret = gst_ebml_read_uint (ebml, &id, &block_duration);
3213 GST_DEBUG_OBJECT (demux, "BlockDuration: %" G_GUINT64_FORMAT,
3218 case GST_MATROSKA_ID_REFERENCEBLOCK:{
3219 ret = gst_ebml_read_sint (ebml, &id, &referenceblock);
3220 GST_DEBUG_OBJECT (demux, "ReferenceBlock: %" G_GINT64_FORMAT,
3225 case GST_MATROSKA_ID_CODECSTATE:{
3227 guint64 data_len = 0;
3230 gst_ebml_read_binary (ebml, &id, &data,
3231 &data_len)) != GST_FLOW_OK)
3234 if (G_UNLIKELY (stream == NULL)) {
3235 GST_WARNING_OBJECT (demux,
3236 "Unexpected CodecState subelement - ignoring");
3240 g_free (stream->codec_state);
3241 stream->codec_state = data;
3242 stream->codec_state_size = data_len;
3244 /* Decode if necessary */
3245 if (stream->encodings && stream->encodings->len > 0
3246 && stream->codec_state && stream->codec_state_size > 0) {
3247 if (!gst_matroska_decode_data (stream->encodings,
3248 &stream->codec_state, &stream->codec_state_size,
3249 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
3250 GST_WARNING_OBJECT (demux, "Decoding codec state failed");
3254 GST_DEBUG_OBJECT (demux, "CodecState of %" G_GSIZE_FORMAT " bytes",
3255 stream->codec_state_size);
3260 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3264 case GST_MATROSKA_ID_BLOCKVIRTUAL:
3265 case GST_MATROSKA_ID_BLOCKADDITIONS:
3266 case GST_MATROSKA_ID_REFERENCEPRIORITY:
3267 case GST_MATROSKA_ID_REFERENCEVIRTUAL:
3268 case GST_MATROSKA_ID_SLICES:
3269 GST_DEBUG_OBJECT (demux,
3270 "Skipping BlockGroup subelement 0x%x - ignoring", id);
3271 ret = gst_ebml_read_skip (ebml);
3279 /* reading a number or so could have failed */
3280 if (ret != GST_FLOW_OK)
3283 if (ret == GST_FLOW_OK && readblock) {
3284 gboolean invisible_frame = FALSE;
3285 gboolean delta_unit = FALSE;
3286 guint64 duration = 0;
3287 gint64 lace_time = 0;
3289 stream = g_ptr_array_index (demux->common.src, stream_num);
3291 if (cluster_time != GST_CLOCK_TIME_NONE) {
3292 /* FIXME: What to do with negative timestamps? Give timestamp 0 or -1?
3293 * Drop unless the lace contains timestamp 0? */
3294 if (time < 0 && (-time) > cluster_time) {
3297 if (stream->timecodescale == 1.0)
3298 lace_time = (cluster_time + time) * demux->common.time_scale;
3301 gst_util_guint64_to_gdouble ((cluster_time + time) *
3302 demux->common.time_scale) * stream->timecodescale;
3305 lace_time = GST_CLOCK_TIME_NONE;
3308 /* need to refresh segment info ASAP */
3309 if (GST_CLOCK_TIME_IS_VALID (lace_time) && demux->need_segment) {
3310 GstSegment *segment = &demux->common.segment;
3312 GstEvent *segment_event;
3314 if (!GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
3315 demux->stream_start_time = lace_time;
3316 GST_DEBUG_OBJECT (demux,
3317 "Setting stream start time to %" GST_TIME_FORMAT,
3318 GST_TIME_ARGS (lace_time));
3320 clace_time = MAX (lace_time, demux->stream_start_time);
3321 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.position) &&
3322 demux->common.segment.position != 0) {
3323 GST_DEBUG_OBJECT (demux,
3324 "using stored seek position %" GST_TIME_FORMAT,
3325 GST_TIME_ARGS (demux->common.segment.position));
3326 clace_time = demux->common.segment.position + demux->stream_start_time;
3327 segment->position = GST_CLOCK_TIME_NONE;
3329 segment->start = clace_time;
3330 segment->stop = GST_CLOCK_TIME_NONE;
3331 segment->time = segment->start - demux->stream_start_time;
3332 segment->position = segment->start - demux->stream_start_time;
3333 GST_DEBUG_OBJECT (demux,
3334 "generated segment starting at %" GST_TIME_FORMAT ": %"
3335 GST_SEGMENT_FORMAT, GST_TIME_ARGS (lace_time), segment);
3336 /* now convey our segment notion downstream */
3337 segment_event = gst_event_new_segment (segment);
3338 if (demux->segment_seqnum)
3339 gst_event_set_seqnum (segment_event, demux->segment_seqnum);
3340 gst_matroska_demux_send_event (demux, segment_event);
3341 demux->need_segment = FALSE;
3342 demux->segment_seqnum = 0;
3345 /* send pending codec data headers for all streams,
3346 * before we perform sync across all streams */
3347 gst_matroska_demux_push_codec_data_all (demux);
3349 if (block_duration != -1) {
3350 if (stream->timecodescale == 1.0)
3351 duration = gst_util_uint64_scale (block_duration,
3352 demux->common.time_scale, 1);
3355 gst_util_gdouble_to_guint64 (gst_util_guint64_to_gdouble
3356 (gst_util_uint64_scale (block_duration, demux->common.time_scale,
3357 1)) * stream->timecodescale);
3358 } else if (stream->default_duration) {
3359 duration = stream->default_duration * laces;
3361 /* else duration is diff between timecode of this and next block */
3363 /* For SimpleBlock, look at the keyframe bit in flags. Otherwise,
3364 a ReferenceBlock implies that this is not a keyframe. In either
3365 case, it only makes sense for video streams. */
3366 if (stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
3367 if ((is_simpleblock && !(flags & 0x80)) || referenceblock) {
3369 invisible_frame = ((flags & 0x08)) &&
3370 (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8) ||
3371 !strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP9));
3375 for (n = 0; n < laces; n++) {
3378 if (G_UNLIKELY (lace_size[n] > size)) {
3379 GST_WARNING_OBJECT (demux, "Invalid lace size");
3383 /* QoS for video track with an index. the assumption is that
3384 index entries point to keyframes, but if that is not true we
3385 will instad skip until the next keyframe. */
3386 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
3387 stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
3388 stream->index_table && demux->common.segment.rate > 0.0) {
3389 GstMatroskaTrackVideoContext *videocontext =
3390 (GstMatroskaTrackVideoContext *) stream;
3391 GstClockTime earliest_time;
3392 GstClockTime earliest_stream_time;
3394 GST_OBJECT_LOCK (demux);
3395 earliest_time = videocontext->earliest_time;
3396 GST_OBJECT_UNLOCK (demux);
3397 earliest_stream_time = gst_segment_to_position (&demux->common.segment,
3398 GST_FORMAT_TIME, earliest_time);
3400 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
3401 GST_CLOCK_TIME_IS_VALID (earliest_stream_time) &&
3402 lace_time <= earliest_stream_time) {
3403 /* find index entry (keyframe) <= earliest_stream_time */
3404 GstMatroskaIndex *entry =
3405 gst_util_array_binary_search (stream->index_table->data,
3406 stream->index_table->len, sizeof (GstMatroskaIndex),
3407 (GCompareDataFunc) gst_matroska_index_seek_find,
3408 GST_SEARCH_MODE_BEFORE, &earliest_stream_time, NULL);
3410 /* if that entry (keyframe) is after the current the current
3411 buffer, we can skip pushing (and thus decoding) all
3412 buffers until that keyframe. */
3413 if (entry && GST_CLOCK_TIME_IS_VALID (entry->time) &&
3414 entry->time > lace_time) {
3415 GST_LOG_OBJECT (demux, "Skipping lace before late keyframe");
3416 stream->set_discont = TRUE;
3422 sub = gst_buffer_copy_region (buf, GST_BUFFER_COPY_ALL,
3423 gst_buffer_get_size (buf) - size, lace_size[n]);
3424 GST_DEBUG_OBJECT (demux, "created subbuffer %p", sub);
3427 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
3429 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
3431 if (invisible_frame)
3432 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DECODE_ONLY);
3434 if (stream->encodings != NULL && stream->encodings->len > 0)
3435 sub = gst_matroska_decode_buffer (stream, sub);
3438 GST_WARNING_OBJECT (demux, "Decoding buffer failed");
3442 GST_BUFFER_TIMESTAMP (sub) = lace_time;
3444 if (GST_CLOCK_TIME_IS_VALID (lace_time)) {
3445 GstClockTime last_stop_end;
3447 /* Check if this stream is after segment stop */
3448 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop) &&
3449 lace_time >= demux->common.segment.stop) {
3450 GST_DEBUG_OBJECT (demux,
3451 "Stream %d after segment stop %" GST_TIME_FORMAT, stream->index,
3452 GST_TIME_ARGS (demux->common.segment.stop));
3453 gst_buffer_unref (sub);
3456 if (offset >= stream->to_offset
3457 || (GST_CLOCK_TIME_IS_VALID (demux->to_time)
3458 && lace_time > demux->to_time)) {
3459 GST_DEBUG_OBJECT (demux, "Stream %d after playback section",
3461 gst_buffer_unref (sub);
3465 /* handle gaps, e.g. non-zero start-time, or an cue index entry
3466 * that landed us with timestamps not quite intended */
3467 GST_OBJECT_LOCK (demux);
3468 if (demux->max_gap_time &&
3469 GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) &&
3470 demux->common.segment.rate > 0.0) {
3471 GstClockTimeDiff diff;
3473 /* only send segments with increasing start times,
3474 * otherwise if these go back and forth downstream (sinks) increase
3475 * accumulated time and running_time */
3476 diff = GST_CLOCK_DIFF (demux->last_stop_end, lace_time);
3477 if (diff > 0 && diff > demux->max_gap_time
3478 && lace_time > demux->common.segment.start
3479 && (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop)
3480 || lace_time < demux->common.segment.stop)) {
3482 GST_DEBUG_OBJECT (demux,
3483 "Gap of %" G_GINT64_FORMAT " ns detected in"
3484 "stream %d (%" GST_TIME_FORMAT " -> %" GST_TIME_FORMAT "). "
3485 "Sending updated SEGMENT events", diff,
3486 stream->index, GST_TIME_ARGS (stream->pos),
3487 GST_TIME_ARGS (lace_time));
3489 event = gst_event_new_gap (demux->last_stop_end, diff);
3490 GST_OBJECT_UNLOCK (demux);
3491 gst_pad_push_event (stream->pad, event);
3492 GST_OBJECT_LOCK (demux);
3496 if (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.position)
3497 || demux->common.segment.position < lace_time) {
3498 demux->common.segment.position = lace_time;
3500 GST_OBJECT_UNLOCK (demux);
3502 last_stop_end = lace_time;
3504 GST_BUFFER_DURATION (sub) = duration / laces;
3505 last_stop_end += GST_BUFFER_DURATION (sub);
3508 if (!GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) ||
3509 demux->last_stop_end < last_stop_end)
3510 demux->last_stop_end = last_stop_end;
3512 GST_OBJECT_LOCK (demux);
3513 if (demux->common.segment.duration == -1 ||
3514 demux->stream_start_time + demux->common.segment.duration <
3516 demux->common.segment.duration =
3517 last_stop_end - demux->stream_start_time;
3518 GST_OBJECT_UNLOCK (demux);
3519 if (!demux->invalid_duration) {
3520 gst_element_post_message (GST_ELEMENT_CAST (demux),
3521 gst_message_new_duration_changed (GST_OBJECT_CAST (demux)));
3522 demux->invalid_duration = TRUE;
3525 GST_OBJECT_UNLOCK (demux);
3529 stream->pos = lace_time;
3531 gst_matroska_demux_sync_streams (demux);
3533 if (stream->set_discont) {
3534 GST_DEBUG_OBJECT (demux, "marking DISCONT");
3535 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DISCONT);
3536 stream->set_discont = FALSE;
3538 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DISCONT);
3541 /* reverse playback book-keeping */
3542 if (!GST_CLOCK_TIME_IS_VALID (stream->from_time))
3543 stream->from_time = lace_time;
3544 if (stream->from_offset == -1)
3545 stream->from_offset = offset;
3547 GST_DEBUG_OBJECT (demux,
3548 "Pushing lace %d, data of size %" G_GSIZE_FORMAT
3549 " for stream %d, time=%" GST_TIME_FORMAT " and duration=%"
3550 GST_TIME_FORMAT, n, gst_buffer_get_size (sub), stream_num,
3551 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (sub)),
3552 GST_TIME_ARGS (GST_BUFFER_DURATION (sub)));
3555 if (demux->common.element_index) {
3556 if (stream->index_writer_id == -1)
3557 gst_index_get_writer_id (demux->common.element_index,
3558 GST_OBJECT (stream->pad), &stream->index_writer_id);
3560 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
3561 G_GUINT64_FORMAT " for writer id %d",
3562 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (sub)), cluster_offset,
3563 stream->index_writer_id);
3564 gst_index_add_association (demux->common.element_index,
3565 stream->index_writer_id, GST_BUFFER_FLAG_IS_SET (sub,
3566 GST_BUFFER_FLAG_DELTA_UNIT) ? 0 : GST_ASSOCIATION_FLAG_KEY_UNIT,
3567 GST_FORMAT_TIME, GST_BUFFER_TIMESTAMP (sub), GST_FORMAT_BYTES,
3568 cluster_offset, NULL);
3572 /* Postprocess the buffers depending on the codec used */
3573 if (stream->postprocess_frame) {
3574 GST_LOG_OBJECT (demux, "running post process");
3575 ret = stream->postprocess_frame (GST_ELEMENT (demux), stream, &sub);
3578 /* At this point, we have a sub-buffer pointing at data within a larger
3579 buffer. This data might not be aligned with anything. If the data is
3580 raw samples though, we want it aligned to the raw type (eg, 4 bytes
3581 for 32 bit samples, etc), or bad things will happen downstream as
3582 elements typically assume minimal alignment.
3583 Therefore, create an aligned copy if necessary. */
3584 g_assert (stream->alignment <= G_MEM_ALIGN);
3585 sub = gst_matroska_demux_align_buffer (demux, sub, stream->alignment);
3587 if (GST_BUFFER_PTS_IS_VALID (sub)) {
3588 stream->pos = GST_BUFFER_PTS (sub);
3589 if (GST_BUFFER_DURATION_IS_VALID (sub))
3590 stream->pos += GST_BUFFER_DURATION (sub);
3593 ret = gst_pad_push (stream->pad, sub);
3595 if (demux->common.segment.rate < 0) {
3596 if (lace_time > demux->common.segment.stop && ret == GST_FLOW_EOS) {
3597 /* In reverse playback we can get a GST_FLOW_EOS when
3598 * we are at the end of the segment, so we just need to jump
3599 * back to the previous section. */
3600 GST_DEBUG_OBJECT (demux, "downstream has reached end of segment");
3605 ret = gst_flow_combiner_update_flow (demux->flowcombiner, ret);
3608 size -= lace_size[n];
3609 if (lace_time != GST_CLOCK_TIME_NONE && duration)
3610 lace_time += duration / laces;
3612 lace_time = GST_CLOCK_TIME_NONE;
3618 gst_buffer_unmap (buf, &map);
3619 gst_buffer_unref (buf);
3631 ret = gst_flow_combiner_update_flow (demux->flowcombiner, ret);
3636 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Invalid lacing size"));
3637 /* non-fatal, try next block(group) */
3643 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Data error"));
3644 /* non-fatal, try next block(group) */
3650 /* return FALSE if block(group) should be skipped (due to a seek) */
3651 static inline gboolean
3652 gst_matroska_demux_seek_block (GstMatroskaDemux * demux)
3654 if (G_UNLIKELY (demux->seek_block)) {
3655 if (!(--demux->seek_block)) {
3658 GST_LOG_OBJECT (demux, "should skip block due to seek");
3666 static GstFlowReturn
3667 gst_matroska_demux_parse_contents_seekentry (GstMatroskaDemux * demux,
3671 guint64 seek_pos = (guint64) - 1;
3672 guint32 seek_id = 0;
3675 DEBUG_ELEMENT_START (demux, ebml, "Seek");
3677 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3678 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
3682 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3683 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3687 case GST_MATROSKA_ID_SEEKID:
3691 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
3694 GST_DEBUG_OBJECT (demux, "SeekID: %" G_GUINT64_FORMAT, t);
3699 case GST_MATROSKA_ID_SEEKPOSITION:
3703 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
3706 if (t > G_MAXINT64) {
3707 GST_WARNING_OBJECT (demux,
3708 "Too large SeekPosition %" G_GUINT64_FORMAT, t);
3712 GST_DEBUG_OBJECT (demux, "SeekPosition: %" G_GUINT64_FORMAT, t);
3718 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3724 if (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)
3727 if (!seek_id || seek_pos == (guint64) - 1) {
3728 GST_WARNING_OBJECT (demux, "Incomplete seekhead entry (0x%x/%"
3729 G_GUINT64_FORMAT ")", seek_id, seek_pos);
3734 case GST_MATROSKA_ID_SEEKHEAD:
3737 case GST_MATROSKA_ID_CUES:
3738 case GST_MATROSKA_ID_TAGS:
3739 case GST_MATROSKA_ID_TRACKS:
3740 case GST_MATROSKA_ID_SEGMENTINFO:
3741 case GST_MATROSKA_ID_ATTACHMENTS:
3742 case GST_MATROSKA_ID_CHAPTERS:
3744 guint64 before_pos, length;
3748 length = gst_matroska_read_common_get_length (&demux->common);
3749 before_pos = demux->common.offset;
3751 if (length == (guint64) - 1) {
3752 GST_DEBUG_OBJECT (demux, "no upstream length, skipping SeakHead entry");
3756 /* check for validity */
3757 if (seek_pos + demux->common.ebml_segment_start + 12 >= length) {
3758 GST_WARNING_OBJECT (demux,
3759 "SeekHead reference lies outside file!" " (%"
3760 G_GUINT64_FORMAT "+%" G_GUINT64_FORMAT "+12 >= %"
3761 G_GUINT64_FORMAT ")", seek_pos, demux->common.ebml_segment_start,
3766 /* only pick up index location when streaming */
3767 if (demux->streaming) {
3768 if (seek_id == GST_MATROSKA_ID_CUES) {
3769 demux->index_offset = seek_pos + demux->common.ebml_segment_start;
3770 GST_DEBUG_OBJECT (demux, "Cues located at offset %" G_GUINT64_FORMAT,
3771 demux->index_offset);
3777 demux->common.offset = seek_pos + demux->common.ebml_segment_start;
3780 if ((ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
3781 GST_ELEMENT_CAST (demux), &id, &length, &needed)) !=
3785 if (id != seek_id) {
3786 GST_WARNING_OBJECT (demux,
3787 "We looked for ID=0x%x but got ID=0x%x (pos=%" G_GUINT64_FORMAT ")",
3788 seek_id, id, seek_pos + demux->common.ebml_segment_start);
3791 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
3796 demux->common.offset = before_pos;
3800 case GST_MATROSKA_ID_CLUSTER:
3802 guint64 pos = seek_pos + demux->common.ebml_segment_start;
3804 GST_LOG_OBJECT (demux, "Cluster position");
3805 if (G_UNLIKELY (!demux->clusters))
3806 demux->clusters = g_array_sized_new (TRUE, TRUE, sizeof (guint64), 100);
3807 g_array_append_val (demux->clusters, pos);
3812 GST_DEBUG_OBJECT (demux, "Ignoring Seek entry for ID=0x%x", seek_id);
3815 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
3820 static GstFlowReturn
3821 gst_matroska_demux_parse_contents (GstMatroskaDemux * demux, GstEbmlRead * ebml)
3823 GstFlowReturn ret = GST_FLOW_OK;
3826 DEBUG_ELEMENT_START (demux, ebml, "SeekHead");
3828 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3829 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
3833 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3834 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3838 case GST_MATROSKA_ID_SEEKENTRY:
3840 ret = gst_matroska_demux_parse_contents_seekentry (demux, ebml);
3841 /* Ignore EOS and errors here */
3842 if (ret != GST_FLOW_OK) {
3843 GST_DEBUG_OBJECT (demux, "Ignoring %s", gst_flow_get_name (ret));
3850 ret = gst_matroska_read_common_parse_skip (&demux->common,
3851 ebml, "SeekHead", id);
3856 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
3858 /* Sort clusters by position for easier searching */
3859 if (demux->clusters)
3860 g_array_sort (demux->clusters, (GCompareFunc) gst_matroska_cluster_compare);
3865 #define GST_FLOW_OVERFLOW GST_FLOW_CUSTOM_ERROR
3867 #define MAX_BLOCK_SIZE (15 * 1024 * 1024)
3869 static inline GstFlowReturn
3870 gst_matroska_demux_check_read_size (GstMatroskaDemux * demux, guint64 bytes)
3872 if (G_UNLIKELY (bytes > MAX_BLOCK_SIZE)) {
3873 /* only a few blocks are expected/allowed to be large,
3874 * and will be recursed into, whereas others will be read and must fit */
3875 if (demux->streaming) {
3876 /* fatal in streaming case, as we can't step over easily */
3877 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
3878 ("reading large block of size %" G_GUINT64_FORMAT " not supported; "
3879 "file might be corrupt.", bytes));
3880 return GST_FLOW_ERROR;
3882 /* indicate higher level to quietly give up */
3883 GST_DEBUG_OBJECT (demux,
3884 "too large block of size %" G_GUINT64_FORMAT, bytes);
3885 return GST_FLOW_ERROR;
3892 /* returns TRUE if we truely are in error state, and should give up */
3893 static inline gboolean
3894 gst_matroska_demux_check_parse_error (GstMatroskaDemux * demux)
3896 if (!demux->streaming && demux->next_cluster_offset > 0) {
3897 /* just repositioning to where next cluster should be and try from there */
3898 GST_WARNING_OBJECT (demux, "parse error, trying next cluster expected at %"
3899 G_GUINT64_FORMAT, demux->next_cluster_offset);
3900 demux->common.offset = demux->next_cluster_offset;
3901 demux->next_cluster_offset = 0;
3906 /* sigh, one last attempt above and beyond call of duty ...;
3907 * search for cluster mark following current pos */
3908 pos = demux->common.offset;
3909 GST_WARNING_OBJECT (demux, "parse error, looking for next cluster");
3910 if (gst_matroska_demux_search_cluster (demux, &pos) != GST_FLOW_OK) {
3911 /* did not work, give up */
3914 GST_DEBUG_OBJECT (demux, "... found at %" G_GUINT64_FORMAT, pos);
3915 /* try that position */
3916 demux->common.offset = pos;
3922 static inline GstFlowReturn
3923 gst_matroska_demux_flush (GstMatroskaDemux * demux, guint flush)
3925 GST_LOG_OBJECT (demux, "skipping %d bytes", flush);
3926 demux->common.offset += flush;
3927 if (demux->streaming) {
3930 /* hard to skip large blocks when streaming */
3931 ret = gst_matroska_demux_check_read_size (demux, flush);
3932 if (ret != GST_FLOW_OK)
3934 if (flush <= gst_adapter_available (demux->common.adapter))
3935 gst_adapter_flush (demux->common.adapter, flush);
3937 return GST_FLOW_EOS;
3942 /* initializes @ebml with @bytes from input stream at current offset.
3943 * Returns EOS if insufficient available,
3944 * ERROR if too much was attempted to read. */
3945 static inline GstFlowReturn
3946 gst_matroska_demux_take (GstMatroskaDemux * demux, guint64 bytes,
3949 GstBuffer *buffer = NULL;
3950 GstFlowReturn ret = GST_FLOW_OK;
3952 GST_LOG_OBJECT (demux, "taking %" G_GUINT64_FORMAT " bytes for parsing",
3954 ret = gst_matroska_demux_check_read_size (demux, bytes);
3955 if (G_UNLIKELY (ret != GST_FLOW_OK)) {
3956 if (!demux->streaming) {
3957 /* in pull mode, we can skip */
3958 if ((ret = gst_matroska_demux_flush (demux, bytes)) == GST_FLOW_OK)
3959 ret = GST_FLOW_OVERFLOW;
3961 /* otherwise fatal */
3962 ret = GST_FLOW_ERROR;
3966 if (demux->streaming) {
3967 if (gst_adapter_available (demux->common.adapter) >= bytes)
3968 buffer = gst_adapter_take_buffer (demux->common.adapter, bytes);
3972 ret = gst_matroska_read_common_peek_bytes (&demux->common,
3973 demux->common.offset, bytes, &buffer, NULL);
3974 if (G_LIKELY (buffer)) {
3975 gst_ebml_read_init (ebml, GST_ELEMENT_CAST (demux), buffer,
3976 demux->common.offset);
3977 demux->common.offset += bytes;
3984 gst_matroska_demux_check_seekability (GstMatroskaDemux * demux)
3987 gboolean seekable = FALSE;
3988 gint64 start = -1, stop = -1;
3990 query = gst_query_new_seeking (GST_FORMAT_BYTES);
3991 if (!gst_pad_peer_query (demux->common.sinkpad, query)) {
3992 GST_DEBUG_OBJECT (demux, "seeking query failed");
3996 gst_query_parse_seeking (query, NULL, &seekable, &start, &stop);
3998 /* try harder to query upstream size if we didn't get it the first time */
3999 if (seekable && stop == -1) {
4000 GST_DEBUG_OBJECT (demux, "doing duration query to fix up unset stop");
4001 gst_pad_peer_query_duration (demux->common.sinkpad, GST_FORMAT_BYTES,
4005 /* if upstream doesn't know the size, it's likely that it's not seekable in
4006 * practice even if it technically may be seekable */
4007 if (seekable && (start != 0 || stop <= start)) {
4008 GST_DEBUG_OBJECT (demux, "seekable but unknown start/stop -> disable");
4013 GST_INFO_OBJECT (demux, "seekable: %d (%" G_GUINT64_FORMAT " - %"
4014 G_GUINT64_FORMAT ")", seekable, start, stop);
4015 demux->seekable = seekable;
4017 gst_query_unref (query);
4020 static GstFlowReturn
4021 gst_matroska_demux_find_tracks (GstMatroskaDemux * demux)
4027 GstFlowReturn ret = GST_FLOW_OK;
4029 GST_WARNING_OBJECT (demux,
4030 "Found Cluster element before Tracks, searching Tracks");
4033 before_pos = demux->common.offset;
4035 /* Search Tracks element */
4037 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4038 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4039 if (ret != GST_FLOW_OK)
4042 if (id != GST_MATROSKA_ID_TRACKS) {
4043 /* we may be skipping large cluster here, so forego size check etc */
4044 /* ... but we can't skip undefined size; force error */
4045 if (length == G_MAXUINT64) {
4046 ret = gst_matroska_demux_check_read_size (demux, length);
4049 demux->common.offset += needed;
4050 demux->common.offset += length;
4055 /* will lead to track parsing ... */
4056 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4061 demux->common.offset = before_pos;
4066 #define GST_READ_CHECK(stmt) \
4068 if (G_UNLIKELY ((ret = (stmt)) != GST_FLOW_OK)) { \
4069 if (ret == GST_FLOW_OVERFLOW) { \
4070 ret = GST_FLOW_OK; \
4076 static GstFlowReturn
4077 gst_matroska_demux_parse_id (GstMatroskaDemux * demux, guint32 id,
4078 guint64 length, guint needed)
4080 GstEbmlRead ebml = { 0, };
4081 GstFlowReturn ret = GST_FLOW_OK;
4084 GST_LOG_OBJECT (demux, "Parsing Element id 0x%x, "
4085 "size %" G_GUINT64_FORMAT ", prefix %d", id, length, needed);
4087 /* if we plan to read and parse this element, we need prefix (id + length)
4088 * and the contents */
4089 /* mind about overflow wrap-around when dealing with undefined size */
4091 if (G_LIKELY (length != G_MAXUINT64))
4094 switch (demux->common.state) {
4095 case GST_MATROSKA_READ_STATE_START:
4097 case GST_EBML_ID_HEADER:
4098 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4099 ret = gst_matroska_read_common_parse_header (&demux->common, &ebml);
4100 if (ret != GST_FLOW_OK)
4102 demux->common.state = GST_MATROSKA_READ_STATE_SEGMENT;
4103 gst_matroska_demux_check_seekability (demux);
4106 goto invalid_header;
4110 case GST_MATROSKA_READ_STATE_SEGMENT:
4112 case GST_MATROSKA_ID_SEGMENT:
4113 /* eat segment prefix */
4114 GST_READ_CHECK (gst_matroska_demux_flush (demux, needed));
4115 GST_DEBUG_OBJECT (demux,
4116 "Found Segment start at offset %" G_GUINT64_FORMAT,
4117 demux->common.offset);
4118 /* seeks are from the beginning of the segment,
4119 * after the segment ID/length */
4120 demux->common.ebml_segment_start = demux->common.offset;
4121 demux->common.state = GST_MATROSKA_READ_STATE_HEADER;
4124 GST_WARNING_OBJECT (demux,
4125 "Expected a Segment ID (0x%x), but received 0x%x!",
4126 GST_MATROSKA_ID_SEGMENT, id);
4127 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4131 case GST_MATROSKA_READ_STATE_SCANNING:
4132 if (id != GST_MATROSKA_ID_CLUSTER &&
4133 id != GST_MATROSKA_ID_CLUSTERTIMECODE)
4136 case GST_MATROSKA_READ_STATE_HEADER:
4137 case GST_MATROSKA_READ_STATE_DATA:
4138 case GST_MATROSKA_READ_STATE_SEEK:
4140 case GST_MATROSKA_ID_SEGMENTINFO:
4141 if (!demux->common.segmentinfo_parsed) {
4142 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4143 ret = gst_matroska_read_common_parse_info (&demux->common,
4144 GST_ELEMENT_CAST (demux), &ebml);
4146 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4149 case GST_MATROSKA_ID_TRACKS:
4150 if (!demux->tracks_parsed) {
4151 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4152 ret = gst_matroska_demux_parse_tracks (demux, &ebml);
4154 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4157 case GST_MATROSKA_ID_CLUSTER:
4158 if (G_UNLIKELY (!demux->tracks_parsed)) {
4159 if (demux->streaming) {
4160 GST_DEBUG_OBJECT (demux, "Cluster before Track");
4161 goto not_streamable;
4163 ret = gst_matroska_demux_find_tracks (demux);
4164 if (!demux->tracks_parsed)
4168 if (G_UNLIKELY (demux->common.state
4169 == GST_MATROSKA_READ_STATE_HEADER)) {
4170 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
4171 demux->first_cluster_offset = demux->common.offset;
4172 GST_DEBUG_OBJECT (demux, "signaling no more pads");
4173 gst_element_no_more_pads (GST_ELEMENT (demux));
4174 /* send initial segment - we wait till we know the first
4175 incoming timestamp, so we can properly set the start of
4177 demux->need_segment = TRUE;
4179 demux->cluster_time = GST_CLOCK_TIME_NONE;
4180 demux->cluster_offset = demux->common.offset;
4181 if (G_UNLIKELY (!demux->seek_first && demux->seek_block)) {
4182 GST_DEBUG_OBJECT (demux, "seek target block %" G_GUINT64_FORMAT
4183 " not found in Cluster, trying next Cluster's first block instead",
4185 demux->seek_block = 0;
4187 demux->seek_first = FALSE;
4188 /* record next cluster for recovery */
4189 if (read != G_MAXUINT64)
4190 demux->next_cluster_offset = demux->cluster_offset + read;
4191 /* eat cluster prefix */
4192 gst_matroska_demux_flush (demux, needed);
4194 case GST_MATROSKA_ID_CLUSTERTIMECODE:
4198 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4199 if ((ret = gst_ebml_read_uint (&ebml, &id, &num)) != GST_FLOW_OK)
4201 GST_DEBUG_OBJECT (demux, "ClusterTimeCode: %" G_GUINT64_FORMAT, num);
4202 demux->cluster_time = num;
4204 if (demux->common.element_index) {
4205 if (demux->common.element_index_writer_id == -1)
4206 gst_index_get_writer_id (demux->common.element_index,
4207 GST_OBJECT (demux), &demux->common.element_index_writer_id);
4208 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
4209 G_GUINT64_FORMAT " for writer id %d",
4210 GST_TIME_ARGS (demux->cluster_time), demux->cluster_offset,
4211 demux->common.element_index_writer_id);
4212 gst_index_add_association (demux->common.element_index,
4213 demux->common.element_index_writer_id,
4214 GST_ASSOCIATION_FLAG_KEY_UNIT,
4215 GST_FORMAT_TIME, demux->cluster_time,
4216 GST_FORMAT_BYTES, demux->cluster_offset, NULL);
4221 case GST_MATROSKA_ID_BLOCKGROUP:
4222 if (!gst_matroska_demux_seek_block (demux))
4224 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4225 DEBUG_ELEMENT_START (demux, &ebml, "BlockGroup");
4226 if ((ret = gst_ebml_read_master (&ebml, &id)) == GST_FLOW_OK) {
4227 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4228 &ebml, demux->cluster_time, demux->cluster_offset, FALSE);
4230 DEBUG_ELEMENT_STOP (demux, &ebml, "BlockGroup", ret);
4232 case GST_MATROSKA_ID_SIMPLEBLOCK:
4233 if (!gst_matroska_demux_seek_block (demux))
4235 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4236 DEBUG_ELEMENT_START (demux, &ebml, "SimpleBlock");
4237 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4238 &ebml, demux->cluster_time, demux->cluster_offset, TRUE);
4239 DEBUG_ELEMENT_STOP (demux, &ebml, "SimpleBlock", ret);
4241 case GST_MATROSKA_ID_ATTACHMENTS:
4242 if (!demux->common.attachments_parsed) {
4243 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4244 ret = gst_matroska_read_common_parse_attachments (&demux->common,
4245 GST_ELEMENT_CAST (demux), &ebml);
4247 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4250 case GST_MATROSKA_ID_TAGS:
4251 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4252 ret = gst_matroska_read_common_parse_metadata (&demux->common,
4253 GST_ELEMENT_CAST (demux), &ebml);
4255 case GST_MATROSKA_ID_CHAPTERS:
4256 if (!demux->common.chapters_parsed) {
4257 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4259 gst_matroska_read_common_parse_chapters (&demux->common, &ebml);
4261 if (demux->common.toc) {
4262 gst_matroska_demux_send_event (demux,
4263 gst_event_new_toc (demux->common.toc, FALSE));
4266 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4268 case GST_MATROSKA_ID_SEEKHEAD:
4269 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4270 ret = gst_matroska_demux_parse_contents (demux, &ebml);
4272 case GST_MATROSKA_ID_CUES:
4273 if (demux->common.index_parsed) {
4274 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4277 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4278 ret = gst_matroska_read_common_parse_index (&demux->common, &ebml);
4279 /* only push based; delayed index building */
4280 if (ret == GST_FLOW_OK
4281 && demux->common.state == GST_MATROSKA_READ_STATE_SEEK) {
4284 GST_OBJECT_LOCK (demux);
4285 event = demux->seek_event;
4286 demux->seek_event = NULL;
4287 GST_OBJECT_UNLOCK (demux);
4290 /* unlikely to fail, since we managed to seek to this point */
4291 if (!gst_matroska_demux_handle_seek_event (demux, NULL, event))
4293 /* resume data handling, main thread clear to seek again */
4294 GST_OBJECT_LOCK (demux);
4295 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
4296 GST_OBJECT_UNLOCK (demux);
4299 case GST_MATROSKA_ID_POSITION:
4300 case GST_MATROSKA_ID_PREVSIZE:
4301 case GST_MATROSKA_ID_ENCRYPTEDBLOCK:
4302 case GST_MATROSKA_ID_SILENTTRACKS:
4303 GST_DEBUG_OBJECT (demux,
4304 "Skipping Cluster subelement 0x%x - ignoring", id);
4308 GST_DEBUG_OBJECT (demux, "skipping Element 0x%x", id);
4309 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4315 if (ret == GST_FLOW_PARSE)
4319 gst_ebml_read_clear (&ebml);
4325 /* simply exit, maybe not enough data yet */
4326 /* no ebml to clear if read error */
4331 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4332 ("Failed to parse Element 0x%x", id));
4333 ret = GST_FLOW_ERROR;
4338 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4339 ("File layout does not permit streaming"));
4340 ret = GST_FLOW_ERROR;
4345 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4346 ("No Tracks element found"));
4347 ret = GST_FLOW_ERROR;
4352 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Invalid header"));
4353 ret = GST_FLOW_ERROR;
4358 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Failed to seek"));
4359 ret = GST_FLOW_ERROR;
4365 gst_matroska_demux_loop (GstPad * pad)
4367 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (pad));
4373 /* If we have to close a segment, send a new segment to do this now */
4374 if (G_LIKELY (demux->common.state == GST_MATROSKA_READ_STATE_DATA)) {
4375 if (G_UNLIKELY (demux->new_segment)) {
4376 gst_matroska_demux_send_event (demux, demux->new_segment);
4377 demux->new_segment = NULL;
4381 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4382 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4383 if (ret == GST_FLOW_EOS) {
4385 } else if (ret == GST_FLOW_FLUSHING) {
4387 } else if (ret != GST_FLOW_OK) {
4388 if (gst_matroska_demux_check_parse_error (demux))
4394 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
4395 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
4398 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4399 if (ret == GST_FLOW_EOS)
4401 if (ret != GST_FLOW_OK)
4404 /* check if we're at the end of a configured segment */
4405 if (G_LIKELY (demux->common.src->len)) {
4408 g_assert (demux->common.num_streams == demux->common.src->len);
4409 for (i = 0; i < demux->common.src->len; i++) {
4410 GstMatroskaTrackContext *context = g_ptr_array_index (demux->common.src,
4412 GST_DEBUG_OBJECT (context->pad, "pos %" GST_TIME_FORMAT,
4413 GST_TIME_ARGS (context->pos));
4414 if (context->eos == FALSE)
4418 GST_INFO_OBJECT (demux, "All streams are EOS");
4424 if (G_UNLIKELY (demux->common.offset ==
4425 gst_matroska_read_common_get_length (&demux->common))) {
4426 GST_LOG_OBJECT (demux, "Reached end of stream");
4436 if (demux->common.segment.rate < 0.0) {
4437 ret = gst_matroska_demux_seek_to_previous_keyframe (demux);
4438 if (ret == GST_FLOW_OK)
4445 const gchar *reason = gst_flow_get_name (ret);
4446 gboolean push_eos = FALSE;
4448 GST_LOG_OBJECT (demux, "pausing task, reason %s", reason);
4449 gst_pad_pause_task (demux->common.sinkpad);
4451 if (ret == GST_FLOW_EOS) {
4452 /* perform EOS logic */
4454 /* If we were in the headers, make sure we send no-more-pads.
4455 This will ensure decodebin2 does not get stuck thinking
4456 the chain is not complete yet, and waiting indefinitely. */
4457 if (G_UNLIKELY (demux->common.state == GST_MATROSKA_READ_STATE_HEADER)) {
4458 if (demux->common.src->len == 0) {
4459 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
4460 ("No pads created"));
4462 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL),
4463 ("Failed to finish reading headers"));
4465 gst_element_no_more_pads (GST_ELEMENT (demux));
4468 if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
4471 /* for segment playback we need to post when (in stream time)
4472 * we stopped, this is either stop (when set) or the duration. */
4473 if ((stop = demux->common.segment.stop) == -1)
4474 stop = demux->last_stop_end;
4476 GST_LOG_OBJECT (demux, "Sending segment done, at end of segment");
4477 gst_element_post_message (GST_ELEMENT (demux),
4478 gst_message_new_segment_done (GST_OBJECT (demux), GST_FORMAT_TIME,
4480 gst_matroska_demux_send_event (demux,
4481 gst_event_new_segment_done (GST_FORMAT_TIME, stop));
4485 } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS) {
4486 /* for fatal errors we post an error message */
4487 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
4488 ("stream stopped, reason %s", reason));
4492 /* send EOS, and prevent hanging if no streams yet */
4493 GST_LOG_OBJECT (demux, "Sending EOS, at end of stream");
4494 if (!gst_matroska_demux_send_event (demux, gst_event_new_eos ()) &&
4495 (ret == GST_FLOW_EOS)) {
4496 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4497 (NULL), ("got eos but no streams (yet)"));
4505 * Create and push a flushing seek event upstream
4508 perform_seek_to_offset (GstMatroskaDemux * demux, gdouble rate, guint64 offset,
4514 GST_DEBUG_OBJECT (demux, "Seeking to %" G_GUINT64_FORMAT, offset);
4517 gst_event_new_seek (rate, GST_FORMAT_BYTES,
4518 GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, GST_SEEK_TYPE_SET, offset,
4519 GST_SEEK_TYPE_NONE, -1);
4520 gst_event_set_seqnum (event, seqnum);
4522 res = gst_pad_push_event (demux->common.sinkpad, event);
4524 /* segment event will update offset */
4528 static GstFlowReturn
4529 gst_matroska_demux_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
4531 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4533 GstFlowReturn ret = GST_FLOW_OK;
4538 if (G_UNLIKELY (GST_BUFFER_IS_DISCONT (buffer))) {
4539 GST_DEBUG_OBJECT (demux, "got DISCONT");
4540 gst_adapter_clear (demux->common.adapter);
4541 GST_OBJECT_LOCK (demux);
4542 gst_matroska_read_common_reset_streams (&demux->common,
4543 GST_CLOCK_TIME_NONE, FALSE);
4544 GST_OBJECT_UNLOCK (demux);
4547 gst_adapter_push (demux->common.adapter, buffer);
4551 available = gst_adapter_available (demux->common.adapter);
4553 ret = gst_matroska_read_common_peek_id_length_push (&demux->common,
4554 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4555 if (G_UNLIKELY (ret != GST_FLOW_OK && ret != GST_FLOW_EOS))
4558 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
4559 "size %" G_GUINT64_FORMAT ", needed %d, available %d",
4560 demux->common.offset, id, length, needed, available);
4562 if (needed > available)
4565 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4566 if (ret == GST_FLOW_EOS) {
4567 /* need more data */
4569 } else if (ret != GST_FLOW_OK) {
4576 gst_matroska_demux_handle_sink_event (GstPad * pad, GstObject * parent,
4579 gboolean res = TRUE;
4580 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4582 GST_DEBUG_OBJECT (demux,
4583 "have event type %s: %p on sink pad", GST_EVENT_TYPE_NAME (event), event);
4585 switch (GST_EVENT_TYPE (event)) {
4586 case GST_EVENT_SEGMENT:
4588 const GstSegment *segment;
4590 /* some debug output */
4591 gst_event_parse_segment (event, &segment);
4592 /* FIXME: do we need to update segment base here (like accum in 0.10)? */
4593 GST_DEBUG_OBJECT (demux,
4594 "received format %d segment %" GST_SEGMENT_FORMAT, segment->format,
4597 if (demux->common.state < GST_MATROSKA_READ_STATE_DATA) {
4598 GST_DEBUG_OBJECT (demux, "still starting");
4602 /* we only expect a BYTE segment, e.g. following a seek */
4603 if (segment->format != GST_FORMAT_BYTES) {
4604 GST_DEBUG_OBJECT (demux, "unsupported segment format, ignoring");
4608 GST_DEBUG_OBJECT (demux, "clearing segment state");
4609 GST_OBJECT_LOCK (demux);
4610 /* clear current segment leftover */
4611 gst_adapter_clear (demux->common.adapter);
4612 /* and some streaming setup */
4613 demux->common.offset = segment->start;
4614 /* accumulate base based on current position */
4615 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.position))
4616 demux->common.segment.base +=
4617 (MAX (demux->common.segment.position, demux->stream_start_time)
4618 - demux->stream_start_time) / fabs (demux->common.segment.rate);
4619 /* do not know where we are;
4620 * need to come across a cluster and generate segment */
4621 demux->common.segment.position = GST_CLOCK_TIME_NONE;
4622 demux->cluster_time = GST_CLOCK_TIME_NONE;
4623 demux->cluster_offset = 0;
4624 demux->need_segment = TRUE;
4625 demux->segment_seqnum = gst_event_get_seqnum (event);
4626 /* but keep some of the upstream segment */
4627 demux->common.segment.rate = segment->rate;
4628 /* also check if need to keep some of the requested seek position */
4629 if (demux->seek_offset == segment->start) {
4630 GST_DEBUG_OBJECT (demux, "position matches requested seek");
4631 demux->common.segment.position = demux->requested_seek_time;
4633 GST_DEBUG_OBJECT (demux, "unexpected segment position");
4635 demux->requested_seek_time = GST_CLOCK_TIME_NONE;
4636 demux->seek_offset = -1;
4637 GST_OBJECT_UNLOCK (demux);
4639 /* chain will send initial segment after pads have been added,
4640 * or otherwise come up with one */
4641 GST_DEBUG_OBJECT (demux, "eating event");
4642 gst_event_unref (event);
4648 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
4649 gst_event_unref (event);
4650 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4651 (NULL), ("got eos and didn't receive a complete header object"));
4652 } else if (demux->common.num_streams == 0) {
4653 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4654 (NULL), ("got eos but no streams (yet)"));
4656 gst_matroska_demux_send_event (demux, event);
4660 case GST_EVENT_FLUSH_STOP:
4664 gst_adapter_clear (demux->common.adapter);
4665 GST_OBJECT_LOCK (demux);
4666 gst_matroska_read_common_reset_streams (&demux->common,
4667 GST_CLOCK_TIME_NONE, TRUE);
4668 dur = demux->common.segment.duration;
4669 gst_segment_init (&demux->common.segment, GST_FORMAT_TIME);
4670 demux->common.segment.duration = dur;
4671 demux->cluster_time = GST_CLOCK_TIME_NONE;
4672 demux->cluster_offset = 0;
4673 GST_OBJECT_UNLOCK (demux);
4677 res = gst_pad_event_default (pad, parent, event);
4685 gst_matroska_demux_sink_activate (GstPad * sinkpad, GstObject * parent)
4687 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4689 gboolean pull_mode = FALSE;
4691 query = gst_query_new_scheduling ();
4693 if (gst_pad_peer_query (sinkpad, query))
4694 pull_mode = gst_query_has_scheduling_mode_with_flags (query,
4695 GST_PAD_MODE_PULL, GST_SCHEDULING_FLAG_SEEKABLE);
4697 gst_query_unref (query);
4700 GST_DEBUG ("going to pull mode");
4701 demux->streaming = FALSE;
4702 return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PULL, TRUE);
4704 GST_DEBUG ("going to push (streaming) mode");
4705 demux->streaming = TRUE;
4706 return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PUSH, TRUE);
4711 gst_matroska_demux_sink_activate_mode (GstPad * sinkpad, GstObject * parent,
4712 GstPadMode mode, gboolean active)
4715 case GST_PAD_MODE_PULL:
4717 /* if we have a scheduler we can start the task */
4718 gst_pad_start_task (sinkpad, (GstTaskFunction) gst_matroska_demux_loop,
4721 gst_pad_stop_task (sinkpad);
4724 case GST_PAD_MODE_PUSH:
4732 gst_duration_to_fraction (guint64 duration, gint * dest_n, gint * dest_d)
4734 static const int common_den[] = { 1, 2, 3, 4, 1001 };
4739 for (i = 0; i < G_N_ELEMENTS (common_den); i++) {
4741 n = floor (0.5 + (d * 1e9) / duration);
4743 a = gst_util_uint64_scale_int (1000000000, d, n);
4744 if (duration >= a - 2 && duration <= a + 2) {
4750 gst_util_double_to_fraction (1e9 / duration, &n, &d);
4759 gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext *
4760 videocontext, const gchar * codec_id, guint8 * data, guint size,
4761 gchar ** codec_name, guint32 * riff_fourcc)
4763 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) videocontext;
4764 GstCaps *caps = NULL;
4766 g_assert (videocontext != NULL);
4767 g_assert (codec_name != NULL);
4772 /* TODO: check if we have all codec types from matroska-ids.h
4773 * check if we have to do more special things with codec_private
4776 * GST_MATROSKA_CODEC_ID_VIDEO_QUICKTIME
4777 * GST_MATROSKA_CODEC_ID_VIDEO_SNOW
4780 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VFW_FOURCC)) {
4781 gst_riff_strf_vids *vids = NULL;
4784 GstBuffer *buf = NULL;
4786 vids = (gst_riff_strf_vids *) data;
4788 /* assure size is big enough */
4790 GST_WARNING ("Too small BITMAPINFOHEADER (%d bytes)", size);
4793 if (size < sizeof (gst_riff_strf_vids)) {
4794 vids = g_new (gst_riff_strf_vids, 1);
4795 memcpy (vids, data, size);
4798 /* little-endian -> byte-order */
4799 vids->size = GUINT32_FROM_LE (vids->size);
4800 vids->width = GUINT32_FROM_LE (vids->width);
4801 vids->height = GUINT32_FROM_LE (vids->height);
4802 vids->planes = GUINT16_FROM_LE (vids->planes);
4803 vids->bit_cnt = GUINT16_FROM_LE (vids->bit_cnt);
4804 vids->compression = GUINT32_FROM_LE (vids->compression);
4805 vids->image_size = GUINT32_FROM_LE (vids->image_size);
4806 vids->xpels_meter = GUINT32_FROM_LE (vids->xpels_meter);
4807 vids->ypels_meter = GUINT32_FROM_LE (vids->ypels_meter);
4808 vids->num_colors = GUINT32_FROM_LE (vids->num_colors);
4809 vids->imp_colors = GUINT32_FROM_LE (vids->imp_colors);
4811 if (size > sizeof (gst_riff_strf_vids)) { /* some extra_data */
4812 gsize offset = sizeof (gst_riff_strf_vids);
4815 gst_buffer_new_wrapped (g_memdup ((guint8 *) vids + offset,
4816 size - offset), size - offset);
4820 *riff_fourcc = vids->compression;
4822 caps = gst_riff_create_video_caps (vids->compression, NULL, vids,
4823 buf, NULL, codec_name);
4826 GST_WARNING ("Unhandled RIFF fourcc %" GST_FOURCC_FORMAT,
4827 GST_FOURCC_ARGS (vids->compression));
4831 gst_buffer_unref (buf);
4833 if (vids != (gst_riff_strf_vids *) data)
4836 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_UNCOMPRESSED)) {
4838 GstVideoFormat format;
4840 gst_video_info_init (&info);
4841 switch (videocontext->fourcc) {
4842 case GST_MAKE_FOURCC ('I', '4', '2', '0'):
4843 format = GST_VIDEO_FORMAT_I420;
4845 case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
4846 format = GST_VIDEO_FORMAT_YUY2;
4848 case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
4849 format = GST_VIDEO_FORMAT_YV12;
4851 case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
4852 format = GST_VIDEO_FORMAT_UYVY;
4854 case GST_MAKE_FOURCC ('A', 'Y', 'U', 'V'):
4855 format = GST_VIDEO_FORMAT_AYUV;
4857 case GST_MAKE_FOURCC ('Y', '8', '0', '0'):
4858 case GST_MAKE_FOURCC ('Y', '8', ' ', ' '):
4859 format = GST_VIDEO_FORMAT_GRAY8;
4861 case GST_MAKE_FOURCC ('R', 'G', 'B', 24):
4862 format = GST_VIDEO_FORMAT_RGB;
4864 case GST_MAKE_FOURCC ('B', 'G', 'R', 24):
4865 format = GST_VIDEO_FORMAT_BGR;
4868 GST_DEBUG ("Unknown fourcc %" GST_FOURCC_FORMAT,
4869 GST_FOURCC_ARGS (videocontext->fourcc));
4873 gst_video_info_set_format (&info, format, videocontext->pixel_width,
4874 videocontext->pixel_height);
4875 caps = gst_video_info_to_caps (&info);
4876 *codec_name = gst_pb_utils_get_codec_description (caps);
4877 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_SP)) {
4878 caps = gst_caps_new_simple ("video/x-divx",
4879 "divxversion", G_TYPE_INT, 4, NULL);
4880 *codec_name = g_strdup ("MPEG-4 simple profile");
4881 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP) ||
4882 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AP)) {
4883 caps = gst_caps_new_simple ("video/mpeg",
4884 "mpegversion", G_TYPE_INT, 4,
4885 "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
4889 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
4890 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
4891 gst_buffer_unref (priv);
4893 gst_codec_utils_mpeg4video_caps_set_level_and_profile (caps, data, size);
4895 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP))
4896 *codec_name = g_strdup ("MPEG-4 advanced simple profile");
4898 *codec_name = g_strdup ("MPEG-4 advanced profile");
4899 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MSMPEG4V3)) {
4901 caps = gst_caps_new_full (gst_structure_new ("video/x-divx",
4902 "divxversion", G_TYPE_INT, 3, NULL),
4903 gst_structure_new ("video/x-msmpeg",
4904 "msmpegversion", G_TYPE_INT, 43, NULL), NULL);
4906 caps = gst_caps_new_simple ("video/x-msmpeg",
4907 "msmpegversion", G_TYPE_INT, 43, NULL);
4908 *codec_name = g_strdup ("Microsoft MPEG-4 v.3");
4909 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1) ||
4910 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG2)) {
4913 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1))
4918 caps = gst_caps_new_simple ("video/mpeg",
4919 "systemstream", G_TYPE_BOOLEAN, FALSE,
4920 "mpegversion", G_TYPE_INT, mpegversion, NULL);
4921 *codec_name = g_strdup_printf ("MPEG-%d video", mpegversion);
4922 context->postprocess_frame = gst_matroska_demux_add_mpeg_seq_header;
4923 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MJPEG)) {
4924 caps = gst_caps_new_empty_simple ("image/jpeg");
4925 *codec_name = g_strdup ("Motion-JPEG");
4926 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AVC)) {
4927 caps = gst_caps_new_empty_simple ("video/x-h264");
4931 /* First byte is the version, second is the profile indication, and third
4932 * is the 5 contraint_set_flags and 3 reserved bits. Fourth byte is the
4933 * level indication. */
4934 gst_codec_utils_h264_caps_set_level_and_profile (caps, data + 1,
4937 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
4938 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
4939 gst_buffer_unref (priv);
4941 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "avc",
4942 "alignment", G_TYPE_STRING, "au", NULL);
4944 GST_WARNING ("No codec data found, assuming output is byte-stream");
4945 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
4948 *codec_name = g_strdup ("H264");
4949 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEGH_HEVC)) {
4950 caps = gst_caps_new_empty_simple ("video/x-h265");
4954 gst_codec_utils_h265_caps_set_level_tier_and_profile (caps, data + 1,
4957 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
4958 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
4959 gst_buffer_unref (priv);
4961 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "hvc1",
4962 "alignment", G_TYPE_STRING, "au", NULL);
4964 GST_WARNING ("No codec data found, assuming output is byte-stream");
4965 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
4968 *codec_name = g_strdup ("HEVC");
4969 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1)) ||
4970 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2)) ||
4971 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3)) ||
4972 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))) {
4973 gint rmversion = -1;
4975 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1))
4977 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2))
4979 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3))
4981 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))
4984 caps = gst_caps_new_simple ("video/x-pn-realvideo",
4985 "rmversion", G_TYPE_INT, rmversion, NULL);
4986 GST_DEBUG ("data:%p, size:0x%x", data, size);
4987 /* We need to extract the extradata ! */
4988 if (data && (size >= 0x22)) {
4993 subformat = GST_READ_UINT32_BE (data + 0x1a);
4994 rformat = GST_READ_UINT32_BE (data + 0x1e);
4997 gst_buffer_new_wrapped (g_memdup (data + 0x1a, size - 0x1a),
4999 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, "format",
5000 G_TYPE_INT, rformat, "subformat", G_TYPE_INT, subformat, NULL);
5001 gst_buffer_unref (priv);
5004 *codec_name = g_strdup_printf ("RealVideo %d.0", rmversion);
5005 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_THEORA)) {
5006 caps = gst_caps_new_empty_simple ("video/x-theora");
5007 context->stream_headers =
5008 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
5009 context->codec_priv_size);
5010 /* FIXME: mark stream as broken and skip if there are no stream headers */
5011 context->send_stream_headers = TRUE;
5012 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_DIRAC)) {
5013 caps = gst_caps_new_empty_simple ("video/x-dirac");
5014 *codec_name = g_strdup_printf ("Dirac");
5015 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8)) {
5016 caps = gst_caps_new_empty_simple ("video/x-vp8");
5017 *codec_name = g_strdup_printf ("On2 VP8");
5018 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP9)) {
5019 caps = gst_caps_new_empty_simple ("video/x-vp9");
5020 *codec_name = g_strdup_printf ("On2 VP9");
5022 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
5028 GstStructure *structure;
5030 for (i = 0; i < gst_caps_get_size (caps); i++) {
5031 structure = gst_caps_get_structure (caps, i);
5033 /* FIXME: use the real unit here! */
5034 GST_DEBUG ("video size %dx%d, target display size %dx%d (any unit)",
5035 videocontext->pixel_width,
5036 videocontext->pixel_height,
5037 videocontext->display_width, videocontext->display_height);
5039 /* pixel width and height are the w and h of the video in pixels */
5040 if (videocontext->pixel_width > 0 && videocontext->pixel_height > 0) {
5041 gint w = videocontext->pixel_width;
5042 gint h = videocontext->pixel_height;
5044 gst_structure_set (structure,
5045 "width", G_TYPE_INT, w, "height", G_TYPE_INT, h, NULL);
5048 if (videocontext->display_width > 0 || videocontext->display_height > 0) {
5051 if (videocontext->display_width <= 0)
5052 videocontext->display_width = videocontext->pixel_width;
5053 if (videocontext->display_height <= 0)
5054 videocontext->display_height = videocontext->pixel_height;
5056 /* calculate the pixel aspect ratio using the display and pixel w/h */
5057 n = videocontext->display_width * videocontext->pixel_height;
5058 d = videocontext->display_height * videocontext->pixel_width;
5059 GST_DEBUG ("setting PAR to %d/%d", n, d);
5060 gst_structure_set (structure, "pixel-aspect-ratio",
5062 videocontext->display_width * videocontext->pixel_height,
5063 videocontext->display_height * videocontext->pixel_width, NULL);
5066 if (videocontext->default_fps > 0.0) {
5069 gst_util_double_to_fraction (videocontext->default_fps, &fps_n, &fps_d);
5071 GST_DEBUG ("using default fps %d/%d", fps_n, fps_d);
5073 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION, fps_n,
5075 } else if (context->default_duration > 0) {
5078 gst_duration_to_fraction (context->default_duration, &fps_n, &fps_d);
5080 GST_INFO ("using default duration %" G_GUINT64_FORMAT
5081 " framerate %d/%d", context->default_duration, fps_n, fps_d);
5083 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
5084 fps_n, fps_d, NULL);
5086 /* sort of a hack to get most codecs to support,
5087 * even if the default_duration is missing */
5088 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
5092 if (videocontext->parent.flags & GST_MATROSKA_VIDEOTRACK_INTERLACED)
5093 gst_structure_set (structure, "interlace-mode", G_TYPE_STRING,
5097 caps = gst_caps_simplify (caps);
5104 * Some AAC specific code... *sigh*
5105 * FIXME: maybe we should use '15' and code the sample rate explicitly
5106 * if the sample rate doesn't match the predefined rates exactly? (tpm)
5110 aac_rate_idx (gint rate)
5114 else if (75132 <= rate)
5116 else if (55426 <= rate)
5118 else if (46009 <= rate)
5120 else if (37566 <= rate)
5122 else if (27713 <= rate)
5124 else if (23004 <= rate)
5126 else if (18783 <= rate)
5128 else if (13856 <= rate)
5130 else if (11502 <= rate)
5132 else if (9391 <= rate)
5139 aac_profile_idx (const gchar * codec_id)
5143 if (strlen (codec_id) <= 12)
5145 else if (!strncmp (&codec_id[12], "MAIN", 4))
5147 else if (!strncmp (&codec_id[12], "LC", 2))
5149 else if (!strncmp (&codec_id[12], "SSR", 3))
5158 round_up_pow2 (guint n)
5169 #define AAC_SYNC_EXTENSION_TYPE 0x02b7
5172 gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext *
5173 audiocontext, const gchar * codec_id, guint8 * data, guint size,
5174 gchar ** codec_name, guint16 * riff_audio_fmt)
5176 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) audiocontext;
5177 GstCaps *caps = NULL;
5179 g_assert (audiocontext != NULL);
5180 g_assert (codec_name != NULL);
5183 *riff_audio_fmt = 0;
5185 /* TODO: check if we have all codec types from matroska-ids.h
5186 * check if we have to do more special things with codec_private
5187 * check if we need bitdepth in different places too
5188 * implement channel position magic
5190 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID9
5191 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID10
5192 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDMC
5193 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDM2
5196 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1) ||
5197 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2) ||
5198 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L3)) {
5201 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1))
5203 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2))
5208 caps = gst_caps_new_simple ("audio/mpeg",
5209 "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, layer, NULL);
5210 *codec_name = g_strdup_printf ("MPEG-1 layer %d", layer);
5211 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE) ||
5212 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_LE)) {
5215 GstAudioFormat format;
5217 sign = (audiocontext->bitdepth != 8);
5218 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE))
5219 endianness = G_BIG_ENDIAN;
5221 endianness = G_LITTLE_ENDIAN;
5223 format = gst_audio_format_build_integer (sign, endianness,
5224 audiocontext->bitdepth, audiocontext->bitdepth);
5226 /* FIXME: Channel mask and reordering */
5227 caps = gst_caps_new_simple ("audio/x-raw",
5228 "format", G_TYPE_STRING, gst_audio_format_to_string (format),
5229 "layout", G_TYPE_STRING, "interleaved", NULL);
5231 *codec_name = g_strdup_printf ("Raw %d-bit PCM audio",
5232 audiocontext->bitdepth);
5233 context->alignment = GST_ROUND_UP_8 (audiocontext->bitdepth) / 8;
5234 context->alignment = round_up_pow2 (context->alignment);
5235 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_FLOAT)) {
5236 const gchar *format;
5237 if (audiocontext->bitdepth == 32)
5241 /* FIXME: Channel mask and reordering */
5242 caps = gst_caps_new_simple ("audio/x-raw",
5243 "format", G_TYPE_STRING, format,
5244 "layout", G_TYPE_STRING, "interleaved", NULL);
5245 *codec_name = g_strdup_printf ("Raw %d-bit floating-point audio",
5246 audiocontext->bitdepth);
5247 context->alignment = audiocontext->bitdepth / 8;
5248 context->alignment = round_up_pow2 (context->alignment);
5249 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AC3,
5250 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AC3))) {
5251 caps = gst_caps_new_simple ("audio/x-ac3",
5252 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5253 *codec_name = g_strdup ("AC-3 audio");
5254 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_EAC3,
5255 strlen (GST_MATROSKA_CODEC_ID_AUDIO_EAC3))) {
5256 caps = gst_caps_new_simple ("audio/x-eac3",
5257 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5258 *codec_name = g_strdup ("E-AC-3 audio");
5259 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TRUEHD,
5260 strlen (GST_MATROSKA_CODEC_ID_AUDIO_TRUEHD))) {
5261 caps = gst_caps_new_empty_simple ("audio/x-true-hd");
5262 *codec_name = g_strdup ("Dolby TrueHD");
5263 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_DTS)) {
5264 caps = gst_caps_new_empty_simple ("audio/x-dts");
5265 *codec_name = g_strdup ("DTS audio");
5266 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_VORBIS)) {
5267 caps = gst_caps_new_empty_simple ("audio/x-vorbis");
5268 context->stream_headers =
5269 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
5270 context->codec_priv_size);
5271 /* FIXME: mark stream as broken and skip if there are no stream headers */
5272 context->send_stream_headers = TRUE;
5273 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_FLAC)) {
5274 caps = gst_caps_new_empty_simple ("audio/x-flac");
5275 context->stream_headers =
5276 gst_matroska_parse_flac_stream_headers (context->codec_priv,
5277 context->codec_priv_size);
5278 /* FIXME: mark stream as broken and skip if there are no stream headers */
5279 context->send_stream_headers = TRUE;
5280 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_SPEEX)) {
5281 caps = gst_caps_new_empty_simple ("audio/x-speex");
5282 context->stream_headers =
5283 gst_matroska_parse_speex_stream_headers (context->codec_priv,
5284 context->codec_priv_size);
5285 /* FIXME: mark stream as broken and skip if there are no stream headers */
5286 context->send_stream_headers = TRUE;
5287 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_OPUS)) {
5288 caps = gst_caps_new_empty_simple ("audio/x-opus");
5289 *codec_name = g_strdup ("Opus");
5290 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_ACM)) {
5291 gst_riff_strf_auds auds;
5293 if (data && size >= 18) {
5294 GstBuffer *codec_data = NULL;
5296 /* little-endian -> byte-order */
5297 auds.format = GST_READ_UINT16_LE (data);
5298 auds.channels = GST_READ_UINT16_LE (data + 2);
5299 auds.rate = GST_READ_UINT32_LE (data + 4);
5300 auds.av_bps = GST_READ_UINT32_LE (data + 8);
5301 auds.blockalign = GST_READ_UINT16_LE (data + 12);
5302 auds.bits_per_sample = GST_READ_UINT16_LE (data + 16);
5304 /* 18 is the waveformatex size */
5306 codec_data = gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY,
5307 data + 18, size - 18, 0, size - 18, NULL, NULL);
5311 *riff_audio_fmt = auds.format;
5313 /* FIXME: Handle reorder map */
5314 caps = gst_riff_create_audio_caps (auds.format, NULL, &auds, NULL,
5315 codec_data, codec_name, NULL);
5317 gst_buffer_unref (codec_data);
5320 GST_WARNING ("Unhandled RIFF audio format 0x%02x", auds.format);
5323 GST_WARNING ("Invalid codec data size (%d expected, got %d)", 18, size);
5325 } else if (g_str_has_prefix (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC)) {
5326 GstBuffer *priv = NULL;
5328 gint rate_idx, profile;
5329 guint8 *data = NULL;
5331 /* unspecified AAC profile with opaque private codec data */
5332 if (strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC) == 0) {
5333 if (context->codec_priv_size >= 2) {
5334 guint obj_type, freq_index, explicit_freq_bytes = 0;
5336 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
5338 freq_index = (GST_READ_UINT16_BE (context->codec_priv) & 0x780) >> 7;
5339 obj_type = (GST_READ_UINT16_BE (context->codec_priv) & 0xF800) >> 11;
5340 if (freq_index == 15)
5341 explicit_freq_bytes = 3;
5342 GST_DEBUG ("obj_type = %u, freq_index = %u", obj_type, freq_index);
5343 priv = gst_buffer_new_wrapped (g_memdup (context->codec_priv,
5344 context->codec_priv_size), context->codec_priv_size);
5345 /* assume SBR if samplerate <= 24kHz */
5346 if (obj_type == 5 || (freq_index >= 6 && freq_index != 15) ||
5347 (context->codec_priv_size == (5 + explicit_freq_bytes))) {
5348 audiocontext->samplerate *= 2;
5351 GST_WARNING ("Opaque A_AAC codec ID, but no codec private data");
5352 /* this is pretty broken;
5353 * maybe we need to make up some default private,
5354 * or maybe ADTS data got dumped in.
5355 * Let's set up some private data now, and check actual data later */
5356 /* just try this and see what happens ... */
5357 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
5358 context->postprocess_frame = gst_matroska_demux_check_aac;
5362 /* make up decoder-specific data if it is not supplied */
5366 priv = gst_buffer_new_allocate (NULL, 5, NULL);
5367 gst_buffer_map (priv, &map, GST_MAP_WRITE);
5369 rate_idx = aac_rate_idx (audiocontext->samplerate);
5370 profile = aac_profile_idx (codec_id);
5372 data[0] = ((profile + 1) << 3) | ((rate_idx & 0xE) >> 1);
5373 data[1] = ((rate_idx & 0x1) << 7) | (audiocontext->channels << 3);
5375 if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2,
5376 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2))) {
5378 gst_buffer_unmap (priv, &map);
5379 gst_buffer_set_size (priv, 2);
5380 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4,
5381 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4))) {
5384 if (g_strrstr (codec_id, "SBR")) {
5385 /* HE-AAC (aka SBR AAC) */
5386 audiocontext->samplerate *= 2;
5387 rate_idx = aac_rate_idx (audiocontext->samplerate);
5388 data[2] = AAC_SYNC_EXTENSION_TYPE >> 3;
5389 data[3] = ((AAC_SYNC_EXTENSION_TYPE & 0x07) << 5) | 5;
5390 data[4] = (1 << 7) | (rate_idx << 3);
5391 gst_buffer_unmap (priv, &map);
5393 gst_buffer_unmap (priv, &map);
5394 gst_buffer_set_size (priv, 2);
5397 gst_buffer_unmap (priv, &map);
5398 gst_buffer_unref (priv);
5400 GST_ERROR ("Unknown AAC profile and no codec private data");
5405 caps = gst_caps_new_simple ("audio/mpeg",
5406 "mpegversion", G_TYPE_INT, mpegversion,
5407 "framed", G_TYPE_BOOLEAN, TRUE,
5408 "stream-format", G_TYPE_STRING, "raw", NULL);
5409 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5410 if (context->codec_priv && context->codec_priv_size > 0)
5411 gst_codec_utils_aac_caps_set_level_and_profile (caps,
5412 context->codec_priv, context->codec_priv_size);
5413 *codec_name = g_strdup_printf ("MPEG-%d AAC audio", mpegversion);
5414 gst_buffer_unref (priv);
5416 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TTA)) {
5417 caps = gst_caps_new_simple ("audio/x-tta",
5418 "width", G_TYPE_INT, audiocontext->bitdepth, NULL);
5419 *codec_name = g_strdup ("TTA audio");
5420 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_WAVPACK4)) {
5421 caps = gst_caps_new_simple ("audio/x-wavpack",
5422 "width", G_TYPE_INT, audiocontext->bitdepth,
5423 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5424 *codec_name = g_strdup ("Wavpack audio");
5425 context->postprocess_frame = gst_matroska_demux_add_wvpk_header;
5426 audiocontext->wvpk_block_index = 0;
5427 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4)) ||
5428 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4)) ||
5429 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))) {
5430 gint raversion = -1;
5432 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4))
5434 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))
5439 caps = gst_caps_new_simple ("audio/x-pn-realaudio",
5440 "raversion", G_TYPE_INT, raversion, NULL);
5441 /* Extract extra information from caps, mapping varies based on codec */
5442 if (data && (size >= 0x50)) {
5449 guint extra_data_size;
5451 GST_ERROR ("real audio raversion:%d", raversion);
5452 if (raversion == 8) {
5454 flavor = GST_READ_UINT16_BE (data + 22);
5455 packet_size = GST_READ_UINT32_BE (data + 24);
5456 height = GST_READ_UINT16_BE (data + 40);
5457 leaf_size = GST_READ_UINT16_BE (data + 44);
5458 sample_width = GST_READ_UINT16_BE (data + 58);
5459 extra_data_size = GST_READ_UINT32_BE (data + 74);
5462 ("flavor:%d, packet_size:%d, height:%d, leaf_size:%d, sample_width:%d, extra_data_size:%d",
5463 flavor, packet_size, height, leaf_size, sample_width,
5465 gst_caps_set_simple (caps, "flavor", G_TYPE_INT, flavor, "packet_size",
5466 G_TYPE_INT, packet_size, "height", G_TYPE_INT, height, "leaf_size",
5467 G_TYPE_INT, leaf_size, "width", G_TYPE_INT, sample_width, NULL);
5469 if ((size - 78) >= extra_data_size) {
5470 priv = gst_buffer_new_wrapped (g_memdup (data + 78, extra_data_size),
5472 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5473 gst_buffer_unref (priv);
5478 *codec_name = g_strdup_printf ("RealAudio %d.0", raversion);
5479 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_SIPR)) {
5480 caps = gst_caps_new_empty_simple ("audio/x-sipro");
5481 *codec_name = g_strdup ("Sipro/ACELP.NET Voice Codec");
5482 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_RALF)) {
5483 caps = gst_caps_new_empty_simple ("audio/x-ralf-mpeg4-generic");
5484 *codec_name = g_strdup ("Real Audio Lossless");
5485 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_ATRC)) {
5486 caps = gst_caps_new_empty_simple ("audio/x-vnd.sony.atrac3");
5487 *codec_name = g_strdup ("Sony ATRAC3");
5489 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
5494 if (audiocontext->samplerate > 0 && audiocontext->channels > 0) {
5497 for (i = 0; i < gst_caps_get_size (caps); i++) {
5498 gst_structure_set (gst_caps_get_structure (caps, i),
5499 "channels", G_TYPE_INT, audiocontext->channels,
5500 "rate", G_TYPE_INT, audiocontext->samplerate, NULL);
5504 caps = gst_caps_simplify (caps);
5511 gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
5512 subtitlecontext, const gchar * codec_id, gpointer data, guint size)
5514 GstCaps *caps = NULL;
5515 GstMatroskaTrackContext *context =
5516 (GstMatroskaTrackContext *) subtitlecontext;
5518 /* for backwards compatibility */
5519 if (!g_ascii_strcasecmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASCII))
5520 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8;
5521 else if (!g_ascii_strcasecmp (codec_id, "S_SSA"))
5522 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_SSA;
5523 else if (!g_ascii_strcasecmp (codec_id, "S_ASS"))
5524 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_ASS;
5525 else if (!g_ascii_strcasecmp (codec_id, "S_USF"))
5526 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_USF;
5528 /* TODO: Add GST_MATROSKA_CODEC_ID_SUBTITLE_BMP support
5529 * Check if we have to do something with codec_private */
5530 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8)) {
5531 /* well, plain text simply does not have a lot of markup ... */
5532 caps = gst_caps_new_simple ("text/x-raw", "format", G_TYPE_STRING,
5533 "pango-markup", NULL);
5534 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5535 subtitlecontext->check_markup = TRUE;
5536 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_SSA)) {
5537 caps = gst_caps_new_empty_simple ("application/x-ssa");
5538 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5539 subtitlecontext->check_markup = FALSE;
5540 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASS)) {
5541 caps = gst_caps_new_empty_simple ("application/x-ass");
5542 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5543 subtitlecontext->check_markup = FALSE;
5544 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_USF)) {
5545 caps = gst_caps_new_empty_simple ("application/x-usf");
5546 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5547 subtitlecontext->check_markup = FALSE;
5548 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB)) {
5549 caps = gst_caps_new_empty_simple ("subpicture/x-dvd");
5550 ((GstMatroskaTrackContext *) subtitlecontext)->send_dvd_event = TRUE;
5551 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_HDMVPGS)) {
5552 caps = gst_caps_new_empty_simple ("subpicture/x-pgs");
5553 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_KATE)) {
5554 caps = gst_caps_new_empty_simple ("subtitle/x-kate");
5555 context->stream_headers =
5556 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
5557 context->codec_priv_size);
5558 /* FIXME: mark stream as broken and skip if there are no stream headers */
5559 context->send_stream_headers = TRUE;
5561 GST_DEBUG ("Unknown subtitle stream: codec_id='%s'", codec_id);
5562 caps = gst_caps_new_empty_simple ("application/x-subtitle-unknown");
5565 if (data != NULL && size > 0) {
5568 buf = gst_buffer_new_wrapped (g_memdup (data, size), size);
5569 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, buf, NULL);
5570 gst_buffer_unref (buf);
5578 gst_matroska_demux_set_index (GstElement * element, GstIndex * index)
5580 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5582 GST_OBJECT_LOCK (demux);
5583 if (demux->common.element_index)
5584 gst_object_unref (demux->common.element_index);
5585 demux->common.element_index = index ? gst_object_ref (index) : NULL;
5586 GST_OBJECT_UNLOCK (demux);
5587 GST_DEBUG_OBJECT (demux, "Set index %" GST_PTR_FORMAT,
5588 demux->common.element_index);
5592 gst_matroska_demux_get_index (GstElement * element)
5594 GstIndex *result = NULL;
5595 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5597 GST_OBJECT_LOCK (demux);
5598 if (demux->common.element_index)
5599 result = gst_object_ref (demux->common.element_index);
5600 GST_OBJECT_UNLOCK (demux);
5602 GST_DEBUG_OBJECT (demux, "Returning index %" GST_PTR_FORMAT, result);
5608 static GstStateChangeReturn
5609 gst_matroska_demux_change_state (GstElement * element,
5610 GstStateChange transition)
5612 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5613 GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
5615 /* handle upwards state changes here */
5616 switch (transition) {
5621 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
5623 /* handle downwards state changes */
5624 switch (transition) {
5625 case GST_STATE_CHANGE_PAUSED_TO_READY:
5626 gst_matroska_demux_reset (GST_ELEMENT (demux));
5636 gst_matroska_demux_set_property (GObject * object,
5637 guint prop_id, const GValue * value, GParamSpec * pspec)
5639 GstMatroskaDemux *demux;
5641 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
5642 demux = GST_MATROSKA_DEMUX (object);
5645 case ARG_MAX_GAP_TIME:
5646 GST_OBJECT_LOCK (demux);
5647 demux->max_gap_time = g_value_get_uint64 (value);
5648 GST_OBJECT_UNLOCK (demux);
5651 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
5657 gst_matroska_demux_get_property (GObject * object,
5658 guint prop_id, GValue * value, GParamSpec * pspec)
5660 GstMatroskaDemux *demux;
5662 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
5663 demux = GST_MATROSKA_DEMUX (object);
5666 case ARG_MAX_GAP_TIME:
5667 GST_OBJECT_LOCK (demux);
5668 g_value_set_uint64 (value, demux->max_gap_time);
5669 GST_OBJECT_UNLOCK (demux);
5672 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
5678 gst_matroska_demux_plugin_init (GstPlugin * plugin)
5682 /* parser helper separate debug */
5683 GST_DEBUG_CATEGORY_INIT (ebmlread_debug, "ebmlread",
5684 0, "EBML stream helper class");
5686 /* create an elementfactory for the matroska_demux element */
5687 if (!gst_element_register (plugin, "matroskademux",
5688 GST_RANK_PRIMARY, GST_TYPE_MATROSKA_DEMUX))