1 /* GStreamer Matroska muxer/demuxer
2 * (c) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
3 * (c) 2006 Tim-Philipp Müller <tim centricular net>
4 * (c) 2008 Sebastian Dröge <slomo@circular-chaos.org>
5 * (c) 2011 Debarshi Ray <rishi@gnu.org>
7 * matroska-demux.c: matroska file/stream demuxer
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Library General Public License for more details.
19 * You should have received a copy of the GNU Library General Public
20 * License along with this library; if not, write to the
21 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
22 * Boston, MA 02110-1301, USA.
25 /* TODO: check CRC32 if present
26 * TODO: there can be a segment after the first segment. Handle like
27 * chained oggs. Fixes #334082
28 * TODO: Test samples: http://www.matroska.org/samples/matrix/index.html
29 * http://samples.mplayerhq.hu/Matroska/
30 * TODO: check if demuxing is done correct for all codecs according to spec
31 * TODO: seeking with incomplete or without CUE
35 * SECTION:element-matroskademux
37 * matroskademux demuxes a Matroska file into the different contained streams.
40 * <title>Example launch line</title>
42 * gst-launch-1.0 -v filesrc location=/path/to/mkv ! matroskademux ! vorbisdec ! audioconvert ! audioresample ! autoaudiosink
43 * ]| This pipeline demuxes a Matroska file and outputs the contained Vorbis audio.
54 #include <glib/gprintf.h>
56 /* For AVI compatibility mode
57 and for fourcc stuff */
58 #include <gst/riff/riff-read.h>
59 #include <gst/riff/riff-ids.h>
60 #include <gst/riff/riff-media.h>
62 #include <gst/audio/audio.h>
63 #include <gst/tag/tag.h>
64 #include <gst/pbutils/pbutils.h>
65 #include <gst/video/video.h>
67 #include "matroska-demux.h"
68 #include "matroska-ids.h"
70 GST_DEBUG_CATEGORY_STATIC (matroskademux_debug);
71 #define GST_CAT_DEFAULT matroskademux_debug
73 #define DEBUG_ELEMENT_START(demux, ebml, element) \
74 GST_DEBUG_OBJECT (demux, "Parsing " element " element at offset %" \
75 G_GUINT64_FORMAT, gst_ebml_read_get_pos (ebml))
77 #define DEBUG_ELEMENT_STOP(demux, ebml, element, ret) \
78 GST_DEBUG_OBJECT (demux, "Parsing " element " element " \
79 " finished with '%s'", gst_flow_get_name (ret))
89 #define DEFAULT_MAX_GAP_TIME (2 * GST_SECOND)
91 static GstStaticPadTemplate sink_templ = GST_STATIC_PAD_TEMPLATE ("sink",
94 GST_STATIC_CAPS ("audio/x-matroska; video/x-matroska; "
95 "video/x-matroska-3d; audio/webm; video/webm")
98 /* TODO: fill in caps! */
100 static GstStaticPadTemplate audio_src_templ =
101 GST_STATIC_PAD_TEMPLATE ("audio_%u",
104 GST_STATIC_CAPS ("ANY")
107 static GstStaticPadTemplate video_src_templ =
108 GST_STATIC_PAD_TEMPLATE ("video_%u",
111 GST_STATIC_CAPS ("ANY")
114 static GstStaticPadTemplate subtitle_src_templ =
115 GST_STATIC_PAD_TEMPLATE ("subtitle_%u",
118 GST_STATIC_CAPS ("text/x-raw, format=pango-markup; application/x-ssa; "
119 "application/x-ass;application/x-usf; subpicture/x-dvd; "
120 "subpicture/x-pgs; subtitle/x-kate; " "application/x-subtitle-unknown")
123 static GstFlowReturn gst_matroska_demux_parse_id (GstMatroskaDemux * demux,
124 guint32 id, guint64 length, guint needed);
126 /* element functions */
127 static void gst_matroska_demux_loop (GstPad * pad);
129 static gboolean gst_matroska_demux_element_send_event (GstElement * element,
131 static gboolean gst_matroska_demux_element_query (GstElement * element,
135 static gboolean gst_matroska_demux_sink_activate (GstPad * sinkpad,
137 static gboolean gst_matroska_demux_sink_activate_mode (GstPad * sinkpad,
138 GstObject * parent, GstPadMode mode, gboolean active);
140 static gboolean gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
141 GstPad * pad, GstEvent * event);
142 static gboolean gst_matroska_demux_handle_src_event (GstPad * pad,
143 GstObject * parent, GstEvent * event);
144 static gboolean gst_matroska_demux_handle_src_query (GstPad * pad,
145 GstObject * parent, GstQuery * query);
147 static gboolean gst_matroska_demux_handle_sink_event (GstPad * pad,
148 GstObject * parent, GstEvent * event);
149 static GstFlowReturn gst_matroska_demux_chain (GstPad * pad,
150 GstObject * object, GstBuffer * buffer);
152 static GstStateChangeReturn
153 gst_matroska_demux_change_state (GstElement * element,
154 GstStateChange transition);
157 gst_matroska_demux_set_index (GstElement * element, GstIndex * index);
158 static GstIndex *gst_matroska_demux_get_index (GstElement * element);
162 static GstCaps *gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext
163 * videocontext, const gchar * codec_id, guint8 * data, guint size,
164 gchar ** codec_name, guint32 * riff_fourcc);
165 static GstCaps *gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext
166 * audiocontext, const gchar * codec_id, guint8 * data, guint size,
167 gchar ** codec_name, guint16 * riff_audio_fmt);
169 * gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
170 subtitlecontext, const gchar * codec_id, gpointer data, guint size);
173 static void gst_matroska_demux_reset (GstElement * element);
174 static gboolean perform_seek_to_offset (GstMatroskaDemux * demux,
175 gdouble rate, guint64 offset, guint32 seqnum);
177 /* gobject functions */
178 static void gst_matroska_demux_set_property (GObject * object,
179 guint prop_id, const GValue * value, GParamSpec * pspec);
180 static void gst_matroska_demux_get_property (GObject * object,
181 guint prop_id, GValue * value, GParamSpec * pspec);
183 GType gst_matroska_demux_get_type (void);
184 #define parent_class gst_matroska_demux_parent_class
185 G_DEFINE_TYPE (GstMatroskaDemux, gst_matroska_demux, GST_TYPE_ELEMENT);
188 gst_matroska_demux_finalize (GObject * object)
190 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (object);
192 gst_matroska_read_common_finalize (&demux->common);
193 gst_flow_combiner_free (demux->flowcombiner);
194 G_OBJECT_CLASS (parent_class)->finalize (object);
198 gst_matroska_demux_class_init (GstMatroskaDemuxClass * klass)
200 GObjectClass *gobject_class = (GObjectClass *) klass;
201 GstElementClass *gstelement_class = (GstElementClass *) klass;
203 GST_DEBUG_CATEGORY_INIT (matroskademux_debug, "matroskademux", 0,
206 gobject_class->finalize = gst_matroska_demux_finalize;
208 gobject_class->get_property = gst_matroska_demux_get_property;
209 gobject_class->set_property = gst_matroska_demux_set_property;
211 g_object_class_install_property (gobject_class, ARG_MAX_GAP_TIME,
212 g_param_spec_uint64 ("max-gap-time", "Maximum gap time",
213 "The demuxer sends out segment events for skipping "
214 "gaps longer than this (0 = disabled).", 0, G_MAXUINT64,
215 DEFAULT_MAX_GAP_TIME, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
217 gstelement_class->change_state =
218 GST_DEBUG_FUNCPTR (gst_matroska_demux_change_state);
219 gstelement_class->send_event =
220 GST_DEBUG_FUNCPTR (gst_matroska_demux_element_send_event);
221 gstelement_class->query =
222 GST_DEBUG_FUNCPTR (gst_matroska_demux_element_query);
224 gstelement_class->set_index =
225 GST_DEBUG_FUNCPTR (gst_matroska_demux_set_index);
226 gstelement_class->get_index =
227 GST_DEBUG_FUNCPTR (gst_matroska_demux_get_index);
230 gst_element_class_add_pad_template (gstelement_class,
231 gst_static_pad_template_get (&video_src_templ));
232 gst_element_class_add_pad_template (gstelement_class,
233 gst_static_pad_template_get (&audio_src_templ));
234 gst_element_class_add_pad_template (gstelement_class,
235 gst_static_pad_template_get (&subtitle_src_templ));
236 gst_element_class_add_pad_template (gstelement_class,
237 gst_static_pad_template_get (&sink_templ));
239 gst_element_class_set_static_metadata (gstelement_class, "Matroska demuxer",
241 "Demuxes Matroska/WebM streams into video/audio/subtitles",
242 "GStreamer maintainers <gstreamer-devel@lists.sourceforge.net>");
246 gst_matroska_demux_init (GstMatroskaDemux * demux)
248 demux->common.sinkpad = gst_pad_new_from_static_template (&sink_templ,
250 gst_pad_set_activate_function (demux->common.sinkpad,
251 GST_DEBUG_FUNCPTR (gst_matroska_demux_sink_activate));
252 gst_pad_set_activatemode_function (demux->common.sinkpad,
253 GST_DEBUG_FUNCPTR (gst_matroska_demux_sink_activate_mode));
254 gst_pad_set_chain_function (demux->common.sinkpad,
255 GST_DEBUG_FUNCPTR (gst_matroska_demux_chain));
256 gst_pad_set_event_function (demux->common.sinkpad,
257 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_sink_event));
258 gst_element_add_pad (GST_ELEMENT (demux), demux->common.sinkpad);
260 /* init defaults for common read context */
261 gst_matroska_read_common_init (&demux->common);
263 /* property defaults */
264 demux->max_gap_time = DEFAULT_MAX_GAP_TIME;
266 GST_OBJECT_FLAG_SET (demux, GST_ELEMENT_FLAG_INDEXABLE);
268 demux->flowcombiner = gst_flow_combiner_new ();
271 gst_matroska_demux_reset (GST_ELEMENT (demux));
275 gst_matroska_demux_reset (GstElement * element)
277 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
279 GST_DEBUG_OBJECT (demux, "Resetting state");
281 gst_matroska_read_common_reset (GST_ELEMENT (demux), &demux->common);
283 demux->num_a_streams = 0;
284 demux->num_t_streams = 0;
285 demux->num_v_streams = 0;
287 demux->have_group_id = FALSE;
288 demux->group_id = G_MAXUINT;
291 demux->tracks_parsed = FALSE;
293 if (demux->clusters) {
294 g_array_free (demux->clusters, TRUE);
295 demux->clusters = NULL;
298 g_list_foreach (demux->seek_parsed,
299 (GFunc) gst_matroska_read_common_free_parsed_el, NULL);
300 g_list_free (demux->seek_parsed);
301 demux->seek_parsed = NULL;
303 demux->last_stop_end = GST_CLOCK_TIME_NONE;
304 demux->seek_block = 0;
305 demux->stream_start_time = GST_CLOCK_TIME_NONE;
306 demux->to_time = GST_CLOCK_TIME_NONE;
307 demux->cluster_time = GST_CLOCK_TIME_NONE;
308 demux->cluster_offset = 0;
309 demux->next_cluster_offset = 0;
310 demux->index_offset = 0;
311 demux->seekable = FALSE;
312 demux->need_segment = FALSE;
313 demux->segment_seqnum = 0;
314 demux->requested_seek_time = GST_CLOCK_TIME_NONE;
315 demux->seek_offset = -1;
316 demux->building_index = FALSE;
317 if (demux->seek_event) {
318 gst_event_unref (demux->seek_event);
319 demux->seek_event = NULL;
322 demux->seek_index = NULL;
323 demux->seek_entry = 0;
325 if (demux->new_segment) {
326 gst_event_unref (demux->new_segment);
327 demux->new_segment = NULL;
330 demux->invalid_duration = FALSE;
332 demux->cached_length = G_MAXUINT64;
334 gst_flow_combiner_clear (demux->flowcombiner);
338 gst_matroska_decode_buffer (GstMatroskaTrackContext * context, GstBuffer * buf)
344 g_return_val_if_fail (GST_IS_BUFFER (buf), NULL);
346 GST_DEBUG ("decoding buffer %p", buf);
348 gst_buffer_map (buf, &map, GST_MAP_READ);
352 g_return_val_if_fail (size > 0, buf);
354 if (gst_matroska_decode_data (context->encodings, &data, &size,
355 GST_MATROSKA_TRACK_ENCODING_SCOPE_FRAME, FALSE)) {
356 gst_buffer_unmap (buf, &map);
357 gst_buffer_unref (buf);
358 return gst_buffer_new_wrapped (data, size);
360 GST_DEBUG ("decode data failed");
361 gst_buffer_unmap (buf, &map);
362 gst_buffer_unref (buf);
368 gst_matroska_demux_add_stream_headers_to_caps (GstMatroskaDemux * demux,
369 GstBufferList * list, GstCaps * caps)
372 GValue arr_val = G_VALUE_INIT;
373 GValue buf_val = G_VALUE_INIT;
376 g_assert (gst_caps_is_writable (caps));
378 g_value_init (&arr_val, GST_TYPE_ARRAY);
379 g_value_init (&buf_val, GST_TYPE_BUFFER);
381 num = gst_buffer_list_length (list);
382 for (i = 0; i < num; ++i) {
383 g_value_set_boxed (&buf_val, gst_buffer_list_get (list, i));
384 gst_value_array_append_value (&arr_val, &buf_val);
387 s = gst_caps_get_structure (caps, 0);
388 gst_structure_take_value (s, "streamheader", &arr_val);
389 g_value_unset (&buf_val);
393 gst_matroska_demux_add_stream (GstMatroskaDemux * demux, GstEbmlRead * ebml)
395 GstElementClass *klass = GST_ELEMENT_GET_CLASS (demux);
396 GstMatroskaTrackContext *context;
397 GstPadTemplate *templ = NULL;
398 GstStreamFlags stream_flags;
399 GstCaps *caps = NULL;
400 gchar *padname = NULL;
402 guint32 id, riff_fourcc = 0;
403 guint16 riff_audio_fmt = 0;
404 GstEvent *stream_start;
408 DEBUG_ELEMENT_START (demux, ebml, "TrackEntry");
410 /* start with the master */
411 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
412 DEBUG_ELEMENT_STOP (demux, ebml, "TrackEntry", ret);
416 /* allocate generic... if we know the type, we'll g_renew()
417 * with the precise type */
418 context = g_new0 (GstMatroskaTrackContext, 1);
419 g_ptr_array_add (demux->common.src, context);
420 context->index = demux->common.num_streams;
421 context->index_writer_id = -1;
422 context->type = 0; /* no type yet */
423 context->default_duration = 0;
425 context->set_discont = TRUE;
426 context->timecodescale = 1.0;
428 GST_MATROSKA_TRACK_ENABLED | GST_MATROSKA_TRACK_DEFAULT |
429 GST_MATROSKA_TRACK_LACING;
430 context->from_time = GST_CLOCK_TIME_NONE;
431 context->from_offset = -1;
432 context->to_offset = G_MAXINT64;
433 context->alignment = 1;
434 context->dts_only = FALSE;
435 context->intra_only = FALSE;
436 context->tags = gst_tag_list_new_empty ();
437 demux->common.num_streams++;
438 g_assert (demux->common.src->len == demux->common.num_streams);
440 GST_DEBUG_OBJECT (demux, "Stream number %d", context->index);
442 /* try reading the trackentry headers */
443 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
444 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
448 /* track number (unique stream ID) */
449 case GST_MATROSKA_ID_TRACKNUMBER:{
452 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
456 GST_ERROR_OBJECT (demux, "Invalid TrackNumber 0");
457 ret = GST_FLOW_ERROR;
459 } else if (!gst_matroska_read_common_tracknumber_unique (&demux->common,
461 GST_ERROR_OBJECT (demux, "TrackNumber %" G_GUINT64_FORMAT
462 " is not unique", num);
463 ret = GST_FLOW_ERROR;
467 GST_DEBUG_OBJECT (demux, "TrackNumber: %" G_GUINT64_FORMAT, num);
471 /* track UID (unique identifier) */
472 case GST_MATROSKA_ID_TRACKUID:{
475 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
479 GST_ERROR_OBJECT (demux, "Invalid TrackUID 0");
480 ret = GST_FLOW_ERROR;
484 GST_DEBUG_OBJECT (demux, "TrackUID: %" G_GUINT64_FORMAT, num);
489 /* track type (video, audio, combined, subtitle, etc.) */
490 case GST_MATROSKA_ID_TRACKTYPE:{
493 if ((ret = gst_ebml_read_uint (ebml, &id, &track_type)) != GST_FLOW_OK) {
497 if (context->type != 0 && context->type != track_type) {
498 GST_WARNING_OBJECT (demux,
499 "More than one tracktype defined in a TrackEntry - skipping");
501 } else if (track_type < 1 || track_type > 254) {
502 GST_WARNING_OBJECT (demux, "Invalid TrackType %" G_GUINT64_FORMAT,
507 GST_DEBUG_OBJECT (demux, "TrackType: %" G_GUINT64_FORMAT, track_type);
509 /* ok, so we're actually going to reallocate this thing */
510 switch (track_type) {
511 case GST_MATROSKA_TRACK_TYPE_VIDEO:
512 gst_matroska_track_init_video_context (&context);
514 case GST_MATROSKA_TRACK_TYPE_AUDIO:
515 gst_matroska_track_init_audio_context (&context);
517 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
518 gst_matroska_track_init_subtitle_context (&context);
520 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
521 case GST_MATROSKA_TRACK_TYPE_LOGO:
522 case GST_MATROSKA_TRACK_TYPE_BUTTONS:
523 case GST_MATROSKA_TRACK_TYPE_CONTROL:
525 GST_WARNING_OBJECT (demux,
526 "Unknown or unsupported TrackType %" G_GUINT64_FORMAT,
531 g_ptr_array_index (demux->common.src, demux->common.num_streams - 1)
536 /* tracktype specific stuff for video */
537 case GST_MATROSKA_ID_TRACKVIDEO:{
538 GstMatroskaTrackVideoContext *videocontext;
540 DEBUG_ELEMENT_START (demux, ebml, "TrackVideo");
542 if (!gst_matroska_track_init_video_context (&context)) {
543 GST_WARNING_OBJECT (demux,
544 "TrackVideo element in non-video track - ignoring track");
545 ret = GST_FLOW_ERROR;
547 } else if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
550 videocontext = (GstMatroskaTrackVideoContext *) context;
551 g_ptr_array_index (demux->common.src, demux->common.num_streams - 1)
554 while (ret == GST_FLOW_OK &&
555 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
556 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
560 /* Should be one level up but some broken muxers write it here. */
561 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
564 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
568 GST_WARNING_OBJECT (demux, "Invalid TrackDefaultDuration 0");
572 GST_DEBUG_OBJECT (demux,
573 "TrackDefaultDuration: %" G_GUINT64_FORMAT, num);
574 context->default_duration = num;
578 /* video framerate */
579 /* NOTE: This one is here only for backward compatibility.
580 * Use _TRACKDEFAULDURATION one level up. */
581 case GST_MATROSKA_ID_VIDEOFRAMERATE:{
584 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
588 GST_WARNING_OBJECT (demux, "Invalid TrackVideoFPS %lf", num);
592 GST_DEBUG_OBJECT (demux, "TrackVideoFrameRate: %lf", num);
593 if (context->default_duration == 0)
594 context->default_duration =
595 gst_gdouble_to_guint64 ((gdouble) GST_SECOND * (1.0 / num));
596 videocontext->default_fps = num;
600 /* width of the size to display the video at */
601 case GST_MATROSKA_ID_VIDEODISPLAYWIDTH:{
604 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
608 GST_WARNING_OBJECT (demux, "Invalid TrackVideoDisplayWidth 0");
612 GST_DEBUG_OBJECT (demux,
613 "TrackVideoDisplayWidth: %" G_GUINT64_FORMAT, num);
614 videocontext->display_width = num;
618 /* height of the size to display the video at */
619 case GST_MATROSKA_ID_VIDEODISPLAYHEIGHT:{
622 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
626 GST_WARNING_OBJECT (demux, "Invalid TrackVideoDisplayHeight 0");
630 GST_DEBUG_OBJECT (demux,
631 "TrackVideoDisplayHeight: %" G_GUINT64_FORMAT, num);
632 videocontext->display_height = num;
636 /* width of the video in the file */
637 case GST_MATROSKA_ID_VIDEOPIXELWIDTH:{
640 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
644 GST_WARNING_OBJECT (demux, "Invalid TrackVideoPixelWidth 0");
648 GST_DEBUG_OBJECT (demux,
649 "TrackVideoPixelWidth: %" G_GUINT64_FORMAT, num);
650 videocontext->pixel_width = num;
654 /* height of the video in the file */
655 case GST_MATROSKA_ID_VIDEOPIXELHEIGHT:{
658 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
662 GST_WARNING_OBJECT (demux, "Invalid TrackVideoPixelHeight 0");
666 GST_DEBUG_OBJECT (demux,
667 "TrackVideoPixelHeight: %" G_GUINT64_FORMAT, num);
668 videocontext->pixel_height = num;
672 /* whether the video is interlaced */
673 case GST_MATROSKA_ID_VIDEOFLAGINTERLACED:{
676 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
680 context->flags |= GST_MATROSKA_VIDEOTRACK_INTERLACED;
682 context->flags &= ~GST_MATROSKA_VIDEOTRACK_INTERLACED;
683 GST_DEBUG_OBJECT (demux, "TrackVideoInterlaced: %d",
684 (context->flags & GST_MATROSKA_VIDEOTRACK_INTERLACED) ? 1 :
689 /* aspect ratio behaviour */
690 case GST_MATROSKA_ID_VIDEOASPECTRATIOTYPE:{
693 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
696 if (num != GST_MATROSKA_ASPECT_RATIO_MODE_FREE &&
697 num != GST_MATROSKA_ASPECT_RATIO_MODE_KEEP &&
698 num != GST_MATROSKA_ASPECT_RATIO_MODE_FIXED) {
699 GST_WARNING_OBJECT (demux,
700 "Unknown TrackVideoAspectRatioType 0x%x", (guint) num);
703 GST_DEBUG_OBJECT (demux,
704 "TrackVideoAspectRatioType: %" G_GUINT64_FORMAT, num);
705 videocontext->asr_mode = num;
709 /* colourspace (only matters for raw video) fourcc */
710 case GST_MATROSKA_ID_VIDEOCOLOURSPACE:{
715 gst_ebml_read_binary (ebml, &id, &data,
716 &datalen)) != GST_FLOW_OK)
721 GST_WARNING_OBJECT (demux,
722 "Invalid TrackVideoColourSpace length %" G_GUINT64_FORMAT,
727 memcpy (&videocontext->fourcc, data, 4);
728 GST_DEBUG_OBJECT (demux,
729 "TrackVideoColourSpace: %" GST_FOURCC_FORMAT,
730 GST_FOURCC_ARGS (videocontext->fourcc));
736 GST_WARNING_OBJECT (demux,
737 "Unknown TrackVideo subelement 0x%x - ignoring", id);
739 case GST_MATROSKA_ID_VIDEOSTEREOMODE:
740 case GST_MATROSKA_ID_VIDEODISPLAYUNIT:
741 case GST_MATROSKA_ID_VIDEOPIXELCROPBOTTOM:
742 case GST_MATROSKA_ID_VIDEOPIXELCROPTOP:
743 case GST_MATROSKA_ID_VIDEOPIXELCROPLEFT:
744 case GST_MATROSKA_ID_VIDEOPIXELCROPRIGHT:
745 case GST_MATROSKA_ID_VIDEOGAMMAVALUE:
746 ret = gst_ebml_read_skip (ebml);
751 DEBUG_ELEMENT_STOP (demux, ebml, "TrackVideo", ret);
755 /* tracktype specific stuff for audio */
756 case GST_MATROSKA_ID_TRACKAUDIO:{
757 GstMatroskaTrackAudioContext *audiocontext;
759 DEBUG_ELEMENT_START (demux, ebml, "TrackAudio");
761 if (!gst_matroska_track_init_audio_context (&context)) {
762 GST_WARNING_OBJECT (demux,
763 "TrackAudio element in non-audio track - ignoring track");
764 ret = GST_FLOW_ERROR;
768 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
771 audiocontext = (GstMatroskaTrackAudioContext *) context;
772 g_ptr_array_index (demux->common.src, demux->common.num_streams - 1)
775 while (ret == GST_FLOW_OK &&
776 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
777 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
782 case GST_MATROSKA_ID_AUDIOSAMPLINGFREQ:{
785 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
790 GST_WARNING_OBJECT (demux,
791 "Invalid TrackAudioSamplingFrequency %lf", num);
795 GST_DEBUG_OBJECT (demux, "TrackAudioSamplingFrequency: %lf", num);
796 audiocontext->samplerate = num;
801 case GST_MATROSKA_ID_AUDIOBITDEPTH:{
804 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
808 GST_WARNING_OBJECT (demux, "Invalid TrackAudioBitDepth 0");
812 GST_DEBUG_OBJECT (demux, "TrackAudioBitDepth: %" G_GUINT64_FORMAT,
814 audiocontext->bitdepth = num;
819 case GST_MATROSKA_ID_AUDIOCHANNELS:{
822 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
826 GST_WARNING_OBJECT (demux, "Invalid TrackAudioChannels 0");
830 GST_DEBUG_OBJECT (demux, "TrackAudioChannels: %" G_GUINT64_FORMAT,
832 audiocontext->channels = num;
837 GST_WARNING_OBJECT (demux,
838 "Unknown TrackAudio subelement 0x%x - ignoring", id);
840 case GST_MATROSKA_ID_AUDIOCHANNELPOSITIONS:
841 case GST_MATROSKA_ID_AUDIOOUTPUTSAMPLINGFREQ:
842 ret = gst_ebml_read_skip (ebml);
847 DEBUG_ELEMENT_STOP (demux, ebml, "TrackAudio", ret);
852 /* codec identifier */
853 case GST_MATROSKA_ID_CODECID:{
856 if ((ret = gst_ebml_read_ascii (ebml, &id, &text)) != GST_FLOW_OK)
859 GST_DEBUG_OBJECT (demux, "CodecID: %s", GST_STR_NULL (text));
860 context->codec_id = text;
864 /* codec private data */
865 case GST_MATROSKA_ID_CODECPRIVATE:{
870 gst_ebml_read_binary (ebml, &id, &data, &size)) != GST_FLOW_OK)
873 context->codec_priv = data;
874 context->codec_priv_size = size;
876 GST_DEBUG_OBJECT (demux, "CodecPrivate of size %" G_GUINT64_FORMAT,
881 /* name of the codec */
882 case GST_MATROSKA_ID_CODECNAME:{
885 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
888 GST_DEBUG_OBJECT (demux, "CodecName: %s", GST_STR_NULL (text));
889 context->codec_name = text;
893 /* name of this track */
894 case GST_MATROSKA_ID_TRACKNAME:{
897 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
900 context->name = text;
901 GST_DEBUG_OBJECT (demux, "TrackName: %s", GST_STR_NULL (text));
905 /* language (matters for audio/subtitles, mostly) */
906 case GST_MATROSKA_ID_TRACKLANGUAGE:{
909 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
913 context->language = text;
916 if (strlen (context->language) >= 4 && context->language[3] == '-')
917 context->language[3] = '\0';
919 GST_DEBUG_OBJECT (demux, "TrackLanguage: %s",
920 GST_STR_NULL (context->language));
924 /* whether this is actually used */
925 case GST_MATROSKA_ID_TRACKFLAGENABLED:{
928 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
932 context->flags |= GST_MATROSKA_TRACK_ENABLED;
934 context->flags &= ~GST_MATROSKA_TRACK_ENABLED;
936 GST_DEBUG_OBJECT (demux, "TrackEnabled: %d",
937 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
941 /* whether it's the default for this track type */
942 case GST_MATROSKA_ID_TRACKFLAGDEFAULT:{
945 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
949 context->flags |= GST_MATROSKA_TRACK_DEFAULT;
951 context->flags &= ~GST_MATROSKA_TRACK_DEFAULT;
953 GST_DEBUG_OBJECT (demux, "TrackDefault: %d",
954 (context->flags & GST_MATROSKA_TRACK_DEFAULT) ? 1 : 0);
958 /* whether the track must be used during playback */
959 case GST_MATROSKA_ID_TRACKFLAGFORCED:{
962 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
966 context->flags |= GST_MATROSKA_TRACK_FORCED;
968 context->flags &= ~GST_MATROSKA_TRACK_FORCED;
970 GST_DEBUG_OBJECT (demux, "TrackForced: %d",
971 (context->flags & GST_MATROSKA_TRACK_FORCED) ? 1 : 0);
975 /* lacing (like MPEG, where blocks don't end/start on frame
977 case GST_MATROSKA_ID_TRACKFLAGLACING:{
980 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
984 context->flags |= GST_MATROSKA_TRACK_LACING;
986 context->flags &= ~GST_MATROSKA_TRACK_LACING;
988 GST_DEBUG_OBJECT (demux, "TrackLacing: %d",
989 (context->flags & GST_MATROSKA_TRACK_LACING) ? 1 : 0);
993 /* default length (in time) of one data block in this track */
994 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
997 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1002 GST_WARNING_OBJECT (demux, "Invalid TrackDefaultDuration 0");
1006 GST_DEBUG_OBJECT (demux, "TrackDefaultDuration: %" G_GUINT64_FORMAT,
1008 context->default_duration = num;
1012 case GST_MATROSKA_ID_CONTENTENCODINGS:{
1013 ret = gst_matroska_read_common_read_track_encodings (&demux->common,
1018 case GST_MATROSKA_ID_TRACKTIMECODESCALE:{
1021 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
1025 GST_WARNING_OBJECT (demux, "Invalid TrackTimeCodeScale %lf", num);
1029 GST_DEBUG_OBJECT (demux, "TrackTimeCodeScale: %lf", num);
1030 context->timecodescale = num;
1035 GST_WARNING ("Unknown TrackEntry subelement 0x%x - ignoring", id);
1038 /* we ignore these because they're nothing useful (i.e. crap)
1039 * or simply not implemented yet. */
1040 case GST_MATROSKA_ID_TRACKMINCACHE:
1041 case GST_MATROSKA_ID_TRACKMAXCACHE:
1042 case GST_MATROSKA_ID_MAXBLOCKADDITIONID:
1043 case GST_MATROSKA_ID_TRACKATTACHMENTLINK:
1044 case GST_MATROSKA_ID_TRACKOVERLAY:
1045 case GST_MATROSKA_ID_TRACKTRANSLATE:
1046 case GST_MATROSKA_ID_TRACKOFFSET:
1047 case GST_MATROSKA_ID_CODECSETTINGS:
1048 case GST_MATROSKA_ID_CODECINFOURL:
1049 case GST_MATROSKA_ID_CODECDOWNLOADURL:
1050 case GST_MATROSKA_ID_CODECDECODEALL:
1051 ret = gst_ebml_read_skip (ebml);
1056 DEBUG_ELEMENT_STOP (demux, ebml, "TrackEntry", ret);
1058 /* Decode codec private data if necessary */
1059 if (context->encodings && context->encodings->len > 0 && context->codec_priv
1060 && context->codec_priv_size > 0) {
1061 if (!gst_matroska_decode_data (context->encodings,
1062 &context->codec_priv, &context->codec_priv_size,
1063 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
1064 GST_WARNING_OBJECT (demux, "Decoding codec private data failed");
1065 ret = GST_FLOW_ERROR;
1069 if (context->type == 0 || context->codec_id == NULL || (ret != GST_FLOW_OK
1070 && ret != GST_FLOW_EOS)) {
1071 if (ret == GST_FLOW_OK || ret == GST_FLOW_EOS)
1072 GST_WARNING_OBJECT (ebml, "Unknown stream/codec in track entry header");
1074 demux->common.num_streams--;
1075 g_ptr_array_remove_index (demux->common.src, demux->common.num_streams);
1076 g_assert (demux->common.src->len == demux->common.num_streams);
1078 gst_matroska_track_free (context);
1084 /* now create the GStreamer connectivity */
1085 switch (context->type) {
1086 case GST_MATROSKA_TRACK_TYPE_VIDEO:{
1087 GstMatroskaTrackVideoContext *videocontext =
1088 (GstMatroskaTrackVideoContext *) context;
1090 padname = g_strdup_printf ("video_%u", demux->num_v_streams++);
1091 templ = gst_element_class_get_pad_template (klass, "video_%u");
1092 caps = gst_matroska_demux_video_caps (videocontext,
1093 context->codec_id, context->codec_priv,
1094 context->codec_priv_size, &codec, &riff_fourcc);
1097 gst_tag_list_add (context->tags, GST_TAG_MERGE_REPLACE,
1098 GST_TAG_VIDEO_CODEC, codec, NULL);
1099 context->tags_changed = TRUE;
1105 case GST_MATROSKA_TRACK_TYPE_AUDIO:{
1106 GstMatroskaTrackAudioContext *audiocontext =
1107 (GstMatroskaTrackAudioContext *) context;
1109 padname = g_strdup_printf ("audio_%u", demux->num_a_streams++);
1110 templ = gst_element_class_get_pad_template (klass, "audio_%u");
1111 caps = gst_matroska_demux_audio_caps (audiocontext,
1112 context->codec_id, context->codec_priv, context->codec_priv_size,
1113 &codec, &riff_audio_fmt);
1116 gst_tag_list_add (context->tags, GST_TAG_MERGE_REPLACE,
1117 GST_TAG_AUDIO_CODEC, codec, NULL);
1118 context->tags_changed = TRUE;
1124 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:{
1125 GstMatroskaTrackSubtitleContext *subtitlecontext =
1126 (GstMatroskaTrackSubtitleContext *) context;
1128 padname = g_strdup_printf ("subtitle_%u", demux->num_t_streams++);
1129 templ = gst_element_class_get_pad_template (klass, "subtitle_%u");
1130 caps = gst_matroska_demux_subtitle_caps (subtitlecontext,
1131 context->codec_id, context->codec_priv, context->codec_priv_size);
1135 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1136 case GST_MATROSKA_TRACK_TYPE_LOGO:
1137 case GST_MATROSKA_TRACK_TYPE_BUTTONS:
1138 case GST_MATROSKA_TRACK_TYPE_CONTROL:
1140 /* we should already have quit by now */
1141 g_assert_not_reached ();
1144 if ((context->language == NULL || *context->language == '\0') &&
1145 (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO ||
1146 context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
1147 GST_LOG ("stream %d: language=eng (assuming default)", context->index);
1148 context->language = g_strdup ("eng");
1151 if (context->language) {
1154 /* Matroska contains ISO 639-2B codes, we want ISO 639-1 */
1155 lang = gst_tag_get_language_code (context->language);
1156 gst_tag_list_add (context->tags, GST_TAG_MERGE_REPLACE,
1157 GST_TAG_LANGUAGE_CODE, (lang) ? lang : context->language, NULL);
1158 context->tags_changed = TRUE;
1162 GST_WARNING_OBJECT (demux, "could not determine caps for stream with "
1163 "codec_id='%s'", context->codec_id);
1164 switch (context->type) {
1165 case GST_MATROSKA_TRACK_TYPE_VIDEO:
1166 caps = gst_caps_new_empty_simple ("video/x-unknown");
1168 case GST_MATROSKA_TRACK_TYPE_AUDIO:
1169 caps = gst_caps_new_empty_simple ("audio/x-unknown");
1171 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
1172 caps = gst_caps_new_empty_simple ("application/x-subtitle-unknown");
1174 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1176 caps = gst_caps_new_empty_simple ("application/x-matroska-unknown");
1179 gst_caps_set_simple (caps, "codec-id", G_TYPE_STRING, context->codec_id,
1182 /* add any unrecognised riff fourcc / audio format, but after codec-id */
1183 if (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO && riff_audio_fmt != 0)
1184 gst_caps_set_simple (caps, "format", G_TYPE_INT, riff_audio_fmt, NULL);
1185 else if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO && riff_fourcc != 0) {
1186 gchar *fstr = g_strdup_printf ("%" GST_FOURCC_FORMAT,
1187 GST_FOURCC_ARGS (riff_fourcc));
1188 gst_caps_set_simple (caps, "fourcc", G_TYPE_STRING, fstr, NULL);
1191 } else if (context->stream_headers != NULL) {
1192 gst_matroska_demux_add_stream_headers_to_caps (demux,
1193 context->stream_headers, caps);
1196 /* the pad in here */
1197 context->pad = gst_pad_new_from_template (templ, padname);
1198 context->caps = caps;
1200 gst_pad_set_event_function (context->pad,
1201 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_event));
1202 gst_pad_set_query_function (context->pad,
1203 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_query));
1205 GST_INFO_OBJECT (demux, "Adding pad '%s' with caps %" GST_PTR_FORMAT,
1208 gst_pad_set_element_private (context->pad, context);
1210 gst_pad_use_fixed_caps (context->pad);
1211 gst_pad_set_active (context->pad, TRUE);
1214 gst_pad_create_stream_id_printf (context->pad, GST_ELEMENT_CAST (demux),
1215 "%03" G_GUINT64_FORMAT, context->uid);
1217 gst_pad_get_sticky_event (demux->common.sinkpad, GST_EVENT_STREAM_START,
1220 if (gst_event_parse_group_id (stream_start, &demux->group_id))
1221 demux->have_group_id = TRUE;
1223 demux->have_group_id = FALSE;
1224 gst_event_unref (stream_start);
1225 } else if (!demux->have_group_id) {
1226 demux->have_group_id = TRUE;
1227 demux->group_id = gst_util_group_id_next ();
1230 stream_start = gst_event_new_stream_start (stream_id);
1232 if (demux->have_group_id)
1233 gst_event_set_group_id (stream_start, demux->group_id);
1234 stream_flags = GST_STREAM_FLAG_NONE;
1235 if (context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)
1236 stream_flags |= GST_STREAM_FLAG_SPARSE;
1237 if (context->flags & GST_MATROSKA_TRACK_DEFAULT)
1238 stream_flags |= GST_STREAM_FLAG_SELECT;
1239 gst_event_set_stream_flags (stream_start, stream_flags);
1240 gst_pad_push_event (context->pad, stream_start);
1241 gst_pad_set_caps (context->pad, context->caps);
1243 gst_element_add_pad (GST_ELEMENT (demux), context->pad);
1244 gst_flow_combiner_add_pad (demux->flowcombiner, context->pad);
1253 gst_matroska_demux_query (GstMatroskaDemux * demux, GstPad * pad,
1256 gboolean res = FALSE;
1257 GstMatroskaTrackContext *context = NULL;
1260 context = gst_pad_get_element_private (pad);
1263 switch (GST_QUERY_TYPE (query)) {
1264 case GST_QUERY_POSITION:
1268 gst_query_parse_position (query, &format, NULL);
1271 if (format == GST_FORMAT_TIME) {
1272 GST_OBJECT_LOCK (demux);
1274 gst_query_set_position (query, GST_FORMAT_TIME,
1275 MAX (context->pos, demux->stream_start_time) -
1276 demux->stream_start_time);
1278 gst_query_set_position (query, GST_FORMAT_TIME,
1279 MAX (demux->common.segment.position, demux->stream_start_time) -
1280 demux->stream_start_time);
1281 GST_OBJECT_UNLOCK (demux);
1282 } else if (format == GST_FORMAT_DEFAULT && context
1283 && context->default_duration) {
1284 GST_OBJECT_LOCK (demux);
1285 gst_query_set_position (query, GST_FORMAT_DEFAULT,
1286 context->pos / context->default_duration);
1287 GST_OBJECT_UNLOCK (demux);
1289 GST_DEBUG_OBJECT (demux,
1290 "only position query in TIME and DEFAULT format is supported");
1296 case GST_QUERY_DURATION:
1300 gst_query_parse_duration (query, &format, NULL);
1303 if (format == GST_FORMAT_TIME) {
1304 GST_OBJECT_LOCK (demux);
1305 gst_query_set_duration (query, GST_FORMAT_TIME,
1306 demux->common.segment.duration);
1307 GST_OBJECT_UNLOCK (demux);
1308 } else if (format == GST_FORMAT_DEFAULT && context
1309 && context->default_duration) {
1310 GST_OBJECT_LOCK (demux);
1311 gst_query_set_duration (query, GST_FORMAT_DEFAULT,
1312 demux->common.segment.duration / context->default_duration);
1313 GST_OBJECT_UNLOCK (demux);
1315 GST_DEBUG_OBJECT (demux,
1316 "only duration query in TIME and DEFAULT format is supported");
1322 case GST_QUERY_SEEKING:
1326 gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
1327 GST_OBJECT_LOCK (demux);
1328 if (fmt == GST_FORMAT_TIME) {
1331 if (demux->streaming) {
1332 /* assuming we'll be able to get an index ... */
1333 seekable = demux->seekable;
1338 gst_query_set_seeking (query, GST_FORMAT_TIME, seekable,
1339 0, demux->common.segment.duration);
1342 GST_OBJECT_UNLOCK (demux);
1345 case GST_QUERY_SEGMENT:
1350 format = demux->common.segment.format;
1353 gst_segment_to_stream_time (&demux->common.segment, format,
1354 demux->common.segment.start);
1355 if ((stop = demux->common.segment.stop) == -1)
1356 stop = demux->common.segment.duration;
1359 gst_segment_to_stream_time (&demux->common.segment, format, stop);
1361 gst_query_set_segment (query, demux->common.segment.rate, format, start,
1368 res = gst_pad_query_default (pad, (GstObject *) demux, query);
1371 GST_ELEMENT_CLASS (parent_class)->query (GST_ELEMENT_CAST (demux),
1380 gst_matroska_demux_element_query (GstElement * element, GstQuery * query)
1382 return gst_matroska_demux_query (GST_MATROSKA_DEMUX (element), NULL, query);
1386 gst_matroska_demux_handle_src_query (GstPad * pad, GstObject * parent,
1389 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
1391 return gst_matroska_demux_query (demux, pad, query);
1394 /* returns FALSE if there are no pads to deliver event to,
1395 * otherwise TRUE (whatever the outcome of event sending),
1396 * takes ownership of the passed event! */
1398 gst_matroska_demux_send_event (GstMatroskaDemux * demux, GstEvent * event)
1400 gboolean ret = FALSE;
1403 g_return_val_if_fail (event != NULL, FALSE);
1405 GST_DEBUG_OBJECT (demux, "Sending event of type %s to all source pads",
1406 GST_EVENT_TYPE_NAME (event));
1408 g_assert (demux->common.src->len == demux->common.num_streams);
1409 for (i = 0; i < demux->common.src->len; i++) {
1410 GstMatroskaTrackContext *stream;
1412 stream = g_ptr_array_index (demux->common.src, i);
1413 gst_event_ref (event);
1414 gst_pad_push_event (stream->pad, event);
1418 gst_event_unref (event);
1423 gst_matroska_demux_send_tags (GstMatroskaDemux * demux)
1427 if (G_UNLIKELY (demux->common.global_tags_changed)) {
1428 GstEvent *tag_event;
1429 gst_tag_list_add (demux->common.global_tags, GST_TAG_MERGE_REPLACE,
1430 GST_TAG_CONTAINER_FORMAT, "Matroska", NULL);
1431 GST_DEBUG_OBJECT (demux, "Sending global_tags %p : %" GST_PTR_FORMAT,
1432 demux->common.global_tags, demux->common.global_tags);
1435 gst_event_new_tag (gst_tag_list_copy (demux->common.global_tags));
1437 for (i = 0; i < demux->common.src->len; i++) {
1438 GstMatroskaTrackContext *stream;
1440 stream = g_ptr_array_index (demux->common.src, i);
1441 gst_pad_push_event (stream->pad, gst_event_ref (tag_event));
1444 gst_event_unref (tag_event);
1445 demux->common.global_tags_changed = FALSE;
1448 g_assert (demux->common.src->len == demux->common.num_streams);
1449 for (i = 0; i < demux->common.src->len; i++) {
1450 GstMatroskaTrackContext *stream;
1452 stream = g_ptr_array_index (demux->common.src, i);
1454 if (G_UNLIKELY (stream->tags_changed)) {
1455 GST_DEBUG_OBJECT (demux, "Sending tags %p for pad %s:%s : %"
1456 GST_PTR_FORMAT, stream->tags,
1457 GST_DEBUG_PAD_NAME (stream->pad), stream->tags);
1458 gst_pad_push_event (stream->pad,
1459 gst_event_new_tag (gst_tag_list_copy (stream->tags)));
1460 stream->tags_changed = FALSE;
1466 gst_matroska_demux_element_send_event (GstElement * element, GstEvent * event)
1468 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
1471 g_return_val_if_fail (event != NULL, FALSE);
1473 if (GST_EVENT_TYPE (event) == GST_EVENT_SEEK) {
1474 res = gst_matroska_demux_handle_seek_event (demux, NULL, event);
1476 GST_WARNING_OBJECT (demux, "Unhandled event of type %s",
1477 GST_EVENT_TYPE_NAME (event));
1480 gst_event_unref (event);
1485 gst_matroska_demux_move_to_entry (GstMatroskaDemux * demux,
1486 GstMatroskaIndex * entry, gboolean reset, gboolean update)
1490 GST_OBJECT_LOCK (demux);
1493 /* seek (relative to matroska segment) */
1494 /* position might be invalid; will error when streaming resumes ... */
1495 demux->common.offset = entry->pos + demux->common.ebml_segment_start;
1496 demux->next_cluster_offset = 0;
1498 GST_DEBUG_OBJECT (demux,
1499 "Seeked to offset %" G_GUINT64_FORMAT ", block %d, " "time %"
1500 GST_TIME_FORMAT, entry->pos + demux->common.ebml_segment_start,
1501 entry->block, GST_TIME_ARGS (entry->time));
1503 /* update the time */
1504 gst_matroska_read_common_reset_streams (&demux->common, entry->time, TRUE);
1505 gst_flow_combiner_reset (demux->flowcombiner);
1506 demux->common.segment.position = entry->time;
1507 demux->seek_block = entry->block;
1508 demux->seek_first = TRUE;
1509 demux->last_stop_end = GST_CLOCK_TIME_NONE;
1512 for (i = 0; i < demux->common.src->len; i++) {
1513 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
1516 stream->to_offset = G_MAXINT64;
1518 if (stream->from_offset != -1)
1519 stream->to_offset = stream->from_offset;
1521 stream->from_offset = -1;
1522 stream->from_time = GST_CLOCK_TIME_NONE;
1525 GST_OBJECT_UNLOCK (demux);
1531 gst_matroska_cluster_compare (gint64 * i1, gint64 * i2)
1541 /* searches for a cluster start from @pos,
1542 * return GST_FLOW_OK and cluster position in @pos if found */
1543 static GstFlowReturn
1544 gst_matroska_demux_search_cluster (GstMatroskaDemux * demux, gint64 * pos)
1546 gint64 newpos = *pos;
1548 GstFlowReturn ret = GST_FLOW_OK;
1549 const guint chunk = 64 * 1024;
1550 GstBuffer *buf = NULL;
1552 gpointer data = NULL;
1557 gint64 oldpos, oldlength;
1559 orig_offset = demux->common.offset;
1561 GST_LOG_OBJECT (demux, "searching cluster following offset %" G_GINT64_FORMAT,
1564 if (demux->clusters) {
1567 cpos = gst_util_array_binary_search (demux->clusters->data,
1568 demux->clusters->len, sizeof (gint64),
1569 (GCompareDataFunc) gst_matroska_cluster_compare,
1570 GST_SEARCH_MODE_AFTER, pos, NULL);
1573 GST_DEBUG_OBJECT (demux,
1574 "cluster reported at offset %" G_GINT64_FORMAT, *cpos);
1575 demux->common.offset = *cpos;
1576 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1577 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1578 if (ret == GST_FLOW_OK && id == GST_MATROSKA_ID_CLUSTER) {
1585 /* read in at newpos and scan for ebml cluster id */
1586 oldpos = oldlength = -1;
1588 GstByteReader reader;
1592 gst_buffer_unmap (buf, &map);
1593 gst_buffer_unref (buf);
1596 ret = gst_pad_pull_range (demux->common.sinkpad, newpos, chunk, &buf);
1597 if (ret != GST_FLOW_OK)
1599 GST_DEBUG_OBJECT (demux,
1600 "read buffer size %" G_GSIZE_FORMAT " at offset %" G_GINT64_FORMAT,
1601 gst_buffer_get_size (buf), newpos);
1602 gst_buffer_map (buf, &map, GST_MAP_READ);
1605 if (oldpos == newpos && oldlength == map.size) {
1606 GST_ERROR_OBJECT (demux, "Stuck at same position");
1607 ret = GST_FLOW_ERROR;
1611 oldlength = map.size;
1614 gst_byte_reader_init (&reader, data, size);
1616 cluster_pos = gst_byte_reader_masked_scan_uint32 (&reader, 0xffffffff,
1617 GST_MATROSKA_ID_CLUSTER, 0, gst_byte_reader_get_remaining (&reader));
1618 if (cluster_pos >= 0) {
1619 newpos += cluster_pos;
1620 /* prepare resuming at next byte */
1621 if (!gst_byte_reader_skip (&reader, cluster_pos + 1)) {
1622 GST_DEBUG_OBJECT (demux, "Need more data -> continue");
1625 GST_DEBUG_OBJECT (demux,
1626 "found cluster ebml id at offset %" G_GINT64_FORMAT, newpos);
1627 /* extra checks whether we really sync'ed to a cluster:
1628 * - either it is the first and only cluster
1629 * - either there is a cluster after this one
1630 * - either cluster length is undefined
1632 /* ok if first cluster (there may not a subsequent one) */
1633 if (newpos == demux->first_cluster_offset) {
1634 GST_DEBUG_OBJECT (demux, "cluster is first cluster -> OK");
1637 demux->common.offset = newpos;
1638 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1639 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1640 if (ret != GST_FLOW_OK) {
1641 GST_DEBUG_OBJECT (demux, "need more data -> continue");
1644 g_assert (id == GST_MATROSKA_ID_CLUSTER);
1645 GST_DEBUG_OBJECT (demux, "cluster size %" G_GUINT64_FORMAT ", prefix %d",
1647 /* ok if undefined length or first cluster */
1648 if (length == GST_EBML_SIZE_UNKNOWN || length == G_MAXUINT64) {
1649 GST_DEBUG_OBJECT (demux, "cluster has undefined length -> OK");
1653 demux->common.offset += length + needed;
1654 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1655 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1656 if (ret != GST_FLOW_OK)
1658 GST_DEBUG_OBJECT (demux, "next element is %scluster",
1659 id == GST_MATROSKA_ID_CLUSTER ? "" : "not ");
1660 if (id == GST_MATROSKA_ID_CLUSTER)
1662 /* not ok, resume */
1665 /* partial cluster id may have been in tail of buffer */
1666 newpos += MAX (gst_byte_reader_get_remaining (&reader), 4) - 3;
1671 gst_buffer_unmap (buf, &map);
1672 gst_buffer_unref (buf);
1677 demux->common.offset = orig_offset;
1682 /* bisect and scan through file for cluster starting before @time,
1683 * returns fake index entry with corresponding info on cluster */
1684 static GstMatroskaIndex *
1685 gst_matroska_demux_search_pos (GstMatroskaDemux * demux, GstClockTime time)
1687 GstMatroskaIndex *entry = NULL;
1688 GstMatroskaReadState current_state;
1689 GstClockTime otime, prev_cluster_time, current_cluster_time, cluster_time;
1690 gint64 opos, newpos, startpos = 0, current_offset;
1691 gint64 prev_cluster_offset = -1, current_cluster_offset, cluster_offset;
1692 const guint chunk = 64 * 1024;
1698 /* (under)estimate new position, resync using cluster ebml id,
1699 * and scan forward to appropriate cluster
1700 * (and re-estimate if need to go backward) */
1702 prev_cluster_time = GST_CLOCK_TIME_NONE;
1704 /* store some current state */
1705 current_state = demux->common.state;
1706 g_return_val_if_fail (current_state == GST_MATROSKA_READ_STATE_DATA, NULL);
1708 current_cluster_offset = demux->cluster_offset;
1709 current_cluster_time = demux->cluster_time;
1710 current_offset = demux->common.offset;
1712 demux->common.state = GST_MATROSKA_READ_STATE_SCANNING;
1714 /* estimate using start and current position */
1715 GST_OBJECT_LOCK (demux);
1716 opos = demux->common.offset - demux->common.ebml_segment_start;
1717 otime = demux->common.segment.position;
1718 GST_OBJECT_UNLOCK (demux);
1721 time = MAX (time, demux->stream_start_time);
1723 /* avoid division by zero in first estimation below */
1724 if (otime <= demux->stream_start_time)
1728 GST_LOG_OBJECT (demux,
1729 "opos: %" G_GUINT64_FORMAT ", otime: %" GST_TIME_FORMAT ", %"
1730 GST_TIME_FORMAT " in stream time (start %" GST_TIME_FORMAT "), time %"
1731 GST_TIME_FORMAT, opos, GST_TIME_ARGS (otime),
1732 GST_TIME_ARGS (otime - demux->stream_start_time),
1733 GST_TIME_ARGS (demux->stream_start_time), GST_TIME_ARGS (time));
1735 if (otime <= demux->stream_start_time) {
1739 gst_util_uint64_scale (opos - demux->common.ebml_segment_start,
1740 time - demux->stream_start_time,
1741 otime - demux->stream_start_time) - chunk;
1745 /* favour undershoot */
1746 newpos = newpos * 90 / 100;
1747 newpos += demux->common.ebml_segment_start;
1749 GST_DEBUG_OBJECT (demux,
1750 "estimated offset for %" GST_TIME_FORMAT ": %" G_GINT64_FORMAT,
1751 GST_TIME_ARGS (time), newpos);
1753 /* and at least start scanning before previous scan start to avoid looping */
1754 startpos = startpos * 90 / 100;
1755 if (startpos && startpos < newpos)
1758 /* read in at newpos and scan for ebml cluster id */
1762 ret = gst_matroska_demux_search_cluster (demux, &newpos);
1763 if (ret == GST_FLOW_EOS) {
1764 /* heuristic HACK */
1765 newpos = startpos * 80 / 100;
1766 GST_DEBUG_OBJECT (demux, "EOS; "
1767 "new estimated offset for %" GST_TIME_FORMAT ": %" G_GINT64_FORMAT,
1768 GST_TIME_ARGS (time), newpos);
1771 } else if (ret != GST_FLOW_OK) {
1778 /* then start scanning and parsing for cluster time,
1779 * re-estimate if overshoot, otherwise next cluster and so on */
1780 demux->common.offset = newpos;
1781 demux->cluster_time = cluster_time = GST_CLOCK_TIME_NONE;
1783 guint64 cluster_size = 0;
1785 /* peek and parse some elements */
1786 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1787 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1788 if (ret != GST_FLOW_OK)
1790 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
1791 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
1793 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
1794 if (ret != GST_FLOW_OK)
1797 if (id == GST_MATROSKA_ID_CLUSTER) {
1798 cluster_time = GST_CLOCK_TIME_NONE;
1799 if (length == G_MAXUINT64)
1802 cluster_size = length + needed;
1804 if (demux->cluster_time != GST_CLOCK_TIME_NONE &&
1805 cluster_time == GST_CLOCK_TIME_NONE) {
1806 cluster_time = demux->cluster_time * demux->common.time_scale;
1807 cluster_offset = demux->cluster_offset;
1808 GST_DEBUG_OBJECT (demux, "found cluster at offset %" G_GINT64_FORMAT
1809 " with time %" GST_TIME_FORMAT, cluster_offset,
1810 GST_TIME_ARGS (cluster_time));
1811 if (cluster_time > time) {
1812 GST_DEBUG_OBJECT (demux, "overshot target");
1813 /* cluster overshoots */
1814 if (cluster_offset == demux->first_cluster_offset) {
1815 /* but no prev one */
1816 GST_DEBUG_OBJECT (demux, "but using first cluster anyway");
1817 prev_cluster_time = cluster_time;
1818 prev_cluster_offset = cluster_offset;
1821 if (prev_cluster_time != GST_CLOCK_TIME_NONE) {
1822 /* prev cluster did not overshoot, so prev cluster is target */
1825 /* re-estimate using this new position info */
1826 opos = cluster_offset;
1827 otime = cluster_time;
1831 /* cluster undershoots, goto next one */
1832 prev_cluster_time = cluster_time;
1833 prev_cluster_offset = cluster_offset;
1834 /* skip cluster if length is defined,
1835 * otherwise will be skippingly parsed into */
1837 GST_DEBUG_OBJECT (demux, "skipping to next cluster");
1838 demux->common.offset = cluster_offset + cluster_size;
1839 demux->cluster_time = GST_CLOCK_TIME_NONE;
1841 GST_DEBUG_OBJECT (demux, "parsing/skipping cluster elements");
1848 if (ret == GST_FLOW_EOS) {
1849 if (prev_cluster_time != GST_CLOCK_TIME_NONE)
1855 entry = g_new0 (GstMatroskaIndex, 1);
1856 entry->time = prev_cluster_time;
1857 entry->pos = prev_cluster_offset - demux->common.ebml_segment_start;
1858 GST_DEBUG_OBJECT (demux, "simulated index entry; time %" GST_TIME_FORMAT
1859 ", pos %" G_GUINT64_FORMAT, GST_TIME_ARGS (entry->time), entry->pos);
1863 /* restore some state */
1864 demux->cluster_offset = current_cluster_offset;
1865 demux->cluster_time = current_cluster_time;
1866 demux->common.offset = current_offset;
1867 demux->common.state = current_state;
1873 gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
1874 GstPad * pad, GstEvent * event)
1876 GstMatroskaIndex *entry = NULL;
1877 GstMatroskaIndex scan_entry;
1879 GstSeekType cur_type, stop_type;
1881 gboolean flush, keyunit, before, after, snap_next;
1884 GstMatroskaTrackContext *track = NULL;
1885 GstSegment seeksegment = { 0, };
1886 gboolean update = TRUE;
1887 gboolean pad_locked = FALSE;
1889 GstSearchMode snap_dir;
1891 g_return_val_if_fail (event != NULL, FALSE);
1894 track = gst_pad_get_element_private (pad);
1896 GST_DEBUG_OBJECT (demux, "Have seek %" GST_PTR_FORMAT, event);
1898 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
1900 seqnum = gst_event_get_seqnum (event);
1902 /* we can only seek on time */
1903 if (format != GST_FORMAT_TIME) {
1904 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
1908 /* copy segment, we need this because we still need the old
1909 * segment when we close the current segment. */
1910 memcpy (&seeksegment, &demux->common.segment, sizeof (GstSegment));
1912 /* pull mode without index means that the actual duration is not known,
1913 * we might be playing a file that's still being recorded
1914 * so, invalidate our current duration, which is only a moving target,
1915 * and should not be used to clamp anything */
1916 if (!demux->streaming && !demux->common.index && demux->invalid_duration) {
1917 seeksegment.duration = GST_CLOCK_TIME_NONE;
1920 GST_DEBUG_OBJECT (demux, "configuring seek");
1921 /* Subtract stream_start_time so we always seek on a segment
1923 if (GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
1924 seeksegment.start -= demux->stream_start_time;
1925 seeksegment.position -= demux->stream_start_time;
1926 if (GST_CLOCK_TIME_IS_VALID (seeksegment.stop))
1927 seeksegment.stop -= demux->stream_start_time;
1929 seeksegment.stop = seeksegment.duration;
1932 gst_segment_do_seek (&seeksegment, rate, format, flags,
1933 cur_type, cur, stop_type, stop, &update);
1935 /* Restore the clip timestamp offset */
1936 if (GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
1937 seeksegment.position += demux->stream_start_time;
1938 seeksegment.start += demux->stream_start_time;
1939 if (!GST_CLOCK_TIME_IS_VALID (seeksegment.stop))
1940 seeksegment.stop = seeksegment.duration;
1941 if (GST_CLOCK_TIME_IS_VALID (seeksegment.stop))
1942 seeksegment.stop += demux->stream_start_time;
1945 /* restore segment duration (if any effect),
1946 * would be determined again when parsing, but anyway ... */
1947 seeksegment.duration = demux->common.segment.duration;
1949 flush = ! !(flags & GST_SEEK_FLAG_FLUSH);
1950 keyunit = ! !(flags & GST_SEEK_FLAG_KEY_UNIT);
1951 after = ! !(flags & GST_SEEK_FLAG_SNAP_AFTER);
1952 before = ! !(flags & GST_SEEK_FLAG_SNAP_BEFORE);
1954 /* always do full update if flushing,
1955 * otherwise problems might arise downstream with missing keyframes etc */
1956 update = update || flush;
1958 GST_DEBUG_OBJECT (demux, "New segment %" GST_SEGMENT_FORMAT, &seeksegment);
1960 /* check sanity before we start flushing and all that */
1961 snap_next = after && !before;
1962 if (seeksegment.rate < 0)
1963 snap_dir = snap_next ? GST_SEARCH_MODE_BEFORE : GST_SEARCH_MODE_AFTER;
1965 snap_dir = snap_next ? GST_SEARCH_MODE_AFTER : GST_SEARCH_MODE_BEFORE;
1967 GST_OBJECT_LOCK (demux);
1968 track = gst_matroska_read_common_get_seek_track (&demux->common, track);
1969 if ((entry = gst_matroska_read_common_do_index_seek (&demux->common, track,
1970 seeksegment.position, &demux->seek_index, &demux->seek_entry,
1971 snap_dir)) == NULL) {
1972 /* pull mode without index can scan later on */
1973 if (demux->streaming) {
1974 GST_DEBUG_OBJECT (demux, "No matching seek entry in index");
1975 GST_OBJECT_UNLOCK (demux);
1977 } else if (rate < 0.0) {
1978 /* FIXME: We should build an index during playback or when scanning
1979 * that can be used here. The reverse playback code requires seek_index
1980 * and seek_entry to be set!
1982 GST_DEBUG_OBJECT (demux,
1983 "No matching seek entry in index, needed for reverse playback");
1984 GST_OBJECT_UNLOCK (demux);
1988 GST_DEBUG_OBJECT (demux, "Seek position looks sane");
1989 GST_OBJECT_UNLOCK (demux);
1992 /* only have to update some segment,
1993 * but also still have to honour flush and so on */
1994 GST_DEBUG_OBJECT (demux, "... no update");
1995 /* bad goto, bad ... */
1999 if (demux->streaming)
2004 GstEvent *flush_event = gst_event_new_flush_start ();
2005 gst_event_set_seqnum (flush_event, seqnum);
2006 GST_DEBUG_OBJECT (demux, "Starting flush");
2007 gst_pad_push_event (demux->common.sinkpad, gst_event_ref (flush_event));
2008 gst_matroska_demux_send_event (demux, flush_event);
2010 GST_DEBUG_OBJECT (demux, "Non-flushing seek, pausing task");
2011 gst_pad_pause_task (demux->common.sinkpad);
2015 GST_PAD_STREAM_LOCK (demux->common.sinkpad);
2020 /* now grab the stream lock so that streaming cannot continue, for
2021 * non flushing seeks when the element is in PAUSED this could block
2023 GST_DEBUG_OBJECT (demux, "Waiting for streaming to stop");
2024 GST_PAD_STREAM_LOCK (demux->common.sinkpad);
2027 /* pull mode without index can do some scanning */
2028 if (!demux->streaming && !entry) {
2029 GstEvent *flush_event;
2031 /* need to stop flushing upstream as we need it next */
2033 flush_event = gst_event_new_flush_stop (TRUE);
2034 gst_event_set_seqnum (flush_event, seqnum);
2035 gst_pad_push_event (demux->common.sinkpad, flush_event);
2037 entry = gst_matroska_demux_search_pos (demux, seeksegment.position);
2038 /* keep local copy */
2040 scan_entry = *entry;
2042 entry = &scan_entry;
2044 GST_DEBUG_OBJECT (demux, "Scan failed to find matching position");
2046 flush_event = gst_event_new_flush_stop (TRUE);
2047 gst_event_set_seqnum (flush_event, seqnum);
2048 gst_matroska_demux_send_event (demux, flush_event);
2056 GST_DEBUG_OBJECT (demux, "seek to key unit, adjusting segment start from %"
2057 GST_TIME_FORMAT " to %" GST_TIME_FORMAT,
2058 GST_TIME_ARGS (seeksegment.start), GST_TIME_ARGS (entry->time));
2059 seeksegment.start = MAX (entry->time, demux->stream_start_time);
2060 seeksegment.position = seeksegment.start;
2061 seeksegment.time = seeksegment.start - demux->stream_start_time;
2064 if (demux->streaming) {
2065 GST_OBJECT_LOCK (demux);
2066 /* track real position we should start at */
2067 GST_DEBUG_OBJECT (demux, "storing segment start");
2068 demux->requested_seek_time = seeksegment.position;
2069 demux->seek_offset = entry->pos + demux->common.ebml_segment_start;
2070 GST_OBJECT_UNLOCK (demux);
2071 /* need to seek to cluster start to pick up cluster time */
2072 /* upstream takes care of flushing and all that
2073 * ... and newsegment event handling takes care of the rest */
2074 return perform_seek_to_offset (demux, rate,
2075 entry->pos + demux->common.ebml_segment_start, seqnum);
2080 GstEvent *flush_event = gst_event_new_flush_stop (TRUE);
2081 gst_event_set_seqnum (flush_event, seqnum);
2082 GST_DEBUG_OBJECT (demux, "Stopping flush");
2083 gst_pad_push_event (demux->common.sinkpad, gst_event_ref (flush_event));
2084 gst_matroska_demux_send_event (demux, flush_event);
2087 GST_OBJECT_LOCK (demux);
2088 /* now update the real segment info */
2089 GST_DEBUG_OBJECT (demux, "Committing new seek segment");
2090 memcpy (&demux->common.segment, &seeksegment, sizeof (GstSegment));
2091 GST_OBJECT_UNLOCK (demux);
2093 /* update some (segment) state */
2094 if (!gst_matroska_demux_move_to_entry (demux, entry, TRUE, update))
2097 /* notify start of new segment */
2098 if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
2101 msg = gst_message_new_segment_start (GST_OBJECT (demux),
2102 GST_FORMAT_TIME, demux->common.segment.start);
2103 gst_message_set_seqnum (msg, seqnum);
2104 gst_element_post_message (GST_ELEMENT (demux), msg);
2107 GST_OBJECT_LOCK (demux);
2108 if (demux->new_segment)
2109 gst_event_unref (demux->new_segment);
2111 /* On port from 0.10, discarded !update (for segment.update) here, FIXME? */
2112 demux->new_segment = gst_event_new_segment (&demux->common.segment);
2113 gst_event_set_seqnum (demux->new_segment, seqnum);
2114 if (demux->common.segment.rate < 0 && demux->common.segment.stop == -1)
2115 demux->to_time = demux->common.segment.position;
2117 demux->to_time = GST_CLOCK_TIME_NONE;
2118 GST_OBJECT_UNLOCK (demux);
2120 /* restart our task since it might have been stopped when we did the
2122 gst_pad_start_task (demux->common.sinkpad,
2123 (GstTaskFunction) gst_matroska_demux_loop, demux->common.sinkpad, NULL);
2125 /* streaming can continue now */
2127 GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
2135 GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
2137 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Got a seek error"));
2143 * Handle whether we can perform the seek event or if we have to let the chain
2144 * function handle seeks to build the seek indexes first.
2147 gst_matroska_demux_handle_seek_push (GstMatroskaDemux * demux, GstPad * pad,
2151 GstSeekType cur_type, stop_type;
2156 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
2161 /* we can only seek on time */
2162 if (format != GST_FORMAT_TIME) {
2163 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
2167 if (stop_type != GST_SEEK_TYPE_NONE && stop != GST_CLOCK_TIME_NONE) {
2168 GST_DEBUG_OBJECT (demux, "Seek end-time not supported in streaming mode");
2172 if (!(flags & GST_SEEK_FLAG_FLUSH)) {
2173 GST_DEBUG_OBJECT (demux,
2174 "Non-flushing seek not supported in streaming mode");
2178 if (flags & GST_SEEK_FLAG_SEGMENT) {
2179 GST_DEBUG_OBJECT (demux, "Segment seek not supported in streaming mode");
2183 /* check for having parsed index already */
2184 if (!demux->common.index_parsed) {
2185 gboolean building_index;
2188 if (!demux->index_offset) {
2189 GST_DEBUG_OBJECT (demux, "no index (location); no seek in push mode");
2193 GST_OBJECT_LOCK (demux);
2194 /* handle the seek event in the chain function */
2195 demux->common.state = GST_MATROSKA_READ_STATE_SEEK;
2196 /* no more seek can be issued until state reset to _DATA */
2198 /* copy the event */
2199 if (demux->seek_event)
2200 gst_event_unref (demux->seek_event);
2201 demux->seek_event = gst_event_ref (event);
2203 /* set the building_index flag so that only one thread can setup the
2204 * structures for index seeking. */
2205 building_index = demux->building_index;
2206 if (!building_index) {
2207 demux->building_index = TRUE;
2208 offset = demux->index_offset;
2210 GST_OBJECT_UNLOCK (demux);
2212 if (!building_index) {
2213 /* seek to the first subindex or legacy index */
2214 GST_INFO_OBJECT (demux, "Seeking to Cues at %" G_GUINT64_FORMAT, offset);
2215 return perform_seek_to_offset (demux, rate, offset,
2216 gst_event_get_seqnum (event));
2219 /* well, we are handling it already */
2223 /* delegate to tweaked regular seek */
2224 return gst_matroska_demux_handle_seek_event (demux, pad, event);
2228 gst_matroska_demux_handle_src_event (GstPad * pad, GstObject * parent,
2231 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
2232 gboolean res = TRUE;
2234 switch (GST_EVENT_TYPE (event)) {
2235 case GST_EVENT_SEEK:
2236 /* no seeking until we are (safely) ready */
2237 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
2238 GST_DEBUG_OBJECT (demux, "not ready for seeking yet");
2241 if (!demux->streaming)
2242 res = gst_matroska_demux_handle_seek_event (demux, pad, event);
2244 res = gst_matroska_demux_handle_seek_push (demux, pad, event);
2245 gst_event_unref (event);
2250 GstMatroskaTrackContext *context = gst_pad_get_element_private (pad);
2251 if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
2252 GstMatroskaTrackVideoContext *videocontext =
2253 (GstMatroskaTrackVideoContext *) context;
2255 GstClockTimeDiff diff;
2256 GstClockTime timestamp;
2258 gst_event_parse_qos (event, NULL, &proportion, &diff, ×tamp);
2260 GST_OBJECT_LOCK (demux);
2261 videocontext->earliest_time = timestamp + diff;
2262 GST_OBJECT_UNLOCK (demux);
2265 gst_event_unref (event);
2269 case GST_EVENT_TOC_SELECT:
2272 GstTocEntry *entry = NULL;
2273 GstEvent *seek_event;
2276 if (!demux->common.toc) {
2277 GST_DEBUG_OBJECT (demux, "no TOC to select");
2280 gst_event_parse_toc_select (event, &uid);
2282 GST_OBJECT_LOCK (demux);
2283 entry = gst_toc_find_entry (demux->common.toc, uid);
2284 if (entry == NULL) {
2285 GST_OBJECT_UNLOCK (demux);
2286 GST_WARNING_OBJECT (demux, "no TOC entry with given UID: %s", uid);
2289 gst_toc_entry_get_start_stop_times (entry, &start_pos, NULL);
2290 GST_OBJECT_UNLOCK (demux);
2291 seek_event = gst_event_new_seek (1.0,
2293 GST_SEEK_FLAG_FLUSH,
2294 GST_SEEK_TYPE_SET, start_pos, GST_SEEK_TYPE_SET, -1);
2295 res = gst_matroska_demux_handle_seek_event (demux, pad, seek_event);
2296 gst_event_unref (seek_event);
2300 GST_WARNING_OBJECT (demux, "received empty TOC select event");
2304 gst_event_unref (event);
2308 /* events we don't need to handle */
2309 case GST_EVENT_NAVIGATION:
2310 gst_event_unref (event);
2314 case GST_EVENT_LATENCY:
2316 res = gst_pad_push_event (demux->common.sinkpad, event);
2323 static GstFlowReturn
2324 gst_matroska_demux_seek_to_previous_keyframe (GstMatroskaDemux * demux)
2326 GstFlowReturn ret = GST_FLOW_EOS;
2327 gboolean done = TRUE;
2330 g_return_val_if_fail (demux->seek_index, GST_FLOW_EOS);
2331 g_return_val_if_fail (demux->seek_entry < demux->seek_index->len,
2334 GST_DEBUG_OBJECT (demux, "locating previous keyframe");
2336 if (!demux->seek_entry) {
2337 GST_DEBUG_OBJECT (demux, "no earlier index entry");
2341 for (i = 0; i < demux->common.src->len; i++) {
2342 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
2344 GST_DEBUG_OBJECT (demux, "segment start %" GST_TIME_FORMAT
2345 ", stream %d at %" GST_TIME_FORMAT,
2346 GST_TIME_ARGS (demux->common.segment.start), stream->index,
2347 GST_TIME_ARGS (stream->from_time));
2348 if (GST_CLOCK_TIME_IS_VALID (stream->from_time)) {
2349 if (stream->from_time > demux->common.segment.start) {
2350 GST_DEBUG_OBJECT (demux, "stream %d not finished yet", stream->index);
2354 /* nothing pushed for this stream;
2355 * likely seek entry did not start at keyframe, so all was skipped.
2356 * So we need an earlier entry */
2362 GstMatroskaIndex *entry;
2364 entry = &g_array_index (demux->seek_index, GstMatroskaIndex,
2365 --demux->seek_entry);
2366 if (!gst_matroska_demux_move_to_entry (demux, entry, FALSE, TRUE))
2376 static GstFlowReturn
2377 gst_matroska_demux_parse_tracks (GstMatroskaDemux * demux, GstEbmlRead * ebml)
2379 GstFlowReturn ret = GST_FLOW_OK;
2382 DEBUG_ELEMENT_START (demux, ebml, "Tracks");
2384 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2385 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
2389 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
2390 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
2394 /* one track within the "all-tracks" header */
2395 case GST_MATROSKA_ID_TRACKENTRY:
2396 ret = gst_matroska_demux_add_stream (demux, ebml);
2400 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
2405 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
2407 demux->tracks_parsed = TRUE;
2413 * Read signed/unsigned "EBML" numbers.
2414 * Return: number of bytes processed.
2418 gst_matroska_ebmlnum_uint (guint8 * data, guint size, guint64 * num)
2420 gint len_mask = 0x80, read = 1, n = 1, num_ffs = 0;
2428 while (read <= 8 && !(total & len_mask)) {
2435 if ((total &= (len_mask - 1)) == len_mask - 1)
2440 if (data[n] == 0xff)
2442 total = (total << 8) | data[n];
2446 if (read == num_ffs && total != 0)
2455 gst_matroska_ebmlnum_sint (guint8 * data, guint size, gint64 * num)
2460 /* read as unsigned number first */
2461 if ((res = gst_matroska_ebmlnum_uint (data, size, &unum)) < 0)
2465 if (unum == G_MAXUINT64)
2468 *num = unum - ((1 << ((7 * res) - 1)) - 1);
2474 * Mostly used for subtitles. We add void filler data for each
2475 * lagging stream to make sure we don't deadlock.
2479 gst_matroska_demux_sync_streams (GstMatroskaDemux * demux)
2483 GST_OBJECT_LOCK (demux);
2485 GST_LOG_OBJECT (demux, "Sync to %" GST_TIME_FORMAT,
2486 GST_TIME_ARGS (demux->common.segment.position));
2488 g_assert (demux->common.num_streams == demux->common.src->len);
2489 for (stream_nr = 0; stream_nr < demux->common.src->len; stream_nr++) {
2490 GstMatroskaTrackContext *context;
2492 context = g_ptr_array_index (demux->common.src, stream_nr);
2494 GST_LOG_OBJECT (demux,
2495 "Checking for resync on stream %d (%" GST_TIME_FORMAT ")", stream_nr,
2496 GST_TIME_ARGS (context->pos));
2498 if (G_LIKELY (context->type != GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
2499 GST_LOG_OBJECT (demux, "Skipping sync on non-subtitle stream");
2503 /* does it lag? 0.5 seconds is a random threshold...
2504 * lag need only be considered if we have advanced into requested segment */
2505 if (GST_CLOCK_TIME_IS_VALID (context->pos) &&
2506 GST_CLOCK_TIME_IS_VALID (demux->common.segment.position) &&
2507 demux->common.segment.position > demux->common.segment.start &&
2508 context->pos + (GST_SECOND / 2) < demux->common.segment.position) {
2511 guint64 start = context->pos;
2512 guint64 stop = demux->common.segment.position - (GST_SECOND / 2);
2514 GST_DEBUG_OBJECT (demux,
2515 "Synchronizing stream %d with other by advancing time from %"
2516 GST_TIME_FORMAT " to %" GST_TIME_FORMAT, stream_nr,
2517 GST_TIME_ARGS (start), GST_TIME_ARGS (stop));
2519 context->pos = stop;
2521 event = gst_event_new_gap (start, stop - start);
2522 GST_OBJECT_UNLOCK (demux);
2523 gst_pad_push_event (context->pad, event);
2524 GST_OBJECT_LOCK (demux);
2528 GST_OBJECT_UNLOCK (demux);
2531 static GstFlowReturn
2532 gst_matroska_demux_push_stream_headers (GstMatroskaDemux * demux,
2533 GstMatroskaTrackContext * stream)
2535 GstFlowReturn ret = GST_FLOW_OK;
2538 num = gst_buffer_list_length (stream->stream_headers);
2539 for (i = 0; i < num; ++i) {
2542 buf = gst_buffer_list_get (stream->stream_headers, i);
2543 buf = gst_buffer_copy (buf);
2545 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
2547 if (stream->set_discont) {
2548 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
2549 stream->set_discont = FALSE;
2551 GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DISCONT);
2554 /* push out all headers in one go and use last flow return */
2555 ret = gst_pad_push (stream->pad, buf);
2558 /* don't need these any longer */
2559 gst_buffer_list_unref (stream->stream_headers);
2560 stream->stream_headers = NULL;
2563 ret = gst_flow_combiner_update_flow (demux->flowcombiner, ret);
2569 gst_matroska_demux_push_dvd_clut_change_event (GstMatroskaDemux * demux,
2570 GstMatroskaTrackContext * stream)
2574 g_assert (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB));
2576 if (!stream->codec_priv)
2579 /* ideally, VobSub private data should be parsed and stored more convenient
2580 * elsewhere, but for now, only interested in a small part */
2582 /* make sure we have terminating 0 */
2583 buf = g_strndup (stream->codec_priv, stream->codec_priv_size);
2585 /* just locate and parse palette part */
2586 start = strstr (buf, "palette:");
2591 guint8 r, g, b, y, u, v;
2594 while (g_ascii_isspace (*start))
2596 for (i = 0; i < 16; i++) {
2597 if (sscanf (start, "%06x", &col) != 1)
2600 while ((*start == ',') || g_ascii_isspace (*start))
2602 /* sigh, need to convert this from vobsub pseudo-RGB to YUV */
2603 r = (col >> 16) & 0xff;
2604 g = (col >> 8) & 0xff;
2606 y = CLAMP ((0.1494 * r + 0.6061 * g + 0.2445 * b) * 219 / 255 + 16, 0,
2608 u = CLAMP (0.6066 * r - 0.4322 * g - 0.1744 * b + 128, 0, 255);
2609 v = CLAMP (-0.08435 * r - 0.3422 * g + 0.4266 * b + 128, 0, 255);
2610 clut[i] = (y << 16) | (u << 8) | v;
2613 /* got them all without problems; build and send event */
2617 s = gst_structure_new ("application/x-gst-dvd", "event", G_TYPE_STRING,
2618 "dvd-spu-clut-change", "clut00", G_TYPE_INT, clut[0], "clut01",
2619 G_TYPE_INT, clut[1], "clut02", G_TYPE_INT, clut[2], "clut03",
2620 G_TYPE_INT, clut[3], "clut04", G_TYPE_INT, clut[4], "clut05",
2621 G_TYPE_INT, clut[5], "clut06", G_TYPE_INT, clut[6], "clut07",
2622 G_TYPE_INT, clut[7], "clut08", G_TYPE_INT, clut[8], "clut09",
2623 G_TYPE_INT, clut[9], "clut10", G_TYPE_INT, clut[10], "clut11",
2624 G_TYPE_INT, clut[11], "clut12", G_TYPE_INT, clut[12], "clut13",
2625 G_TYPE_INT, clut[13], "clut14", G_TYPE_INT, clut[14], "clut15",
2626 G_TYPE_INT, clut[15], NULL);
2628 gst_pad_push_event (stream->pad,
2629 gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM_STICKY, s));
2636 gst_matroska_demux_push_codec_data_all (GstMatroskaDemux * demux)
2640 GST_OBJECT_LOCK (demux);
2642 g_assert (demux->common.num_streams == demux->common.src->len);
2643 for (stream_nr = 0; stream_nr < demux->common.src->len; stream_nr++) {
2644 GstMatroskaTrackContext *stream;
2646 stream = g_ptr_array_index (demux->common.src, stream_nr);
2648 if (stream->send_stream_headers) {
2649 if (stream->stream_headers != NULL) {
2650 gst_matroska_demux_push_stream_headers (demux, stream);
2652 /* FIXME: perhaps we can just disable and skip this stream then */
2653 GST_ELEMENT_ERROR (demux, STREAM, DECODE, (NULL),
2654 ("Failed to extract stream headers from codec private data"));
2656 stream->send_stream_headers = FALSE;
2659 if (stream->send_dvd_event) {
2660 gst_matroska_demux_push_dvd_clut_change_event (demux, stream);
2661 /* FIXME: should we send this event again after (flushing) seek ? */
2662 stream->send_dvd_event = FALSE;
2666 GST_OBJECT_UNLOCK (demux);
2669 static GstFlowReturn
2670 gst_matroska_demux_add_mpeg_seq_header (GstElement * element,
2671 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2674 guint seq_header_len;
2675 guint32 header, tmp;
2677 if (stream->codec_state) {
2678 seq_header = stream->codec_state;
2679 seq_header_len = stream->codec_state_size;
2680 } else if (stream->codec_priv) {
2681 seq_header = stream->codec_priv;
2682 seq_header_len = stream->codec_priv_size;
2687 /* Sequence header only needed for keyframes */
2688 if (GST_BUFFER_FLAG_IS_SET (*buf, GST_BUFFER_FLAG_DELTA_UNIT))
2691 if (gst_buffer_get_size (*buf) < 4)
2694 gst_buffer_extract (*buf, 0, &tmp, sizeof (guint32));
2695 header = GUINT32_FROM_BE (tmp);
2697 /* Sequence start code, if not found prepend */
2698 if (header != 0x000001b3) {
2701 GST_DEBUG_OBJECT (element, "Prepending MPEG sequence header");
2703 newbuf = gst_buffer_new_wrapped (g_memdup (seq_header, seq_header_len),
2706 gst_buffer_copy_into (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
2707 GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_MEMORY, 0,
2708 gst_buffer_get_size (*buf));
2710 gst_buffer_unref (*buf);
2717 static GstFlowReturn
2718 gst_matroska_demux_add_wvpk_header (GstElement * element,
2719 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2721 GstMatroskaTrackAudioContext *audiocontext =
2722 (GstMatroskaTrackAudioContext *) stream;
2723 GstBuffer *newbuf = NULL;
2724 GstMapInfo map, outmap;
2725 guint8 *buf_data, *data;
2733 wvh.version = GST_READ_UINT16_LE (stream->codec_priv);
2736 wvh.total_samples = -1;
2737 wvh.block_index = audiocontext->wvpk_block_index;
2739 if (audiocontext->channels <= 2) {
2740 guint32 block_samples, tmp;
2741 gsize size = gst_buffer_get_size (*buf);
2743 gst_buffer_extract (*buf, 0, &tmp, sizeof (guint32));
2744 block_samples = GUINT32_FROM_LE (tmp);
2745 /* we need to reconstruct the header of the wavpack block */
2747 /* -20 because ck_size is the size of the wavpack block -8
2748 * and lace_size is the size of the wavpack block + 12
2749 * (the three guint32 of the header that already are in the buffer) */
2750 wvh.ck_size = size + sizeof (Wavpack4Header) - 20;
2752 /* block_samples, flags and crc are already in the buffer */
2753 newbuf = gst_buffer_new_allocate (NULL, sizeof (Wavpack4Header) - 12, NULL);
2755 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2761 GST_WRITE_UINT32_LE (data + 4, wvh.ck_size);
2762 GST_WRITE_UINT16_LE (data + 8, wvh.version);
2763 GST_WRITE_UINT8 (data + 10, wvh.track_no);
2764 GST_WRITE_UINT8 (data + 11, wvh.index_no);
2765 GST_WRITE_UINT32_LE (data + 12, wvh.total_samples);
2766 GST_WRITE_UINT32_LE (data + 16, wvh.block_index);
2768 /* Append data from buf: */
2769 gst_buffer_copy_into (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
2770 GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_MEMORY, 0, size);
2772 gst_buffer_unref (*buf);
2774 audiocontext->wvpk_block_index += block_samples;
2776 guint8 *outdata = NULL;
2778 gsize buf_size, size, out_size = 0;
2779 guint32 block_samples, flags, crc, blocksize;
2781 gst_buffer_map (*buf, &map, GST_MAP_READ);
2782 buf_data = map.data;
2783 buf_size = map.size;
2786 GST_ERROR_OBJECT (element, "Too small wavpack buffer");
2787 gst_buffer_unmap (*buf, &map);
2788 return GST_FLOW_ERROR;
2794 block_samples = GST_READ_UINT32_LE (data);
2799 flags = GST_READ_UINT32_LE (data);
2802 crc = GST_READ_UINT32_LE (data);
2805 blocksize = GST_READ_UINT32_LE (data);
2809 if (blocksize == 0 || size < blocksize)
2812 g_assert ((newbuf == NULL) == (outdata == NULL));
2814 if (newbuf == NULL) {
2815 out_size = sizeof (Wavpack4Header) + blocksize;
2816 newbuf = gst_buffer_new_allocate (NULL, out_size, NULL);
2818 gst_buffer_copy_into (newbuf, *buf,
2819 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS, 0, -1);
2822 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2823 outdata = outmap.data;
2825 gst_buffer_unmap (newbuf, &outmap);
2826 out_size += sizeof (Wavpack4Header) + blocksize;
2827 gst_buffer_set_size (newbuf, out_size);
2828 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2829 outdata = outmap.data;
2832 outdata[outpos] = 'w';
2833 outdata[outpos + 1] = 'v';
2834 outdata[outpos + 2] = 'p';
2835 outdata[outpos + 3] = 'k';
2838 GST_WRITE_UINT32_LE (outdata + outpos,
2839 blocksize + sizeof (Wavpack4Header) - 8);
2840 GST_WRITE_UINT16_LE (outdata + outpos + 4, wvh.version);
2841 GST_WRITE_UINT8 (outdata + outpos + 6, wvh.track_no);
2842 GST_WRITE_UINT8 (outdata + outpos + 7, wvh.index_no);
2843 GST_WRITE_UINT32_LE (outdata + outpos + 8, wvh.total_samples);
2844 GST_WRITE_UINT32_LE (outdata + outpos + 12, wvh.block_index);
2845 GST_WRITE_UINT32_LE (outdata + outpos + 16, block_samples);
2846 GST_WRITE_UINT32_LE (outdata + outpos + 20, flags);
2847 GST_WRITE_UINT32_LE (outdata + outpos + 24, crc);
2850 memmove (outdata + outpos, data, blocksize);
2851 outpos += blocksize;
2855 gst_buffer_unmap (*buf, &map);
2856 gst_buffer_unref (*buf);
2859 gst_buffer_unmap (newbuf, &outmap);
2862 audiocontext->wvpk_block_index += block_samples;
2868 /* @text must be null-terminated */
2870 gst_matroska_demux_subtitle_chunk_has_tag (GstElement * element,
2875 g_return_val_if_fail (text != NULL, FALSE);
2877 /* yes, this might all lead to false positives ... */
2878 tag = (gchar *) text;
2879 while ((tag = strchr (tag, '<'))) {
2881 if (*tag != '\0' && *(tag + 1) == '>') {
2882 /* some common convenience ones */
2883 /* maybe any character will do here ? */
2896 if (strstr (text, "<span"))
2902 static GstFlowReturn
2903 gst_matroska_demux_check_subtitle_buffer (GstElement * element,
2904 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2906 GstMatroskaTrackSubtitleContext *sub_stream;
2907 const gchar *encoding;
2912 gboolean needs_unmap = TRUE;
2914 sub_stream = (GstMatroskaTrackSubtitleContext *) stream;
2916 if (!gst_buffer_get_size (*buf) || !gst_buffer_map (*buf, &map, GST_MAP_READ))
2919 /* Need \0-terminator at the end */
2920 if (map.data[map.size - 1] != '\0') {
2921 newbuf = gst_buffer_new_and_alloc (map.size + 1);
2923 /* Copy old buffer and add a 0 at the end */
2924 gst_buffer_fill (newbuf, 0, map.data, map.size);
2925 gst_buffer_memset (newbuf, map.size, 0, 1);
2926 gst_buffer_unmap (*buf, &map);
2928 gst_buffer_copy_into (newbuf, *buf,
2929 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS |
2930 GST_BUFFER_COPY_META, 0, -1);
2931 gst_buffer_unref (*buf);
2933 gst_buffer_map (*buf, &map, GST_MAP_READ);
2936 if (!sub_stream->invalid_utf8) {
2937 if (g_utf8_validate ((gchar *) map.data, map.size - 1, NULL)) {
2940 GST_WARNING_OBJECT (element, "subtitle stream %" G_GUINT64_FORMAT
2941 " is not valid UTF-8, this is broken according to the matroska"
2942 " specification", stream->num);
2943 sub_stream->invalid_utf8 = TRUE;
2946 /* file with broken non-UTF8 subtitle, do the best we can do to fix it */
2947 encoding = g_getenv ("GST_SUBTITLE_ENCODING");
2948 if (encoding == NULL || *encoding == '\0') {
2949 /* if local encoding is UTF-8 and no encoding specified
2950 * via the environment variable, assume ISO-8859-15 */
2951 if (g_get_charset (&encoding)) {
2952 encoding = "ISO-8859-15";
2957 g_convert_with_fallback ((gchar *) map.data, map.size, "UTF-8", encoding,
2958 (char *) "*", NULL, NULL, &err);
2961 GST_LOG_OBJECT (element, "could not convert string from '%s' to UTF-8: %s",
2962 encoding, err->message);
2966 /* invalid input encoding, fall back to ISO-8859-15 (always succeeds) */
2967 encoding = "ISO-8859-15";
2969 g_convert_with_fallback ((gchar *) map.data, map.size, "UTF-8",
2970 encoding, (char *) "*", NULL, NULL, NULL);
2973 GST_LOG_OBJECT (element, "converted subtitle text from %s to UTF-8 %s",
2974 encoding, (err) ? "(using ISO-8859-15 as fallback)" : "");
2977 utf8 = g_strdup ("invalid subtitle");
2979 newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
2980 gst_buffer_unmap (*buf, &map);
2981 gst_buffer_copy_into (newbuf, *buf,
2982 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_META,
2984 gst_buffer_unref (*buf);
2987 gst_buffer_map (*buf, &map, GST_MAP_READ);
2991 if (sub_stream->check_markup) {
2992 /* caps claim markup text, so we need to escape text,
2993 * except if text is already markup and then needs no further escaping */
2994 sub_stream->seen_markup_tag = sub_stream->seen_markup_tag ||
2995 gst_matroska_demux_subtitle_chunk_has_tag (element, (gchar *) map.data);
2997 if (!sub_stream->seen_markup_tag) {
2998 utf8 = g_markup_escape_text ((gchar *) map.data, map.size);
3000 newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
3001 gst_buffer_unmap (*buf, &map);
3002 gst_buffer_copy_into (newbuf, *buf,
3003 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS |
3004 GST_BUFFER_COPY_META, 0, -1);
3005 gst_buffer_unref (*buf);
3008 needs_unmap = FALSE;
3013 gst_buffer_unmap (*buf, &map);
3018 static GstFlowReturn
3019 gst_matroska_demux_check_aac (GstElement * element,
3020 GstMatroskaTrackContext * stream, GstBuffer ** buf)
3025 gst_buffer_extract (*buf, 0, data, 2);
3026 size = gst_buffer_get_size (*buf);
3028 if (size > 2 && data[0] == 0xff && (data[1] >> 4 == 0x0f)) {
3031 /* tss, ADTS data, remove codec_data
3032 * still assume it is at least parsed */
3033 stream->caps = gst_caps_make_writable (stream->caps);
3034 s = gst_caps_get_structure (stream->caps, 0);
3036 gst_structure_remove_field (s, "codec_data");
3037 gst_pad_set_caps (stream->pad, stream->caps);
3038 GST_DEBUG_OBJECT (element, "ADTS AAC audio data; removing codec-data, "
3039 "new caps: %" GST_PTR_FORMAT, stream->caps);
3042 /* disable subsequent checking */
3043 stream->postprocess_frame = NULL;
3049 gst_matroska_demux_align_buffer (GstMatroskaDemux * demux,
3050 GstBuffer * buffer, gsize alignment)
3054 gst_buffer_map (buffer, &map, GST_MAP_READ);
3056 if (map.size < sizeof (guintptr)) {
3057 gst_buffer_unmap (buffer, &map);
3061 if (((guintptr) map.data) & (alignment - 1)) {
3062 GstBuffer *new_buffer;
3063 GstAllocationParams params = { 0, alignment - 1, 0, 0, };
3065 new_buffer = gst_buffer_new_allocate (NULL,
3066 gst_buffer_get_size (buffer), ¶ms);
3068 /* Copy data "by hand", so ensure alignment is kept: */
3069 gst_buffer_fill (new_buffer, 0, map.data, map.size);
3071 gst_buffer_copy_into (new_buffer, buffer, GST_BUFFER_COPY_METADATA, 0, -1);
3072 GST_DEBUG_OBJECT (demux,
3073 "We want output aligned on %" G_GSIZE_FORMAT ", reallocated",
3076 gst_buffer_unmap (buffer, &map);
3077 gst_buffer_unref (buffer);
3082 gst_buffer_unmap (buffer, &map);
3086 static GstFlowReturn
3087 gst_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux,
3088 GstEbmlRead * ebml, guint64 cluster_time, guint64 cluster_offset,
3089 gboolean is_simpleblock)
3091 GstMatroskaTrackContext *stream = NULL;
3092 GstFlowReturn ret = GST_FLOW_OK;
3093 gboolean readblock = FALSE;
3095 guint64 block_duration = -1;
3096 GstBuffer *buf = NULL;
3098 gint stream_num = -1, n, laces = 0;
3100 gint *lace_size = NULL;
3103 gint64 referenceblock = 0;
3105 GstClockTime buffer_timestamp;
3107 offset = gst_ebml_read_get_offset (ebml);
3109 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3110 if (!is_simpleblock) {
3111 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK) {
3115 id = GST_MATROSKA_ID_SIMPLEBLOCK;
3119 /* one block inside the group. Note, block parsing is one
3120 * of the harder things, so this code is a bit complicated.
3121 * See http://www.matroska.org/ for documentation. */
3122 case GST_MATROSKA_ID_SIMPLEBLOCK:
3123 case GST_MATROSKA_ID_BLOCK:
3129 gst_buffer_unmap (buf, &map);
3130 gst_buffer_unref (buf);
3133 if ((ret = gst_ebml_read_buffer (ebml, &id, &buf)) != GST_FLOW_OK)
3136 gst_buffer_map (buf, &map, GST_MAP_READ);
3140 /* first byte(s): blocknum */
3141 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
3146 /* fetch stream from num */
3147 stream_num = gst_matroska_read_common_stream_from_num (&demux->common,
3149 if (G_UNLIKELY (size < 3)) {
3150 GST_WARNING_OBJECT (demux, "Invalid size %u", size);
3151 /* non-fatal, try next block(group) */
3154 } else if (G_UNLIKELY (stream_num < 0 ||
3155 stream_num >= demux->common.num_streams)) {
3156 /* let's not give up on a stray invalid track number */
3157 GST_WARNING_OBJECT (demux,
3158 "Invalid stream %d for track number %" G_GUINT64_FORMAT
3159 "; ignoring block", stream_num, num);
3163 stream = g_ptr_array_index (demux->common.src, stream_num);
3165 /* time (relative to cluster time) */
3166 time = ((gint16) GST_READ_UINT16_BE (data));
3169 flags = GST_READ_UINT8 (data);
3173 GST_LOG_OBJECT (demux, "time %" G_GUINT64_FORMAT ", flags %d", time,
3176 switch ((flags & 0x06) >> 1) {
3177 case 0x0: /* no lacing */
3179 lace_size = g_new (gint, 1);
3180 lace_size[0] = size;
3183 case 0x1: /* xiph lacing */
3184 case 0x2: /* fixed-size lacing */
3185 case 0x3: /* EBML lacing */
3187 goto invalid_lacing;
3188 laces = GST_READ_UINT8 (data) + 1;
3191 lace_size = g_new0 (gint, laces);
3193 switch ((flags & 0x06) >> 1) {
3194 case 0x1: /* xiph lacing */ {
3195 guint temp, total = 0;
3197 for (n = 0; ret == GST_FLOW_OK && n < laces - 1; n++) {
3200 goto invalid_lacing;
3201 temp = GST_READ_UINT8 (data);
3202 lace_size[n] += temp;
3208 total += lace_size[n];
3210 lace_size[n] = size - total;
3214 case 0x2: /* fixed-size lacing */
3215 for (n = 0; n < laces; n++)
3216 lace_size[n] = size / laces;
3219 case 0x3: /* EBML lacing */ {
3222 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
3226 total = lace_size[0] = num;
3227 for (n = 1; ret == GST_FLOW_OK && n < laces - 1; n++) {
3231 if ((r = gst_matroska_ebmlnum_sint (data, size, &snum)) < 0)
3235 lace_size[n] = lace_size[n - 1] + snum;
3236 total += lace_size[n];
3239 lace_size[n] = size - total;
3246 if (ret != GST_FLOW_OK)
3253 case GST_MATROSKA_ID_BLOCKDURATION:{
3254 ret = gst_ebml_read_uint (ebml, &id, &block_duration);
3255 GST_DEBUG_OBJECT (demux, "BlockDuration: %" G_GUINT64_FORMAT,
3260 case GST_MATROSKA_ID_REFERENCEBLOCK:{
3261 ret = gst_ebml_read_sint (ebml, &id, &referenceblock);
3262 GST_DEBUG_OBJECT (demux, "ReferenceBlock: %" G_GINT64_FORMAT,
3267 case GST_MATROSKA_ID_CODECSTATE:{
3269 guint64 data_len = 0;
3272 gst_ebml_read_binary (ebml, &id, &data,
3273 &data_len)) != GST_FLOW_OK)
3276 if (G_UNLIKELY (stream == NULL)) {
3277 GST_WARNING_OBJECT (demux,
3278 "Unexpected CodecState subelement - ignoring");
3282 g_free (stream->codec_state);
3283 stream->codec_state = data;
3284 stream->codec_state_size = data_len;
3286 /* Decode if necessary */
3287 if (stream->encodings && stream->encodings->len > 0
3288 && stream->codec_state && stream->codec_state_size > 0) {
3289 if (!gst_matroska_decode_data (stream->encodings,
3290 &stream->codec_state, &stream->codec_state_size,
3291 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
3292 GST_WARNING_OBJECT (demux, "Decoding codec state failed");
3296 GST_DEBUG_OBJECT (demux, "CodecState of %" G_GSIZE_FORMAT " bytes",
3297 stream->codec_state_size);
3302 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3306 case GST_MATROSKA_ID_BLOCKVIRTUAL:
3307 case GST_MATROSKA_ID_BLOCKADDITIONS:
3308 case GST_MATROSKA_ID_REFERENCEPRIORITY:
3309 case GST_MATROSKA_ID_REFERENCEVIRTUAL:
3310 case GST_MATROSKA_ID_SLICES:
3311 GST_DEBUG_OBJECT (demux,
3312 "Skipping BlockGroup subelement 0x%x - ignoring", id);
3313 ret = gst_ebml_read_skip (ebml);
3321 /* reading a number or so could have failed */
3322 if (ret != GST_FLOW_OK)
3325 if (ret == GST_FLOW_OK && readblock) {
3326 gboolean invisible_frame = FALSE;
3327 gboolean delta_unit = FALSE;
3328 guint64 duration = 0;
3329 gint64 lace_time = 0;
3331 stream = g_ptr_array_index (demux->common.src, stream_num);
3333 if (cluster_time != GST_CLOCK_TIME_NONE) {
3334 /* FIXME: What to do with negative timestamps? Give timestamp 0 or -1?
3335 * Drop unless the lace contains timestamp 0? */
3336 if (time < 0 && (-time) > cluster_time) {
3339 if (stream->timecodescale == 1.0)
3340 lace_time = (cluster_time + time) * demux->common.time_scale;
3343 gst_util_guint64_to_gdouble ((cluster_time + time) *
3344 demux->common.time_scale) * stream->timecodescale;
3347 lace_time = GST_CLOCK_TIME_NONE;
3350 /* need to refresh segment info ASAP */
3351 if (GST_CLOCK_TIME_IS_VALID (lace_time) && demux->need_segment) {
3352 GstSegment *segment = &demux->common.segment;
3354 GstEvent *segment_event;
3356 if (!GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
3357 demux->stream_start_time = lace_time;
3358 GST_DEBUG_OBJECT (demux,
3359 "Setting stream start time to %" GST_TIME_FORMAT,
3360 GST_TIME_ARGS (lace_time));
3362 clace_time = MAX (lace_time, demux->stream_start_time);
3363 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.position) &&
3364 demux->common.segment.position != 0) {
3365 GST_DEBUG_OBJECT (demux,
3366 "using stored seek position %" GST_TIME_FORMAT,
3367 GST_TIME_ARGS (demux->common.segment.position));
3368 clace_time = demux->common.segment.position + demux->stream_start_time;
3369 segment->position = GST_CLOCK_TIME_NONE;
3371 segment->start = clace_time;
3372 segment->stop = GST_CLOCK_TIME_NONE;
3373 segment->time = segment->start - demux->stream_start_time;
3374 segment->position = segment->start - demux->stream_start_time;
3375 GST_DEBUG_OBJECT (demux,
3376 "generated segment starting at %" GST_TIME_FORMAT ": %"
3377 GST_SEGMENT_FORMAT, GST_TIME_ARGS (lace_time), segment);
3378 /* now convey our segment notion downstream */
3379 segment_event = gst_event_new_segment (segment);
3380 if (demux->segment_seqnum)
3381 gst_event_set_seqnum (segment_event, demux->segment_seqnum);
3382 gst_matroska_demux_send_event (demux, segment_event);
3383 demux->need_segment = FALSE;
3384 demux->segment_seqnum = 0;
3387 /* send pending codec data headers for all streams,
3388 * before we perform sync across all streams */
3389 gst_matroska_demux_push_codec_data_all (demux);
3391 if (block_duration != -1) {
3392 if (stream->timecodescale == 1.0)
3393 duration = gst_util_uint64_scale (block_duration,
3394 demux->common.time_scale, 1);
3397 gst_util_gdouble_to_guint64 (gst_util_guint64_to_gdouble
3398 (gst_util_uint64_scale (block_duration, demux->common.time_scale,
3399 1)) * stream->timecodescale);
3400 } else if (stream->default_duration) {
3401 duration = stream->default_duration * laces;
3403 /* else duration is diff between timecode of this and next block */
3405 /* For SimpleBlock, look at the keyframe bit in flags. Otherwise,
3406 a ReferenceBlock implies that this is not a keyframe. In either
3407 case, it only makes sense for video streams. */
3408 if (stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
3409 if ((is_simpleblock && !(flags & 0x80)) || referenceblock) {
3411 invisible_frame = ((flags & 0x08)) &&
3412 (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8) ||
3413 !strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP9));
3417 for (n = 0; n < laces; n++) {
3420 if (G_UNLIKELY (lace_size[n] > size)) {
3421 GST_WARNING_OBJECT (demux, "Invalid lace size");
3425 /* QoS for video track with an index. the assumption is that
3426 index entries point to keyframes, but if that is not true we
3427 will instad skip until the next keyframe. */
3428 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
3429 stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
3430 stream->index_table && demux->common.segment.rate > 0.0) {
3431 GstMatroskaTrackVideoContext *videocontext =
3432 (GstMatroskaTrackVideoContext *) stream;
3433 GstClockTime earliest_time;
3434 GstClockTime earliest_stream_time;
3436 GST_OBJECT_LOCK (demux);
3437 earliest_time = videocontext->earliest_time;
3438 GST_OBJECT_UNLOCK (demux);
3439 earliest_stream_time = gst_segment_to_position (&demux->common.segment,
3440 GST_FORMAT_TIME, earliest_time);
3442 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
3443 GST_CLOCK_TIME_IS_VALID (earliest_stream_time) &&
3444 lace_time <= earliest_stream_time) {
3445 /* find index entry (keyframe) <= earliest_stream_time */
3446 GstMatroskaIndex *entry =
3447 gst_util_array_binary_search (stream->index_table->data,
3448 stream->index_table->len, sizeof (GstMatroskaIndex),
3449 (GCompareDataFunc) gst_matroska_index_seek_find,
3450 GST_SEARCH_MODE_BEFORE, &earliest_stream_time, NULL);
3452 /* if that entry (keyframe) is after the current the current
3453 buffer, we can skip pushing (and thus decoding) all
3454 buffers until that keyframe. */
3455 if (entry && GST_CLOCK_TIME_IS_VALID (entry->time) &&
3456 entry->time > lace_time) {
3457 GST_LOG_OBJECT (demux, "Skipping lace before late keyframe");
3458 stream->set_discont = TRUE;
3464 sub = gst_buffer_copy_region (buf, GST_BUFFER_COPY_ALL,
3465 gst_buffer_get_size (buf) - size, lace_size[n]);
3466 GST_DEBUG_OBJECT (demux, "created subbuffer %p", sub);
3469 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
3471 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
3473 if (invisible_frame)
3474 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DECODE_ONLY);
3476 if (stream->encodings != NULL && stream->encodings->len > 0)
3477 sub = gst_matroska_decode_buffer (stream, sub);
3480 GST_WARNING_OBJECT (demux, "Decoding buffer failed");
3484 buffer_timestamp = gst_matroska_track_get_buffer_timestamp (stream, sub);
3486 if (!stream->dts_only) {
3487 GST_BUFFER_PTS (sub) = lace_time;
3489 GST_BUFFER_DTS (sub) = lace_time;
3490 if (stream->intra_only)
3491 GST_BUFFER_PTS (sub) = lace_time;
3494 if (GST_CLOCK_TIME_IS_VALID (lace_time)) {
3495 GstClockTime last_stop_end;
3497 /* Check if this stream is after segment stop */
3498 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop) &&
3499 lace_time >= demux->common.segment.stop) {
3500 GST_DEBUG_OBJECT (demux,
3501 "Stream %d after segment stop %" GST_TIME_FORMAT, stream->index,
3502 GST_TIME_ARGS (demux->common.segment.stop));
3503 gst_buffer_unref (sub);
3506 if (offset >= stream->to_offset
3507 || (GST_CLOCK_TIME_IS_VALID (demux->to_time)
3508 && lace_time > demux->to_time)) {
3509 GST_DEBUG_OBJECT (demux, "Stream %d after playback section",
3511 gst_buffer_unref (sub);
3515 /* handle gaps, e.g. non-zero start-time, or an cue index entry
3516 * that landed us with timestamps not quite intended */
3517 GST_OBJECT_LOCK (demux);
3518 if (demux->max_gap_time &&
3519 GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) &&
3520 demux->common.segment.rate > 0.0) {
3521 GstClockTimeDiff diff;
3523 /* only send segments with increasing start times,
3524 * otherwise if these go back and forth downstream (sinks) increase
3525 * accumulated time and running_time */
3526 diff = GST_CLOCK_DIFF (demux->last_stop_end, lace_time);
3527 if (diff > 0 && diff > demux->max_gap_time
3528 && lace_time > demux->common.segment.start
3529 && (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop)
3530 || lace_time < demux->common.segment.stop)) {
3532 GST_DEBUG_OBJECT (demux,
3533 "Gap of %" G_GINT64_FORMAT " ns detected in"
3534 "stream %d (%" GST_TIME_FORMAT " -> %" GST_TIME_FORMAT "). "
3535 "Sending updated SEGMENT events", diff,
3536 stream->index, GST_TIME_ARGS (stream->pos),
3537 GST_TIME_ARGS (lace_time));
3539 event = gst_event_new_gap (demux->last_stop_end, diff);
3540 GST_OBJECT_UNLOCK (demux);
3541 gst_pad_push_event (stream->pad, event);
3542 GST_OBJECT_LOCK (demux);
3546 if (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.position)
3547 || demux->common.segment.position < lace_time) {
3548 demux->common.segment.position = lace_time;
3550 GST_OBJECT_UNLOCK (demux);
3552 last_stop_end = lace_time;
3554 GST_BUFFER_DURATION (sub) = duration / laces;
3555 last_stop_end += GST_BUFFER_DURATION (sub);
3558 if (!GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) ||
3559 demux->last_stop_end < last_stop_end)
3560 demux->last_stop_end = last_stop_end;
3562 GST_OBJECT_LOCK (demux);
3563 if (demux->common.segment.duration == -1 ||
3564 demux->stream_start_time + demux->common.segment.duration <
3566 demux->common.segment.duration =
3567 last_stop_end - demux->stream_start_time;
3568 GST_OBJECT_UNLOCK (demux);
3569 if (!demux->invalid_duration) {
3570 gst_element_post_message (GST_ELEMENT_CAST (demux),
3571 gst_message_new_duration_changed (GST_OBJECT_CAST (demux)));
3572 demux->invalid_duration = TRUE;
3575 GST_OBJECT_UNLOCK (demux);
3579 stream->pos = lace_time;
3581 gst_matroska_demux_sync_streams (demux);
3583 if (stream->set_discont) {
3584 GST_DEBUG_OBJECT (demux, "marking DISCONT");
3585 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DISCONT);
3586 stream->set_discont = FALSE;
3588 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DISCONT);
3591 /* reverse playback book-keeping */
3592 if (!GST_CLOCK_TIME_IS_VALID (stream->from_time))
3593 stream->from_time = lace_time;
3594 if (stream->from_offset == -1)
3595 stream->from_offset = offset;
3597 GST_DEBUG_OBJECT (demux,
3598 "Pushing lace %d, data of size %" G_GSIZE_FORMAT
3599 " for stream %d, time=%" GST_TIME_FORMAT " and duration=%"
3600 GST_TIME_FORMAT, n, gst_buffer_get_size (sub), stream_num,
3601 GST_TIME_ARGS (buffer_timestamp),
3602 GST_TIME_ARGS (GST_BUFFER_DURATION (sub)));
3605 if (demux->common.element_index) {
3606 if (stream->index_writer_id == -1)
3607 gst_index_get_writer_id (demux->common.element_index,
3608 GST_OBJECT (stream->pad), &stream->index_writer_id);
3610 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
3611 G_GUINT64_FORMAT " for writer id %d",
3612 GST_TIME_ARGS (buffer_timestamp), cluster_offset,
3613 stream->index_writer_id);
3614 gst_index_add_association (demux->common.element_index,
3615 stream->index_writer_id, GST_BUFFER_FLAG_IS_SET (sub,
3616 GST_BUFFER_FLAG_DELTA_UNIT) ? 0 : GST_ASSOCIATION_FLAG_KEY_UNIT,
3617 GST_FORMAT_TIME, buffer_timestamp, GST_FORMAT_BYTES, cluster_offset,
3622 /* Postprocess the buffers depending on the codec used */
3623 if (stream->postprocess_frame) {
3624 GST_LOG_OBJECT (demux, "running post process");
3625 ret = stream->postprocess_frame (GST_ELEMENT (demux), stream, &sub);
3628 /* At this point, we have a sub-buffer pointing at data within a larger
3629 buffer. This data might not be aligned with anything. If the data is
3630 raw samples though, we want it aligned to the raw type (eg, 4 bytes
3631 for 32 bit samples, etc), or bad things will happen downstream as
3632 elements typically assume minimal alignment.
3633 Therefore, create an aligned copy if necessary. */
3634 g_assert (stream->alignment <= G_MEM_ALIGN);
3635 sub = gst_matroska_demux_align_buffer (demux, sub, stream->alignment);
3637 if (GST_BUFFER_PTS_IS_VALID (sub)) {
3638 stream->pos = GST_BUFFER_PTS (sub);
3639 if (GST_BUFFER_DURATION_IS_VALID (sub))
3640 stream->pos += GST_BUFFER_DURATION (sub);
3641 } else if (GST_BUFFER_DTS_IS_VALID (sub)) {
3642 stream->pos = GST_BUFFER_DTS (sub);
3643 if (GST_BUFFER_DURATION_IS_VALID (sub))
3644 stream->pos += GST_BUFFER_DURATION (sub);
3647 ret = gst_pad_push (stream->pad, sub);
3649 if (demux->common.segment.rate < 0) {
3650 if (lace_time > demux->common.segment.stop && ret == GST_FLOW_EOS) {
3651 /* In reverse playback we can get a GST_FLOW_EOS when
3652 * we are at the end of the segment, so we just need to jump
3653 * back to the previous section. */
3654 GST_DEBUG_OBJECT (demux, "downstream has reached end of segment");
3659 ret = gst_flow_combiner_update_pad_flow (demux->flowcombiner,
3663 size -= lace_size[n];
3664 if (lace_time != GST_CLOCK_TIME_NONE && duration)
3665 lace_time += duration / laces;
3667 lace_time = GST_CLOCK_TIME_NONE;
3673 gst_buffer_unmap (buf, &map);
3674 gst_buffer_unref (buf);
3686 ret = gst_flow_combiner_update_pad_flow (demux->flowcombiner, stream->pad,
3692 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Invalid lacing size"));
3693 /* non-fatal, try next block(group) */
3699 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Data error"));
3700 /* non-fatal, try next block(group) */
3706 /* return FALSE if block(group) should be skipped (due to a seek) */
3707 static inline gboolean
3708 gst_matroska_demux_seek_block (GstMatroskaDemux * demux)
3710 if (G_UNLIKELY (demux->seek_block)) {
3711 if (!(--demux->seek_block)) {
3714 GST_LOG_OBJECT (demux, "should skip block due to seek");
3722 static GstFlowReturn
3723 gst_matroska_demux_parse_contents_seekentry (GstMatroskaDemux * demux,
3727 guint64 seek_pos = (guint64) - 1;
3728 guint32 seek_id = 0;
3731 DEBUG_ELEMENT_START (demux, ebml, "Seek");
3733 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3734 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
3738 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3739 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3743 case GST_MATROSKA_ID_SEEKID:
3747 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
3750 GST_DEBUG_OBJECT (demux, "SeekID: %" G_GUINT64_FORMAT, t);
3755 case GST_MATROSKA_ID_SEEKPOSITION:
3759 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
3762 if (t > G_MAXINT64) {
3763 GST_WARNING_OBJECT (demux,
3764 "Too large SeekPosition %" G_GUINT64_FORMAT, t);
3768 GST_DEBUG_OBJECT (demux, "SeekPosition: %" G_GUINT64_FORMAT, t);
3774 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3780 if (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)
3783 if (!seek_id || seek_pos == (guint64) - 1) {
3784 GST_WARNING_OBJECT (demux, "Incomplete seekhead entry (0x%x/%"
3785 G_GUINT64_FORMAT ")", seek_id, seek_pos);
3790 case GST_MATROSKA_ID_SEEKHEAD:
3793 case GST_MATROSKA_ID_CUES:
3794 case GST_MATROSKA_ID_TAGS:
3795 case GST_MATROSKA_ID_TRACKS:
3796 case GST_MATROSKA_ID_SEGMENTINFO:
3797 case GST_MATROSKA_ID_ATTACHMENTS:
3798 case GST_MATROSKA_ID_CHAPTERS:
3800 guint64 before_pos, length;
3804 length = gst_matroska_read_common_get_length (&demux->common);
3805 before_pos = demux->common.offset;
3807 if (length == (guint64) - 1) {
3808 GST_DEBUG_OBJECT (demux, "no upstream length, skipping SeakHead entry");
3812 /* check for validity */
3813 if (seek_pos + demux->common.ebml_segment_start + 12 >= length) {
3814 GST_WARNING_OBJECT (demux,
3815 "SeekHead reference lies outside file!" " (%"
3816 G_GUINT64_FORMAT "+%" G_GUINT64_FORMAT "+12 >= %"
3817 G_GUINT64_FORMAT ")", seek_pos, demux->common.ebml_segment_start,
3822 /* only pick up index location when streaming */
3823 if (demux->streaming) {
3824 if (seek_id == GST_MATROSKA_ID_CUES) {
3825 demux->index_offset = seek_pos + demux->common.ebml_segment_start;
3826 GST_DEBUG_OBJECT (demux, "Cues located at offset %" G_GUINT64_FORMAT,
3827 demux->index_offset);
3833 demux->common.offset = seek_pos + demux->common.ebml_segment_start;
3836 if ((ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
3837 GST_ELEMENT_CAST (demux), &id, &length, &needed)) !=
3841 if (id != seek_id) {
3842 GST_WARNING_OBJECT (demux,
3843 "We looked for ID=0x%x but got ID=0x%x (pos=%" G_GUINT64_FORMAT ")",
3844 seek_id, id, seek_pos + demux->common.ebml_segment_start);
3847 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
3852 demux->common.offset = before_pos;
3856 case GST_MATROSKA_ID_CLUSTER:
3858 guint64 pos = seek_pos + demux->common.ebml_segment_start;
3860 GST_LOG_OBJECT (demux, "Cluster position");
3861 if (G_UNLIKELY (!demux->clusters))
3862 demux->clusters = g_array_sized_new (TRUE, TRUE, sizeof (guint64), 100);
3863 g_array_append_val (demux->clusters, pos);
3868 GST_DEBUG_OBJECT (demux, "Ignoring Seek entry for ID=0x%x", seek_id);
3871 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
3876 static GstFlowReturn
3877 gst_matroska_demux_parse_contents (GstMatroskaDemux * demux, GstEbmlRead * ebml)
3879 GstFlowReturn ret = GST_FLOW_OK;
3882 DEBUG_ELEMENT_START (demux, ebml, "SeekHead");
3884 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3885 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
3889 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3890 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3894 case GST_MATROSKA_ID_SEEKENTRY:
3896 ret = gst_matroska_demux_parse_contents_seekentry (demux, ebml);
3897 /* Ignore EOS and errors here */
3898 if (ret != GST_FLOW_OK) {
3899 GST_DEBUG_OBJECT (demux, "Ignoring %s", gst_flow_get_name (ret));
3906 ret = gst_matroska_read_common_parse_skip (&demux->common,
3907 ebml, "SeekHead", id);
3912 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
3914 /* Sort clusters by position for easier searching */
3915 if (demux->clusters)
3916 g_array_sort (demux->clusters, (GCompareFunc) gst_matroska_cluster_compare);
3921 #define GST_FLOW_OVERFLOW GST_FLOW_CUSTOM_ERROR
3923 #define MAX_BLOCK_SIZE (15 * 1024 * 1024)
3925 static inline GstFlowReturn
3926 gst_matroska_demux_check_read_size (GstMatroskaDemux * demux, guint64 bytes)
3928 if (G_UNLIKELY (bytes > MAX_BLOCK_SIZE)) {
3929 /* only a few blocks are expected/allowed to be large,
3930 * and will be recursed into, whereas others will be read and must fit */
3931 if (demux->streaming) {
3932 /* fatal in streaming case, as we can't step over easily */
3933 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
3934 ("reading large block of size %" G_GUINT64_FORMAT " not supported; "
3935 "file might be corrupt.", bytes));
3936 return GST_FLOW_ERROR;
3938 /* indicate higher level to quietly give up */
3939 GST_DEBUG_OBJECT (demux,
3940 "too large block of size %" G_GUINT64_FORMAT, bytes);
3941 return GST_FLOW_ERROR;
3948 /* returns TRUE if we truely are in error state, and should give up */
3949 static inline GstFlowReturn
3950 gst_matroska_demux_check_parse_error (GstMatroskaDemux * demux)
3952 if (!demux->streaming && demux->next_cluster_offset > 0) {
3953 /* just repositioning to where next cluster should be and try from there */
3954 GST_WARNING_OBJECT (demux, "parse error, trying next cluster expected at %"
3955 G_GUINT64_FORMAT, demux->next_cluster_offset);
3956 demux->common.offset = demux->next_cluster_offset;
3957 demux->next_cluster_offset = 0;
3963 /* sigh, one last attempt above and beyond call of duty ...;
3964 * search for cluster mark following current pos */
3965 pos = demux->common.offset;
3966 GST_WARNING_OBJECT (demux, "parse error, looking for next cluster");
3967 if ((ret = gst_matroska_demux_search_cluster (demux, &pos)) != GST_FLOW_OK) {
3968 /* did not work, give up */
3971 GST_DEBUG_OBJECT (demux, "... found at %" G_GUINT64_FORMAT, pos);
3972 /* try that position */
3973 demux->common.offset = pos;
3979 static inline GstFlowReturn
3980 gst_matroska_demux_flush (GstMatroskaDemux * demux, guint flush)
3982 GST_LOG_OBJECT (demux, "skipping %d bytes", flush);
3983 demux->common.offset += flush;
3984 if (demux->streaming) {
3987 /* hard to skip large blocks when streaming */
3988 ret = gst_matroska_demux_check_read_size (demux, flush);
3989 if (ret != GST_FLOW_OK)
3991 if (flush <= gst_adapter_available (demux->common.adapter))
3992 gst_adapter_flush (demux->common.adapter, flush);
3994 return GST_FLOW_EOS;
3999 /* initializes @ebml with @bytes from input stream at current offset.
4000 * Returns EOS if insufficient available,
4001 * ERROR if too much was attempted to read. */
4002 static inline GstFlowReturn
4003 gst_matroska_demux_take (GstMatroskaDemux * demux, guint64 bytes,
4006 GstBuffer *buffer = NULL;
4007 GstFlowReturn ret = GST_FLOW_OK;
4009 GST_LOG_OBJECT (demux, "taking %" G_GUINT64_FORMAT " bytes for parsing",
4011 ret = gst_matroska_demux_check_read_size (demux, bytes);
4012 if (G_UNLIKELY (ret != GST_FLOW_OK)) {
4013 if (!demux->streaming) {
4014 /* in pull mode, we can skip */
4015 if ((ret = gst_matroska_demux_flush (demux, bytes)) == GST_FLOW_OK)
4016 ret = GST_FLOW_OVERFLOW;
4018 /* otherwise fatal */
4019 ret = GST_FLOW_ERROR;
4023 if (demux->streaming) {
4024 if (gst_adapter_available (demux->common.adapter) >= bytes)
4025 buffer = gst_adapter_take_buffer (demux->common.adapter, bytes);
4029 ret = gst_matroska_read_common_peek_bytes (&demux->common,
4030 demux->common.offset, bytes, &buffer, NULL);
4031 if (G_LIKELY (buffer)) {
4032 gst_ebml_read_init (ebml, GST_ELEMENT_CAST (demux), buffer,
4033 demux->common.offset);
4034 demux->common.offset += bytes;
4041 gst_matroska_demux_check_seekability (GstMatroskaDemux * demux)
4044 gboolean seekable = FALSE;
4045 gint64 start = -1, stop = -1;
4047 query = gst_query_new_seeking (GST_FORMAT_BYTES);
4048 if (!gst_pad_peer_query (demux->common.sinkpad, query)) {
4049 GST_DEBUG_OBJECT (demux, "seeking query failed");
4053 gst_query_parse_seeking (query, NULL, &seekable, &start, &stop);
4055 /* try harder to query upstream size if we didn't get it the first time */
4056 if (seekable && stop == -1) {
4057 GST_DEBUG_OBJECT (demux, "doing duration query to fix up unset stop");
4058 gst_pad_peer_query_duration (demux->common.sinkpad, GST_FORMAT_BYTES,
4062 /* if upstream doesn't know the size, it's likely that it's not seekable in
4063 * practice even if it technically may be seekable */
4064 if (seekable && (start != 0 || stop <= start)) {
4065 GST_DEBUG_OBJECT (demux, "seekable but unknown start/stop -> disable");
4070 GST_INFO_OBJECT (demux, "seekable: %d (%" G_GUINT64_FORMAT " - %"
4071 G_GUINT64_FORMAT ")", seekable, start, stop);
4072 demux->seekable = seekable;
4074 gst_query_unref (query);
4077 static GstFlowReturn
4078 gst_matroska_demux_find_tracks (GstMatroskaDemux * demux)
4084 GstFlowReturn ret = GST_FLOW_OK;
4086 GST_WARNING_OBJECT (demux,
4087 "Found Cluster element before Tracks, searching Tracks");
4090 before_pos = demux->common.offset;
4092 /* Search Tracks element */
4094 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4095 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4096 if (ret != GST_FLOW_OK)
4099 if (id != GST_MATROSKA_ID_TRACKS) {
4100 /* we may be skipping large cluster here, so forego size check etc */
4101 /* ... but we can't skip undefined size; force error */
4102 if (length == G_MAXUINT64) {
4103 ret = gst_matroska_demux_check_read_size (demux, length);
4106 demux->common.offset += needed;
4107 demux->common.offset += length;
4112 /* will lead to track parsing ... */
4113 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4118 demux->common.offset = before_pos;
4123 #define GST_READ_CHECK(stmt) \
4125 if (G_UNLIKELY ((ret = (stmt)) != GST_FLOW_OK)) { \
4126 if (ret == GST_FLOW_OVERFLOW) { \
4127 ret = GST_FLOW_OK; \
4133 static GstFlowReturn
4134 gst_matroska_demux_parse_id (GstMatroskaDemux * demux, guint32 id,
4135 guint64 length, guint needed)
4137 GstEbmlRead ebml = { 0, };
4138 GstFlowReturn ret = GST_FLOW_OK;
4141 GST_LOG_OBJECT (demux, "Parsing Element id 0x%x, "
4142 "size %" G_GUINT64_FORMAT ", prefix %d", id, length, needed);
4144 /* if we plan to read and parse this element, we need prefix (id + length)
4145 * and the contents */
4146 /* mind about overflow wrap-around when dealing with undefined size */
4148 if (G_LIKELY (length != G_MAXUINT64))
4151 switch (demux->common.state) {
4152 case GST_MATROSKA_READ_STATE_START:
4154 case GST_EBML_ID_HEADER:
4155 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4156 ret = gst_matroska_read_common_parse_header (&demux->common, &ebml);
4157 if (ret != GST_FLOW_OK)
4159 demux->common.state = GST_MATROSKA_READ_STATE_SEGMENT;
4160 gst_matroska_demux_check_seekability (demux);
4163 goto invalid_header;
4167 case GST_MATROSKA_READ_STATE_SEGMENT:
4169 case GST_MATROSKA_ID_SEGMENT:
4170 /* eat segment prefix */
4171 GST_READ_CHECK (gst_matroska_demux_flush (demux, needed));
4172 GST_DEBUG_OBJECT (demux,
4173 "Found Segment start at offset %" G_GUINT64_FORMAT " with size %"
4174 G_GUINT64_FORMAT, demux->common.offset, length);
4175 /* seeks are from the beginning of the segment,
4176 * after the segment ID/length */
4177 demux->common.ebml_segment_start = demux->common.offset;
4179 length = G_MAXUINT64;
4180 demux->common.ebml_segment_length = length;
4181 demux->common.state = GST_MATROSKA_READ_STATE_HEADER;
4184 GST_WARNING_OBJECT (demux,
4185 "Expected a Segment ID (0x%x), but received 0x%x!",
4186 GST_MATROSKA_ID_SEGMENT, id);
4187 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4191 case GST_MATROSKA_READ_STATE_SCANNING:
4192 if (id != GST_MATROSKA_ID_CLUSTER &&
4193 id != GST_MATROSKA_ID_CLUSTERTIMECODE)
4196 case GST_MATROSKA_READ_STATE_HEADER:
4197 case GST_MATROSKA_READ_STATE_DATA:
4198 case GST_MATROSKA_READ_STATE_SEEK:
4200 case GST_MATROSKA_ID_SEGMENTINFO:
4201 if (!demux->common.segmentinfo_parsed) {
4202 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4203 ret = gst_matroska_read_common_parse_info (&demux->common,
4204 GST_ELEMENT_CAST (demux), &ebml);
4205 if (ret == GST_FLOW_OK)
4206 gst_matroska_demux_send_tags (demux);
4208 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4211 case GST_MATROSKA_ID_TRACKS:
4212 if (!demux->tracks_parsed) {
4213 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4214 ret = gst_matroska_demux_parse_tracks (demux, &ebml);
4216 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4219 case GST_MATROSKA_ID_CLUSTER:
4220 if (G_UNLIKELY (!demux->tracks_parsed)) {
4221 if (demux->streaming) {
4222 GST_DEBUG_OBJECT (demux, "Cluster before Track");
4223 goto not_streamable;
4225 ret = gst_matroska_demux_find_tracks (demux);
4226 if (!demux->tracks_parsed)
4230 if (G_UNLIKELY (demux->common.state
4231 == GST_MATROSKA_READ_STATE_HEADER)) {
4232 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
4233 demux->first_cluster_offset = demux->common.offset;
4234 GST_DEBUG_OBJECT (demux, "signaling no more pads");
4235 gst_element_no_more_pads (GST_ELEMENT (demux));
4236 /* send initial segment - we wait till we know the first
4237 incoming timestamp, so we can properly set the start of
4239 demux->need_segment = TRUE;
4241 demux->cluster_time = GST_CLOCK_TIME_NONE;
4242 demux->cluster_offset = demux->common.offset;
4243 if (G_UNLIKELY (!demux->seek_first && demux->seek_block)) {
4244 GST_DEBUG_OBJECT (demux, "seek target block %" G_GUINT64_FORMAT
4245 " not found in Cluster, trying next Cluster's first block instead",
4247 demux->seek_block = 0;
4249 demux->seek_first = FALSE;
4250 /* record next cluster for recovery */
4251 if (read != G_MAXUINT64)
4252 demux->next_cluster_offset = demux->cluster_offset + read;
4253 /* eat cluster prefix */
4254 gst_matroska_demux_flush (demux, needed);
4256 case GST_MATROSKA_ID_CLUSTERTIMECODE:
4260 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4261 if ((ret = gst_ebml_read_uint (&ebml, &id, &num)) != GST_FLOW_OK)
4263 GST_DEBUG_OBJECT (demux, "ClusterTimeCode: %" G_GUINT64_FORMAT, num);
4264 demux->cluster_time = num;
4266 if (demux->common.element_index) {
4267 if (demux->common.element_index_writer_id == -1)
4268 gst_index_get_writer_id (demux->common.element_index,
4269 GST_OBJECT (demux), &demux->common.element_index_writer_id);
4270 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
4271 G_GUINT64_FORMAT " for writer id %d",
4272 GST_TIME_ARGS (demux->cluster_time), demux->cluster_offset,
4273 demux->common.element_index_writer_id);
4274 gst_index_add_association (demux->common.element_index,
4275 demux->common.element_index_writer_id,
4276 GST_ASSOCIATION_FLAG_KEY_UNIT,
4277 GST_FORMAT_TIME, demux->cluster_time,
4278 GST_FORMAT_BYTES, demux->cluster_offset, NULL);
4283 case GST_MATROSKA_ID_BLOCKGROUP:
4284 if (!gst_matroska_demux_seek_block (demux))
4286 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4287 DEBUG_ELEMENT_START (demux, &ebml, "BlockGroup");
4288 if ((ret = gst_ebml_read_master (&ebml, &id)) == GST_FLOW_OK) {
4289 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4290 &ebml, demux->cluster_time, demux->cluster_offset, FALSE);
4292 DEBUG_ELEMENT_STOP (demux, &ebml, "BlockGroup", ret);
4294 case GST_MATROSKA_ID_SIMPLEBLOCK:
4295 if (!gst_matroska_demux_seek_block (demux))
4297 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4298 DEBUG_ELEMENT_START (demux, &ebml, "SimpleBlock");
4299 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4300 &ebml, demux->cluster_time, demux->cluster_offset, TRUE);
4301 DEBUG_ELEMENT_STOP (demux, &ebml, "SimpleBlock", ret);
4303 case GST_MATROSKA_ID_ATTACHMENTS:
4304 if (!demux->common.attachments_parsed) {
4305 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4306 ret = gst_matroska_read_common_parse_attachments (&demux->common,
4307 GST_ELEMENT_CAST (demux), &ebml);
4308 if (ret == GST_FLOW_OK)
4309 gst_matroska_demux_send_tags (demux);
4311 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4314 case GST_MATROSKA_ID_TAGS:
4315 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4316 ret = gst_matroska_read_common_parse_metadata (&demux->common,
4317 GST_ELEMENT_CAST (demux), &ebml);
4318 if (ret == GST_FLOW_OK)
4319 gst_matroska_demux_send_tags (demux);
4321 case GST_MATROSKA_ID_CHAPTERS:
4322 if (!demux->common.chapters_parsed) {
4323 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4325 gst_matroska_read_common_parse_chapters (&demux->common, &ebml);
4327 if (demux->common.toc) {
4328 gst_matroska_demux_send_event (demux,
4329 gst_event_new_toc (demux->common.toc, FALSE));
4332 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4334 case GST_MATROSKA_ID_SEEKHEAD:
4335 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4336 ret = gst_matroska_demux_parse_contents (demux, &ebml);
4338 case GST_MATROSKA_ID_CUES:
4339 if (demux->common.index_parsed) {
4340 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4343 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4344 ret = gst_matroska_read_common_parse_index (&demux->common, &ebml);
4345 /* only push based; delayed index building */
4346 if (ret == GST_FLOW_OK
4347 && demux->common.state == GST_MATROSKA_READ_STATE_SEEK) {
4350 GST_OBJECT_LOCK (demux);
4351 event = demux->seek_event;
4352 demux->seek_event = NULL;
4353 GST_OBJECT_UNLOCK (demux);
4356 /* unlikely to fail, since we managed to seek to this point */
4357 if (!gst_matroska_demux_handle_seek_event (demux, NULL, event))
4359 /* resume data handling, main thread clear to seek again */
4360 GST_OBJECT_LOCK (demux);
4361 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
4362 GST_OBJECT_UNLOCK (demux);
4365 case GST_MATROSKA_ID_POSITION:
4366 case GST_MATROSKA_ID_PREVSIZE:
4367 case GST_MATROSKA_ID_ENCRYPTEDBLOCK:
4368 case GST_MATROSKA_ID_SILENTTRACKS:
4369 GST_DEBUG_OBJECT (demux,
4370 "Skipping Cluster subelement 0x%x - ignoring", id);
4374 GST_DEBUG_OBJECT (demux, "skipping Element 0x%x", id);
4375 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4381 if (ret == GST_FLOW_PARSE)
4385 gst_ebml_read_clear (&ebml);
4391 /* simply exit, maybe not enough data yet */
4392 /* no ebml to clear if read error */
4397 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4398 ("Failed to parse Element 0x%x", id));
4399 ret = GST_FLOW_ERROR;
4404 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4405 ("File layout does not permit streaming"));
4406 ret = GST_FLOW_ERROR;
4411 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4412 ("No Tracks element found"));
4413 ret = GST_FLOW_ERROR;
4418 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Invalid header"));
4419 ret = GST_FLOW_ERROR;
4424 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Failed to seek"));
4425 ret = GST_FLOW_ERROR;
4431 gst_matroska_demux_loop (GstPad * pad)
4433 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (pad));
4439 /* If we have to close a segment, send a new segment to do this now */
4440 if (G_LIKELY (demux->common.state == GST_MATROSKA_READ_STATE_DATA)) {
4441 if (G_UNLIKELY (demux->new_segment)) {
4442 gst_matroska_demux_send_event (demux, demux->new_segment);
4443 demux->new_segment = NULL;
4447 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4448 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4449 if (ret == GST_FLOW_EOS) {
4451 } else if (ret == GST_FLOW_FLUSHING) {
4453 } else if (ret != GST_FLOW_OK) {
4454 ret = gst_matroska_demux_check_parse_error (demux);
4456 /* Only handle EOS as no error if we're outside the segment already */
4457 if (ret == GST_FLOW_EOS && (demux->common.ebml_segment_length != G_MAXUINT64
4458 && demux->common.offset >=
4459 demux->common.ebml_segment_start +
4460 demux->common.ebml_segment_length))
4462 else if (ret != GST_FLOW_OK)
4468 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
4469 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
4472 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4473 if (ret == GST_FLOW_EOS)
4475 if (ret != GST_FLOW_OK)
4478 /* check if we're at the end of a configured segment */
4479 if (G_LIKELY (demux->common.src->len)) {
4482 g_assert (demux->common.num_streams == demux->common.src->len);
4483 for (i = 0; i < demux->common.src->len; i++) {
4484 GstMatroskaTrackContext *context = g_ptr_array_index (demux->common.src,
4486 GST_DEBUG_OBJECT (context->pad, "pos %" GST_TIME_FORMAT,
4487 GST_TIME_ARGS (context->pos));
4488 if (context->eos == FALSE)
4492 GST_INFO_OBJECT (demux, "All streams are EOS");
4498 if (G_UNLIKELY (demux->cached_length == G_MAXUINT64 ||
4499 demux->common.offset >= demux->cached_length)) {
4500 demux->cached_length = gst_matroska_read_common_get_length (&demux->common);
4501 if (demux->common.offset == demux->cached_length) {
4502 GST_LOG_OBJECT (demux, "Reached end of stream");
4513 if (demux->common.segment.rate < 0.0) {
4514 ret = gst_matroska_demux_seek_to_previous_keyframe (demux);
4515 if (ret == GST_FLOW_OK)
4522 const gchar *reason = gst_flow_get_name (ret);
4523 gboolean push_eos = FALSE;
4525 GST_LOG_OBJECT (demux, "pausing task, reason %s", reason);
4526 gst_pad_pause_task (demux->common.sinkpad);
4528 if (ret == GST_FLOW_EOS) {
4529 /* perform EOS logic */
4531 /* If we were in the headers, make sure we send no-more-pads.
4532 This will ensure decodebin2 does not get stuck thinking
4533 the chain is not complete yet, and waiting indefinitely. */
4534 if (G_UNLIKELY (demux->common.state == GST_MATROSKA_READ_STATE_HEADER)) {
4535 if (demux->common.src->len == 0) {
4536 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
4537 ("No pads created"));
4539 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL),
4540 ("Failed to finish reading headers"));
4542 gst_element_no_more_pads (GST_ELEMENT (demux));
4545 if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
4548 /* for segment playback we need to post when (in stream time)
4549 * we stopped, this is either stop (when set) or the duration. */
4550 if ((stop = demux->common.segment.stop) == -1)
4551 stop = demux->last_stop_end;
4553 GST_LOG_OBJECT (demux, "Sending segment done, at end of segment");
4554 gst_element_post_message (GST_ELEMENT (demux),
4555 gst_message_new_segment_done (GST_OBJECT (demux), GST_FORMAT_TIME,
4557 gst_matroska_demux_send_event (demux,
4558 gst_event_new_segment_done (GST_FORMAT_TIME, stop));
4562 } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS) {
4563 /* for fatal errors we post an error message */
4564 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
4565 ("stream stopped, reason %s", reason));
4569 /* send EOS, and prevent hanging if no streams yet */
4570 GST_LOG_OBJECT (demux, "Sending EOS, at end of stream");
4571 if (!gst_matroska_demux_send_event (demux, gst_event_new_eos ()) &&
4572 (ret == GST_FLOW_EOS)) {
4573 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4574 (NULL), ("got eos but no streams (yet)"));
4582 * Create and push a flushing seek event upstream
4585 perform_seek_to_offset (GstMatroskaDemux * demux, gdouble rate, guint64 offset,
4591 GST_DEBUG_OBJECT (demux, "Seeking to %" G_GUINT64_FORMAT, offset);
4594 gst_event_new_seek (rate, GST_FORMAT_BYTES,
4595 GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, GST_SEEK_TYPE_SET, offset,
4596 GST_SEEK_TYPE_NONE, -1);
4597 gst_event_set_seqnum (event, seqnum);
4599 res = gst_pad_push_event (demux->common.sinkpad, event);
4601 /* segment event will update offset */
4605 static GstFlowReturn
4606 gst_matroska_demux_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
4608 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4610 GstFlowReturn ret = GST_FLOW_OK;
4615 if (G_UNLIKELY (GST_BUFFER_IS_DISCONT (buffer))) {
4616 GST_DEBUG_OBJECT (demux, "got DISCONT");
4617 gst_adapter_clear (demux->common.adapter);
4618 GST_OBJECT_LOCK (demux);
4619 gst_matroska_read_common_reset_streams (&demux->common,
4620 GST_CLOCK_TIME_NONE, FALSE);
4621 GST_OBJECT_UNLOCK (demux);
4624 gst_adapter_push (demux->common.adapter, buffer);
4628 available = gst_adapter_available (demux->common.adapter);
4630 ret = gst_matroska_read_common_peek_id_length_push (&demux->common,
4631 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4632 if (G_UNLIKELY (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)) {
4633 if (demux->common.ebml_segment_length != G_MAXUINT64
4634 && demux->common.offset >=
4635 demux->common.ebml_segment_start + demux->common.ebml_segment_length)
4640 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
4641 "size %" G_GUINT64_FORMAT ", needed %d, available %d",
4642 demux->common.offset, id, length, needed, available);
4644 if (needed > available)
4647 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4648 if (ret == GST_FLOW_EOS) {
4649 /* need more data */
4651 } else if (ret != GST_FLOW_OK) {
4658 gst_matroska_demux_handle_sink_event (GstPad * pad, GstObject * parent,
4661 gboolean res = TRUE;
4662 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4664 GST_DEBUG_OBJECT (demux,
4665 "have event type %s: %p on sink pad", GST_EVENT_TYPE_NAME (event), event);
4667 switch (GST_EVENT_TYPE (event)) {
4668 case GST_EVENT_SEGMENT:
4670 const GstSegment *segment;
4672 /* some debug output */
4673 gst_event_parse_segment (event, &segment);
4674 /* FIXME: do we need to update segment base here (like accum in 0.10)? */
4675 GST_DEBUG_OBJECT (demux,
4676 "received format %d segment %" GST_SEGMENT_FORMAT, segment->format,
4679 if (demux->common.state < GST_MATROSKA_READ_STATE_DATA) {
4680 GST_DEBUG_OBJECT (demux, "still starting");
4684 /* we only expect a BYTE segment, e.g. following a seek */
4685 if (segment->format != GST_FORMAT_BYTES) {
4686 GST_DEBUG_OBJECT (demux, "unsupported segment format, ignoring");
4690 GST_DEBUG_OBJECT (demux, "clearing segment state");
4691 GST_OBJECT_LOCK (demux);
4692 /* clear current segment leftover */
4693 gst_adapter_clear (demux->common.adapter);
4694 /* and some streaming setup */
4695 demux->common.offset = segment->start;
4696 /* accumulate base based on current position */
4697 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.position))
4698 demux->common.segment.base +=
4699 (MAX (demux->common.segment.position, demux->stream_start_time)
4700 - demux->stream_start_time) / fabs (demux->common.segment.rate);
4701 /* do not know where we are;
4702 * need to come across a cluster and generate segment */
4703 demux->common.segment.position = GST_CLOCK_TIME_NONE;
4704 demux->cluster_time = GST_CLOCK_TIME_NONE;
4705 demux->cluster_offset = 0;
4706 demux->need_segment = TRUE;
4707 demux->segment_seqnum = gst_event_get_seqnum (event);
4708 /* but keep some of the upstream segment */
4709 demux->common.segment.rate = segment->rate;
4710 /* also check if need to keep some of the requested seek position */
4711 if (demux->seek_offset == segment->start) {
4712 GST_DEBUG_OBJECT (demux, "position matches requested seek");
4713 demux->common.segment.position = demux->requested_seek_time;
4715 GST_DEBUG_OBJECT (demux, "unexpected segment position");
4717 demux->requested_seek_time = GST_CLOCK_TIME_NONE;
4718 demux->seek_offset = -1;
4719 GST_OBJECT_UNLOCK (demux);
4721 /* chain will send initial segment after pads have been added,
4722 * or otherwise come up with one */
4723 GST_DEBUG_OBJECT (demux, "eating event");
4724 gst_event_unref (event);
4730 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
4731 gst_event_unref (event);
4732 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4733 (NULL), ("got eos and didn't receive a complete header object"));
4734 } else if (demux->common.num_streams == 0) {
4735 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4736 (NULL), ("got eos but no streams (yet)"));
4738 gst_matroska_demux_send_event (demux, event);
4742 case GST_EVENT_FLUSH_STOP:
4746 gst_adapter_clear (demux->common.adapter);
4747 GST_OBJECT_LOCK (demux);
4748 gst_matroska_read_common_reset_streams (&demux->common,
4749 GST_CLOCK_TIME_NONE, TRUE);
4750 gst_flow_combiner_reset (demux->flowcombiner);
4751 dur = demux->common.segment.duration;
4752 gst_segment_init (&demux->common.segment, GST_FORMAT_TIME);
4753 demux->common.segment.duration = dur;
4754 demux->cluster_time = GST_CLOCK_TIME_NONE;
4755 demux->cluster_offset = 0;
4756 GST_OBJECT_UNLOCK (demux);
4760 res = gst_pad_event_default (pad, parent, event);
4768 gst_matroska_demux_sink_activate (GstPad * sinkpad, GstObject * parent)
4770 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4772 gboolean pull_mode = FALSE;
4774 query = gst_query_new_scheduling ();
4776 if (gst_pad_peer_query (sinkpad, query))
4777 pull_mode = gst_query_has_scheduling_mode_with_flags (query,
4778 GST_PAD_MODE_PULL, GST_SCHEDULING_FLAG_SEEKABLE);
4780 gst_query_unref (query);
4783 GST_DEBUG ("going to pull mode");
4784 demux->streaming = FALSE;
4785 return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PULL, TRUE);
4787 GST_DEBUG ("going to push (streaming) mode");
4788 demux->streaming = TRUE;
4789 return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PUSH, TRUE);
4794 gst_matroska_demux_sink_activate_mode (GstPad * sinkpad, GstObject * parent,
4795 GstPadMode mode, gboolean active)
4798 case GST_PAD_MODE_PULL:
4800 /* if we have a scheduler we can start the task */
4801 gst_pad_start_task (sinkpad, (GstTaskFunction) gst_matroska_demux_loop,
4804 gst_pad_stop_task (sinkpad);
4807 case GST_PAD_MODE_PUSH:
4815 gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext *
4816 videocontext, const gchar * codec_id, guint8 * data, guint size,
4817 gchar ** codec_name, guint32 * riff_fourcc)
4819 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) videocontext;
4820 GstCaps *caps = NULL;
4822 g_assert (videocontext != NULL);
4823 g_assert (codec_name != NULL);
4828 /* TODO: check if we have all codec types from matroska-ids.h
4829 * check if we have to do more special things with codec_private
4832 * GST_MATROSKA_CODEC_ID_VIDEO_QUICKTIME
4833 * GST_MATROSKA_CODEC_ID_VIDEO_SNOW
4836 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VFW_FOURCC)) {
4837 gst_riff_strf_vids *vids = NULL;
4840 GstBuffer *buf = NULL;
4842 vids = (gst_riff_strf_vids *) data;
4844 /* assure size is big enough */
4846 GST_WARNING ("Too small BITMAPINFOHEADER (%d bytes)", size);
4849 if (size < sizeof (gst_riff_strf_vids)) {
4850 vids = g_new (gst_riff_strf_vids, 1);
4851 memcpy (vids, data, size);
4854 context->dts_only = TRUE; /* VFW files only store DTS */
4856 /* little-endian -> byte-order */
4857 vids->size = GUINT32_FROM_LE (vids->size);
4858 vids->width = GUINT32_FROM_LE (vids->width);
4859 vids->height = GUINT32_FROM_LE (vids->height);
4860 vids->planes = GUINT16_FROM_LE (vids->planes);
4861 vids->bit_cnt = GUINT16_FROM_LE (vids->bit_cnt);
4862 vids->compression = GUINT32_FROM_LE (vids->compression);
4863 vids->image_size = GUINT32_FROM_LE (vids->image_size);
4864 vids->xpels_meter = GUINT32_FROM_LE (vids->xpels_meter);
4865 vids->ypels_meter = GUINT32_FROM_LE (vids->ypels_meter);
4866 vids->num_colors = GUINT32_FROM_LE (vids->num_colors);
4867 vids->imp_colors = GUINT32_FROM_LE (vids->imp_colors);
4869 if (size > sizeof (gst_riff_strf_vids)) { /* some extra_data */
4870 gsize offset = sizeof (gst_riff_strf_vids);
4873 gst_buffer_new_wrapped (g_memdup ((guint8 *) vids + offset,
4874 size - offset), size - offset);
4878 *riff_fourcc = vids->compression;
4880 caps = gst_riff_create_video_caps (vids->compression, NULL, vids,
4881 buf, NULL, codec_name);
4884 GST_WARNING ("Unhandled RIFF fourcc %" GST_FOURCC_FORMAT,
4885 GST_FOURCC_ARGS (vids->compression));
4887 static GstStaticCaps intra_caps = GST_STATIC_CAPS ("image/jpeg; "
4888 "video/x-raw; image/png; video/x-dv; video/x-huffyuv; video/x-ffv; "
4889 "video/x-compressed-yuv");
4890 context->intra_only =
4891 gst_caps_can_intersect (gst_static_caps_get (&intra_caps), caps);
4895 gst_buffer_unref (buf);
4897 if (vids != (gst_riff_strf_vids *) data)
4900 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_UNCOMPRESSED)) {
4902 GstVideoFormat format;
4904 gst_video_info_init (&info);
4905 switch (videocontext->fourcc) {
4906 case GST_MAKE_FOURCC ('I', '4', '2', '0'):
4907 format = GST_VIDEO_FORMAT_I420;
4909 case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
4910 format = GST_VIDEO_FORMAT_YUY2;
4912 case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
4913 format = GST_VIDEO_FORMAT_YV12;
4915 case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
4916 format = GST_VIDEO_FORMAT_UYVY;
4918 case GST_MAKE_FOURCC ('A', 'Y', 'U', 'V'):
4919 format = GST_VIDEO_FORMAT_AYUV;
4921 case GST_MAKE_FOURCC ('Y', '8', '0', '0'):
4922 case GST_MAKE_FOURCC ('Y', '8', ' ', ' '):
4923 format = GST_VIDEO_FORMAT_GRAY8;
4925 case GST_MAKE_FOURCC ('R', 'G', 'B', 24):
4926 format = GST_VIDEO_FORMAT_RGB;
4928 case GST_MAKE_FOURCC ('B', 'G', 'R', 24):
4929 format = GST_VIDEO_FORMAT_BGR;
4932 GST_DEBUG ("Unknown fourcc %" GST_FOURCC_FORMAT,
4933 GST_FOURCC_ARGS (videocontext->fourcc));
4937 context->intra_only = TRUE;
4939 gst_video_info_set_format (&info, format, videocontext->pixel_width,
4940 videocontext->pixel_height);
4941 caps = gst_video_info_to_caps (&info);
4942 *codec_name = gst_pb_utils_get_codec_description (caps);
4943 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_SP)) {
4944 caps = gst_caps_new_simple ("video/x-divx",
4945 "divxversion", G_TYPE_INT, 4, NULL);
4946 *codec_name = g_strdup ("MPEG-4 simple profile");
4947 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP) ||
4948 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AP)) {
4949 caps = gst_caps_new_simple ("video/mpeg",
4950 "mpegversion", G_TYPE_INT, 4,
4951 "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
4955 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
4956 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
4957 gst_buffer_unref (priv);
4959 gst_codec_utils_mpeg4video_caps_set_level_and_profile (caps, data, size);
4961 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP))
4962 *codec_name = g_strdup ("MPEG-4 advanced simple profile");
4964 *codec_name = g_strdup ("MPEG-4 advanced profile");
4965 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MSMPEG4V3)) {
4967 caps = gst_caps_new_full (gst_structure_new ("video/x-divx",
4968 "divxversion", G_TYPE_INT, 3, NULL),
4969 gst_structure_new ("video/x-msmpeg",
4970 "msmpegversion", G_TYPE_INT, 43, NULL), NULL);
4972 caps = gst_caps_new_simple ("video/x-msmpeg",
4973 "msmpegversion", G_TYPE_INT, 43, NULL);
4974 *codec_name = g_strdup ("Microsoft MPEG-4 v.3");
4975 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1) ||
4976 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG2)) {
4979 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1))
4984 caps = gst_caps_new_simple ("video/mpeg",
4985 "systemstream", G_TYPE_BOOLEAN, FALSE,
4986 "mpegversion", G_TYPE_INT, mpegversion, NULL);
4987 *codec_name = g_strdup_printf ("MPEG-%d video", mpegversion);
4988 context->postprocess_frame = gst_matroska_demux_add_mpeg_seq_header;
4989 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MJPEG)) {
4990 caps = gst_caps_new_empty_simple ("image/jpeg");
4991 *codec_name = g_strdup ("Motion-JPEG");
4992 context->intra_only = TRUE;
4993 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AVC)) {
4994 caps = gst_caps_new_empty_simple ("video/x-h264");
4998 /* First byte is the version, second is the profile indication, and third
4999 * is the 5 contraint_set_flags and 3 reserved bits. Fourth byte is the
5000 * level indication. */
5001 gst_codec_utils_h264_caps_set_level_and_profile (caps, data + 1,
5004 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
5005 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5006 gst_buffer_unref (priv);
5008 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "avc",
5009 "alignment", G_TYPE_STRING, "au", NULL);
5011 GST_WARNING ("No codec data found, assuming output is byte-stream");
5012 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
5015 *codec_name = g_strdup ("H264");
5016 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEGH_HEVC)) {
5017 caps = gst_caps_new_empty_simple ("video/x-h265");
5021 gst_codec_utils_h265_caps_set_level_tier_and_profile (caps, data + 1,
5024 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
5025 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5026 gst_buffer_unref (priv);
5028 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "hvc1",
5029 "alignment", G_TYPE_STRING, "au", NULL);
5031 GST_WARNING ("No codec data found, assuming output is byte-stream");
5032 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
5035 *codec_name = g_strdup ("HEVC");
5036 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1)) ||
5037 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2)) ||
5038 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3)) ||
5039 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))) {
5040 gint rmversion = -1;
5042 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1))
5044 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2))
5046 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3))
5048 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))
5051 caps = gst_caps_new_simple ("video/x-pn-realvideo",
5052 "rmversion", G_TYPE_INT, rmversion, NULL);
5053 GST_DEBUG ("data:%p, size:0x%x", data, size);
5054 /* We need to extract the extradata ! */
5055 if (data && (size >= 0x22)) {
5060 subformat = GST_READ_UINT32_BE (data + 0x1a);
5061 rformat = GST_READ_UINT32_BE (data + 0x1e);
5064 gst_buffer_new_wrapped (g_memdup (data + 0x1a, size - 0x1a),
5066 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, "format",
5067 G_TYPE_INT, rformat, "subformat", G_TYPE_INT, subformat, NULL);
5068 gst_buffer_unref (priv);
5071 *codec_name = g_strdup_printf ("RealVideo %d.0", rmversion);
5072 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_THEORA)) {
5073 caps = gst_caps_new_empty_simple ("video/x-theora");
5074 context->stream_headers =
5075 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
5076 context->codec_priv_size);
5077 /* FIXME: mark stream as broken and skip if there are no stream headers */
5078 context->send_stream_headers = TRUE;
5079 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_DIRAC)) {
5080 caps = gst_caps_new_empty_simple ("video/x-dirac");
5081 *codec_name = g_strdup_printf ("Dirac");
5082 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8)) {
5083 caps = gst_caps_new_empty_simple ("video/x-vp8");
5084 *codec_name = g_strdup_printf ("On2 VP8");
5085 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP9)) {
5086 caps = gst_caps_new_empty_simple ("video/x-vp9");
5087 *codec_name = g_strdup_printf ("On2 VP9");
5089 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
5095 GstStructure *structure;
5097 for (i = 0; i < gst_caps_get_size (caps); i++) {
5098 structure = gst_caps_get_structure (caps, i);
5100 /* FIXME: use the real unit here! */
5101 GST_DEBUG ("video size %dx%d, target display size %dx%d (any unit)",
5102 videocontext->pixel_width,
5103 videocontext->pixel_height,
5104 videocontext->display_width, videocontext->display_height);
5106 /* pixel width and height are the w and h of the video in pixels */
5107 if (videocontext->pixel_width > 0 && videocontext->pixel_height > 0) {
5108 gint w = videocontext->pixel_width;
5109 gint h = videocontext->pixel_height;
5111 gst_structure_set (structure,
5112 "width", G_TYPE_INT, w, "height", G_TYPE_INT, h, NULL);
5115 if (videocontext->display_width > 0 || videocontext->display_height > 0) {
5118 if (videocontext->display_width <= 0)
5119 videocontext->display_width = videocontext->pixel_width;
5120 if (videocontext->display_height <= 0)
5121 videocontext->display_height = videocontext->pixel_height;
5123 /* calculate the pixel aspect ratio using the display and pixel w/h */
5124 n = videocontext->display_width * videocontext->pixel_height;
5125 d = videocontext->display_height * videocontext->pixel_width;
5126 GST_DEBUG ("setting PAR to %d/%d", n, d);
5127 gst_structure_set (structure, "pixel-aspect-ratio",
5129 videocontext->display_width * videocontext->pixel_height,
5130 videocontext->display_height * videocontext->pixel_width, NULL);
5133 if (videocontext->default_fps > 0.0) {
5136 gst_util_double_to_fraction (videocontext->default_fps, &fps_n, &fps_d);
5138 GST_DEBUG ("using default fps %d/%d", fps_n, fps_d);
5140 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION, fps_n,
5142 } else if (context->default_duration > 0) {
5145 gst_video_guess_framerate (context->default_duration, &fps_n, &fps_d);
5147 GST_INFO ("using default duration %" G_GUINT64_FORMAT
5148 " framerate %d/%d", context->default_duration, fps_n, fps_d);
5150 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
5151 fps_n, fps_d, NULL);
5153 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
5157 if (videocontext->parent.flags & GST_MATROSKA_VIDEOTRACK_INTERLACED)
5158 gst_structure_set (structure, "interlace-mode", G_TYPE_STRING,
5162 caps = gst_caps_simplify (caps);
5169 * Some AAC specific code... *sigh*
5170 * FIXME: maybe we should use '15' and code the sample rate explicitly
5171 * if the sample rate doesn't match the predefined rates exactly? (tpm)
5175 aac_rate_idx (gint rate)
5179 else if (75132 <= rate)
5181 else if (55426 <= rate)
5183 else if (46009 <= rate)
5185 else if (37566 <= rate)
5187 else if (27713 <= rate)
5189 else if (23004 <= rate)
5191 else if (18783 <= rate)
5193 else if (13856 <= rate)
5195 else if (11502 <= rate)
5197 else if (9391 <= rate)
5204 aac_profile_idx (const gchar * codec_id)
5208 if (strlen (codec_id) <= 12)
5210 else if (!strncmp (&codec_id[12], "MAIN", 4))
5212 else if (!strncmp (&codec_id[12], "LC", 2))
5214 else if (!strncmp (&codec_id[12], "SSR", 3))
5223 round_up_pow2 (guint n)
5234 #define AAC_SYNC_EXTENSION_TYPE 0x02b7
5237 gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext *
5238 audiocontext, const gchar * codec_id, guint8 * data, guint size,
5239 gchar ** codec_name, guint16 * riff_audio_fmt)
5241 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) audiocontext;
5242 GstCaps *caps = NULL;
5244 g_assert (audiocontext != NULL);
5245 g_assert (codec_name != NULL);
5248 *riff_audio_fmt = 0;
5250 /* TODO: check if we have all codec types from matroska-ids.h
5251 * check if we have to do more special things with codec_private
5252 * check if we need bitdepth in different places too
5253 * implement channel position magic
5255 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID9
5256 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID10
5257 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDMC
5258 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDM2
5261 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1) ||
5262 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2) ||
5263 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L3)) {
5266 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1))
5268 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2))
5273 caps = gst_caps_new_simple ("audio/mpeg",
5274 "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, layer, NULL);
5275 *codec_name = g_strdup_printf ("MPEG-1 layer %d", layer);
5276 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE) ||
5277 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_LE)) {
5280 GstAudioFormat format;
5282 sign = (audiocontext->bitdepth != 8);
5283 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE))
5284 endianness = G_BIG_ENDIAN;
5286 endianness = G_LITTLE_ENDIAN;
5288 format = gst_audio_format_build_integer (sign, endianness,
5289 audiocontext->bitdepth, audiocontext->bitdepth);
5291 /* FIXME: Channel mask and reordering */
5292 caps = gst_caps_new_simple ("audio/x-raw",
5293 "format", G_TYPE_STRING, gst_audio_format_to_string (format),
5294 "layout", G_TYPE_STRING, "interleaved", NULL);
5296 *codec_name = g_strdup_printf ("Raw %d-bit PCM audio",
5297 audiocontext->bitdepth);
5298 context->alignment = GST_ROUND_UP_8 (audiocontext->bitdepth) / 8;
5299 context->alignment = round_up_pow2 (context->alignment);
5300 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_FLOAT)) {
5301 const gchar *format;
5302 if (audiocontext->bitdepth == 32)
5306 /* FIXME: Channel mask and reordering */
5307 caps = gst_caps_new_simple ("audio/x-raw",
5308 "format", G_TYPE_STRING, format,
5309 "layout", G_TYPE_STRING, "interleaved", NULL);
5310 *codec_name = g_strdup_printf ("Raw %d-bit floating-point audio",
5311 audiocontext->bitdepth);
5312 context->alignment = audiocontext->bitdepth / 8;
5313 context->alignment = round_up_pow2 (context->alignment);
5314 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AC3,
5315 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AC3))) {
5316 caps = gst_caps_new_simple ("audio/x-ac3",
5317 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5318 *codec_name = g_strdup ("AC-3 audio");
5319 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_EAC3,
5320 strlen (GST_MATROSKA_CODEC_ID_AUDIO_EAC3))) {
5321 caps = gst_caps_new_simple ("audio/x-eac3",
5322 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5323 *codec_name = g_strdup ("E-AC-3 audio");
5324 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TRUEHD,
5325 strlen (GST_MATROSKA_CODEC_ID_AUDIO_TRUEHD))) {
5326 caps = gst_caps_new_empty_simple ("audio/x-true-hd");
5327 *codec_name = g_strdup ("Dolby TrueHD");
5328 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_DTS)) {
5329 caps = gst_caps_new_empty_simple ("audio/x-dts");
5330 *codec_name = g_strdup ("DTS audio");
5331 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_VORBIS)) {
5332 caps = gst_caps_new_empty_simple ("audio/x-vorbis");
5333 context->stream_headers =
5334 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
5335 context->codec_priv_size);
5336 /* FIXME: mark stream as broken and skip if there are no stream headers */
5337 context->send_stream_headers = TRUE;
5338 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_FLAC)) {
5339 caps = gst_caps_new_empty_simple ("audio/x-flac");
5340 context->stream_headers =
5341 gst_matroska_parse_flac_stream_headers (context->codec_priv,
5342 context->codec_priv_size);
5343 /* FIXME: mark stream as broken and skip if there are no stream headers */
5344 context->send_stream_headers = TRUE;
5345 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_SPEEX)) {
5346 caps = gst_caps_new_empty_simple ("audio/x-speex");
5347 context->stream_headers =
5348 gst_matroska_parse_speex_stream_headers (context->codec_priv,
5349 context->codec_priv_size);
5350 /* FIXME: mark stream as broken and skip if there are no stream headers */
5351 context->send_stream_headers = TRUE;
5352 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_OPUS)) {
5353 caps = gst_caps_new_empty_simple ("audio/x-opus");
5354 *codec_name = g_strdup ("Opus");
5355 context->stream_headers =
5356 gst_matroska_parse_opus_stream_headers (context->codec_priv,
5357 context->codec_priv_size);
5358 if (context->stream_headers) {
5359 /* There was a valid header. Multistream headers are more than
5360 * 19 bytes, as they include an extra channel mapping table. */
5361 gboolean multistream = (context->codec_priv_size > 19);
5362 gst_caps_set_simple (caps, "multistream", G_TYPE_BOOLEAN, multistream,
5365 /* FIXME: mark stream as broken and skip if there are no stream headers */
5366 context->send_stream_headers = TRUE;
5367 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_ACM)) {
5368 gst_riff_strf_auds auds;
5370 if (data && size >= 18) {
5371 GstBuffer *codec_data = NULL;
5373 /* little-endian -> byte-order */
5374 auds.format = GST_READ_UINT16_LE (data);
5375 auds.channels = GST_READ_UINT16_LE (data + 2);
5376 auds.rate = GST_READ_UINT32_LE (data + 4);
5377 auds.av_bps = GST_READ_UINT32_LE (data + 8);
5378 auds.blockalign = GST_READ_UINT16_LE (data + 12);
5379 auds.bits_per_sample = GST_READ_UINT16_LE (data + 16);
5381 /* 18 is the waveformatex size */
5383 codec_data = gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY,
5384 data + 18, size - 18, 0, size - 18, NULL, NULL);
5388 *riff_audio_fmt = auds.format;
5390 /* FIXME: Handle reorder map */
5391 caps = gst_riff_create_audio_caps (auds.format, NULL, &auds, NULL,
5392 codec_data, codec_name, NULL);
5394 gst_buffer_unref (codec_data);
5397 GST_WARNING ("Unhandled RIFF audio format 0x%02x", auds.format);
5400 GST_WARNING ("Invalid codec data size (%d expected, got %d)", 18, size);
5402 } else if (g_str_has_prefix (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC)) {
5403 GstBuffer *priv = NULL;
5405 gint rate_idx, profile;
5406 guint8 *data = NULL;
5408 /* unspecified AAC profile with opaque private codec data */
5409 if (strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC) == 0) {
5410 if (context->codec_priv_size >= 2) {
5411 guint obj_type, freq_index, explicit_freq_bytes = 0;
5413 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
5415 freq_index = (GST_READ_UINT16_BE (context->codec_priv) & 0x780) >> 7;
5416 obj_type = (GST_READ_UINT16_BE (context->codec_priv) & 0xF800) >> 11;
5417 if (freq_index == 15)
5418 explicit_freq_bytes = 3;
5419 GST_DEBUG ("obj_type = %u, freq_index = %u", obj_type, freq_index);
5420 priv = gst_buffer_new_wrapped (g_memdup (context->codec_priv,
5421 context->codec_priv_size), context->codec_priv_size);
5422 /* assume SBR if samplerate <= 24kHz */
5423 if (obj_type == 5 || (freq_index >= 6 && freq_index != 15) ||
5424 (context->codec_priv_size == (5 + explicit_freq_bytes))) {
5425 audiocontext->samplerate *= 2;
5428 GST_WARNING ("Opaque A_AAC codec ID, but no codec private data");
5429 /* this is pretty broken;
5430 * maybe we need to make up some default private,
5431 * or maybe ADTS data got dumped in.
5432 * Let's set up some private data now, and check actual data later */
5433 /* just try this and see what happens ... */
5434 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
5435 context->postprocess_frame = gst_matroska_demux_check_aac;
5439 /* make up decoder-specific data if it is not supplied */
5443 priv = gst_buffer_new_allocate (NULL, 5, NULL);
5444 gst_buffer_map (priv, &map, GST_MAP_WRITE);
5446 rate_idx = aac_rate_idx (audiocontext->samplerate);
5447 profile = aac_profile_idx (codec_id);
5449 data[0] = ((profile + 1) << 3) | ((rate_idx & 0xE) >> 1);
5450 data[1] = ((rate_idx & 0x1) << 7) | (audiocontext->channels << 3);
5452 if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2,
5453 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2))) {
5455 gst_buffer_unmap (priv, &map);
5456 gst_buffer_set_size (priv, 2);
5457 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4,
5458 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4))) {
5461 if (g_strrstr (codec_id, "SBR")) {
5462 /* HE-AAC (aka SBR AAC) */
5463 audiocontext->samplerate *= 2;
5464 rate_idx = aac_rate_idx (audiocontext->samplerate);
5465 data[2] = AAC_SYNC_EXTENSION_TYPE >> 3;
5466 data[3] = ((AAC_SYNC_EXTENSION_TYPE & 0x07) << 5) | 5;
5467 data[4] = (1 << 7) | (rate_idx << 3);
5468 gst_buffer_unmap (priv, &map);
5470 gst_buffer_unmap (priv, &map);
5471 gst_buffer_set_size (priv, 2);
5474 gst_buffer_unmap (priv, &map);
5475 gst_buffer_unref (priv);
5477 GST_ERROR ("Unknown AAC profile and no codec private data");
5482 caps = gst_caps_new_simple ("audio/mpeg",
5483 "mpegversion", G_TYPE_INT, mpegversion,
5484 "framed", G_TYPE_BOOLEAN, TRUE,
5485 "stream-format", G_TYPE_STRING, "raw", NULL);
5486 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5487 if (context->codec_priv && context->codec_priv_size > 0)
5488 gst_codec_utils_aac_caps_set_level_and_profile (caps,
5489 context->codec_priv, context->codec_priv_size);
5490 *codec_name = g_strdup_printf ("MPEG-%d AAC audio", mpegversion);
5491 gst_buffer_unref (priv);
5493 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TTA)) {
5494 caps = gst_caps_new_simple ("audio/x-tta",
5495 "width", G_TYPE_INT, audiocontext->bitdepth, NULL);
5496 *codec_name = g_strdup ("TTA audio");
5497 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_WAVPACK4)) {
5498 caps = gst_caps_new_simple ("audio/x-wavpack",
5499 "width", G_TYPE_INT, audiocontext->bitdepth,
5500 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5501 *codec_name = g_strdup ("Wavpack audio");
5502 context->postprocess_frame = gst_matroska_demux_add_wvpk_header;
5503 audiocontext->wvpk_block_index = 0;
5504 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4)) ||
5505 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_28_8)) ||
5506 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))) {
5507 gint raversion = -1;
5509 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4))
5511 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))
5516 caps = gst_caps_new_simple ("audio/x-pn-realaudio",
5517 "raversion", G_TYPE_INT, raversion, NULL);
5518 /* Extract extra information from caps, mapping varies based on codec */
5519 if (data && (size >= 0x50)) {
5526 guint extra_data_size;
5528 GST_ERROR ("real audio raversion:%d", raversion);
5529 if (raversion == 8) {
5531 flavor = GST_READ_UINT16_BE (data + 22);
5532 packet_size = GST_READ_UINT32_BE (data + 24);
5533 height = GST_READ_UINT16_BE (data + 40);
5534 leaf_size = GST_READ_UINT16_BE (data + 44);
5535 sample_width = GST_READ_UINT16_BE (data + 58);
5536 extra_data_size = GST_READ_UINT32_BE (data + 74);
5539 ("flavor:%d, packet_size:%d, height:%d, leaf_size:%d, sample_width:%d, extra_data_size:%d",
5540 flavor, packet_size, height, leaf_size, sample_width,
5542 gst_caps_set_simple (caps, "flavor", G_TYPE_INT, flavor, "packet_size",
5543 G_TYPE_INT, packet_size, "height", G_TYPE_INT, height, "leaf_size",
5544 G_TYPE_INT, leaf_size, "width", G_TYPE_INT, sample_width, NULL);
5546 if ((size - 78) >= extra_data_size) {
5547 priv = gst_buffer_new_wrapped (g_memdup (data + 78, extra_data_size),
5549 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5550 gst_buffer_unref (priv);
5555 *codec_name = g_strdup_printf ("RealAudio %d.0", raversion);
5556 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_SIPR)) {
5557 caps = gst_caps_new_empty_simple ("audio/x-sipro");
5558 *codec_name = g_strdup ("Sipro/ACELP.NET Voice Codec");
5559 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_RALF)) {
5560 caps = gst_caps_new_empty_simple ("audio/x-ralf-mpeg4-generic");
5561 *codec_name = g_strdup ("Real Audio Lossless");
5562 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_ATRC)) {
5563 caps = gst_caps_new_empty_simple ("audio/x-vnd.sony.atrac3");
5564 *codec_name = g_strdup ("Sony ATRAC3");
5566 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
5571 if (audiocontext->samplerate > 0 && audiocontext->channels > 0) {
5574 for (i = 0; i < gst_caps_get_size (caps); i++) {
5575 gst_structure_set (gst_caps_get_structure (caps, i),
5576 "channels", G_TYPE_INT, audiocontext->channels,
5577 "rate", G_TYPE_INT, audiocontext->samplerate, NULL);
5581 caps = gst_caps_simplify (caps);
5588 gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
5589 subtitlecontext, const gchar * codec_id, gpointer data, guint size)
5591 GstCaps *caps = NULL;
5592 GstMatroskaTrackContext *context =
5593 (GstMatroskaTrackContext *) subtitlecontext;
5595 /* for backwards compatibility */
5596 if (!g_ascii_strcasecmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASCII))
5597 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8;
5598 else if (!g_ascii_strcasecmp (codec_id, "S_SSA"))
5599 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_SSA;
5600 else if (!g_ascii_strcasecmp (codec_id, "S_ASS"))
5601 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_ASS;
5602 else if (!g_ascii_strcasecmp (codec_id, "S_USF"))
5603 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_USF;
5605 /* TODO: Add GST_MATROSKA_CODEC_ID_SUBTITLE_BMP support
5606 * Check if we have to do something with codec_private */
5607 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8)) {
5608 /* well, plain text simply does not have a lot of markup ... */
5609 caps = gst_caps_new_simple ("text/x-raw", "format", G_TYPE_STRING,
5610 "pango-markup", NULL);
5611 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5612 subtitlecontext->check_markup = TRUE;
5613 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_SSA)) {
5614 caps = gst_caps_new_empty_simple ("application/x-ssa");
5615 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5616 subtitlecontext->check_markup = FALSE;
5617 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASS)) {
5618 caps = gst_caps_new_empty_simple ("application/x-ass");
5619 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5620 subtitlecontext->check_markup = FALSE;
5621 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_USF)) {
5622 caps = gst_caps_new_empty_simple ("application/x-usf");
5623 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5624 subtitlecontext->check_markup = FALSE;
5625 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB)) {
5626 caps = gst_caps_new_empty_simple ("subpicture/x-dvd");
5627 ((GstMatroskaTrackContext *) subtitlecontext)->send_dvd_event = TRUE;
5628 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_HDMVPGS)) {
5629 caps = gst_caps_new_empty_simple ("subpicture/x-pgs");
5630 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_KATE)) {
5631 caps = gst_caps_new_empty_simple ("subtitle/x-kate");
5632 context->stream_headers =
5633 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
5634 context->codec_priv_size);
5635 /* FIXME: mark stream as broken and skip if there are no stream headers */
5636 context->send_stream_headers = TRUE;
5638 GST_DEBUG ("Unknown subtitle stream: codec_id='%s'", codec_id);
5639 caps = gst_caps_new_empty_simple ("application/x-subtitle-unknown");
5642 if (data != NULL && size > 0) {
5645 buf = gst_buffer_new_wrapped (g_memdup (data, size), size);
5646 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, buf, NULL);
5647 gst_buffer_unref (buf);
5655 gst_matroska_demux_set_index (GstElement * element, GstIndex * index)
5657 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5659 GST_OBJECT_LOCK (demux);
5660 if (demux->common.element_index)
5661 gst_object_unref (demux->common.element_index);
5662 demux->common.element_index = index ? gst_object_ref (index) : NULL;
5663 GST_OBJECT_UNLOCK (demux);
5664 GST_DEBUG_OBJECT (demux, "Set index %" GST_PTR_FORMAT,
5665 demux->common.element_index);
5669 gst_matroska_demux_get_index (GstElement * element)
5671 GstIndex *result = NULL;
5672 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5674 GST_OBJECT_LOCK (demux);
5675 if (demux->common.element_index)
5676 result = gst_object_ref (demux->common.element_index);
5677 GST_OBJECT_UNLOCK (demux);
5679 GST_DEBUG_OBJECT (demux, "Returning index %" GST_PTR_FORMAT, result);
5685 static GstStateChangeReturn
5686 gst_matroska_demux_change_state (GstElement * element,
5687 GstStateChange transition)
5689 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5690 GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
5692 /* handle upwards state changes here */
5693 switch (transition) {
5698 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
5700 /* handle downwards state changes */
5701 switch (transition) {
5702 case GST_STATE_CHANGE_PAUSED_TO_READY:
5703 gst_matroska_demux_reset (GST_ELEMENT (demux));
5713 gst_matroska_demux_set_property (GObject * object,
5714 guint prop_id, const GValue * value, GParamSpec * pspec)
5716 GstMatroskaDemux *demux;
5718 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
5719 demux = GST_MATROSKA_DEMUX (object);
5722 case ARG_MAX_GAP_TIME:
5723 GST_OBJECT_LOCK (demux);
5724 demux->max_gap_time = g_value_get_uint64 (value);
5725 GST_OBJECT_UNLOCK (demux);
5728 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
5734 gst_matroska_demux_get_property (GObject * object,
5735 guint prop_id, GValue * value, GParamSpec * pspec)
5737 GstMatroskaDemux *demux;
5739 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
5740 demux = GST_MATROSKA_DEMUX (object);
5743 case ARG_MAX_GAP_TIME:
5744 GST_OBJECT_LOCK (demux);
5745 g_value_set_uint64 (value, demux->max_gap_time);
5746 GST_OBJECT_UNLOCK (demux);
5749 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
5755 gst_matroska_demux_plugin_init (GstPlugin * plugin)
5759 /* parser helper separate debug */
5760 GST_DEBUG_CATEGORY_INIT (ebmlread_debug, "ebmlread",
5761 0, "EBML stream helper class");
5763 /* create an elementfactory for the matroska_demux element */
5764 if (!gst_element_register (plugin, "matroskademux",
5765 GST_RANK_PRIMARY, GST_TYPE_MATROSKA_DEMUX))