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, PROP_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));
734 case GST_MATROSKA_ID_VIDEOSTEREOMODE:
738 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
741 GST_DEBUG_OBJECT (demux, "StereoMode: %" G_GUINT64_FORMAT, num);
744 case GST_MATROSKA_STEREO_MODE_SBS_RL:
745 videocontext->multiview_flags =
746 GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST;
748 case GST_MATROSKA_STEREO_MODE_SBS_LR:
749 videocontext->multiview_mode =
750 GST_VIDEO_MULTIVIEW_MODE_SIDE_BY_SIDE;
752 case GST_MATROSKA_STEREO_MODE_TB_RL:
753 videocontext->multiview_flags =
754 GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST;
756 case GST_MATROSKA_STEREO_MODE_TB_LR:
757 videocontext->multiview_mode =
758 GST_VIDEO_MULTIVIEW_MODE_TOP_BOTTOM;
760 case GST_MATROSKA_STEREO_MODE_CHECKER_RL:
761 videocontext->multiview_flags =
762 GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST;
764 case GST_MATROSKA_STEREO_MODE_CHECKER_LR:
765 videocontext->multiview_mode =
766 GST_VIDEO_MULTIVIEW_MODE_CHECKERBOARD;
768 case GST_MATROSKA_STEREO_MODE_FBF_RL:
769 videocontext->multiview_flags =
770 GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST;
772 case GST_MATROSKA_STEREO_MODE_FBF_LR:
773 videocontext->multiview_mode =
774 GST_VIDEO_MULTIVIEW_MODE_FRAME_BY_FRAME;
775 /* FIXME: In frame-by-frame mode, left/right frame buffers are
776 * laced within one block, and we'll need to apply FIRST_IN_BUNDLE
777 * accordingly. See http://www.matroska.org/technical/specs/index.html#StereoMode */
778 GST_FIXME_OBJECT (demux,
779 "Frame-by-frame stereoscopic mode not fully implemented");
786 GST_WARNING_OBJECT (demux,
787 "Unknown TrackVideo subelement 0x%x - ignoring", id);
789 case GST_MATROSKA_ID_VIDEODISPLAYUNIT:
790 case GST_MATROSKA_ID_VIDEOPIXELCROPBOTTOM:
791 case GST_MATROSKA_ID_VIDEOPIXELCROPTOP:
792 case GST_MATROSKA_ID_VIDEOPIXELCROPLEFT:
793 case GST_MATROSKA_ID_VIDEOPIXELCROPRIGHT:
794 case GST_MATROSKA_ID_VIDEOGAMMAVALUE:
795 ret = gst_ebml_read_skip (ebml);
800 DEBUG_ELEMENT_STOP (demux, ebml, "TrackVideo", ret);
804 /* tracktype specific stuff for audio */
805 case GST_MATROSKA_ID_TRACKAUDIO:{
806 GstMatroskaTrackAudioContext *audiocontext;
808 DEBUG_ELEMENT_START (demux, ebml, "TrackAudio");
810 if (!gst_matroska_track_init_audio_context (&context)) {
811 GST_WARNING_OBJECT (demux,
812 "TrackAudio element in non-audio track - ignoring track");
813 ret = GST_FLOW_ERROR;
817 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
820 audiocontext = (GstMatroskaTrackAudioContext *) context;
821 g_ptr_array_index (demux->common.src, demux->common.num_streams - 1)
824 while (ret == GST_FLOW_OK &&
825 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
826 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
831 case GST_MATROSKA_ID_AUDIOSAMPLINGFREQ:{
834 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
839 GST_WARNING_OBJECT (demux,
840 "Invalid TrackAudioSamplingFrequency %lf", num);
844 GST_DEBUG_OBJECT (demux, "TrackAudioSamplingFrequency: %lf", num);
845 audiocontext->samplerate = num;
850 case GST_MATROSKA_ID_AUDIOBITDEPTH:{
853 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
857 GST_WARNING_OBJECT (demux, "Invalid TrackAudioBitDepth 0");
861 GST_DEBUG_OBJECT (demux, "TrackAudioBitDepth: %" G_GUINT64_FORMAT,
863 audiocontext->bitdepth = num;
868 case GST_MATROSKA_ID_AUDIOCHANNELS:{
871 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
875 GST_WARNING_OBJECT (demux, "Invalid TrackAudioChannels 0");
879 GST_DEBUG_OBJECT (demux, "TrackAudioChannels: %" G_GUINT64_FORMAT,
881 audiocontext->channels = num;
886 GST_WARNING_OBJECT (demux,
887 "Unknown TrackAudio subelement 0x%x - ignoring", id);
889 case GST_MATROSKA_ID_AUDIOCHANNELPOSITIONS:
890 case GST_MATROSKA_ID_AUDIOOUTPUTSAMPLINGFREQ:
891 ret = gst_ebml_read_skip (ebml);
896 DEBUG_ELEMENT_STOP (demux, ebml, "TrackAudio", ret);
901 /* codec identifier */
902 case GST_MATROSKA_ID_CODECID:{
905 if ((ret = gst_ebml_read_ascii (ebml, &id, &text)) != GST_FLOW_OK)
908 GST_DEBUG_OBJECT (demux, "CodecID: %s", GST_STR_NULL (text));
909 context->codec_id = text;
913 /* codec private data */
914 case GST_MATROSKA_ID_CODECPRIVATE:{
919 gst_ebml_read_binary (ebml, &id, &data, &size)) != GST_FLOW_OK)
922 context->codec_priv = data;
923 context->codec_priv_size = size;
925 GST_DEBUG_OBJECT (demux, "CodecPrivate of size %" G_GUINT64_FORMAT,
930 /* name of the codec */
931 case GST_MATROSKA_ID_CODECNAME:{
934 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
937 GST_DEBUG_OBJECT (demux, "CodecName: %s", GST_STR_NULL (text));
938 context->codec_name = text;
942 /* name of this track */
943 case GST_MATROSKA_ID_TRACKNAME:{
946 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
949 context->name = text;
950 GST_DEBUG_OBJECT (demux, "TrackName: %s", GST_STR_NULL (text));
954 /* language (matters for audio/subtitles, mostly) */
955 case GST_MATROSKA_ID_TRACKLANGUAGE:{
958 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
962 context->language = text;
965 if (strlen (context->language) >= 4 && context->language[3] == '-')
966 context->language[3] = '\0';
968 GST_DEBUG_OBJECT (demux, "TrackLanguage: %s",
969 GST_STR_NULL (context->language));
973 /* whether this is actually used */
974 case GST_MATROSKA_ID_TRACKFLAGENABLED:{
977 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
981 context->flags |= GST_MATROSKA_TRACK_ENABLED;
983 context->flags &= ~GST_MATROSKA_TRACK_ENABLED;
985 GST_DEBUG_OBJECT (demux, "TrackEnabled: %d",
986 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
990 /* whether it's the default for this track type */
991 case GST_MATROSKA_ID_TRACKFLAGDEFAULT:{
994 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
998 context->flags |= GST_MATROSKA_TRACK_DEFAULT;
1000 context->flags &= ~GST_MATROSKA_TRACK_DEFAULT;
1002 GST_DEBUG_OBJECT (demux, "TrackDefault: %d",
1003 (context->flags & GST_MATROSKA_TRACK_DEFAULT) ? 1 : 0);
1007 /* whether the track must be used during playback */
1008 case GST_MATROSKA_ID_TRACKFLAGFORCED:{
1011 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1015 context->flags |= GST_MATROSKA_TRACK_FORCED;
1017 context->flags &= ~GST_MATROSKA_TRACK_FORCED;
1019 GST_DEBUG_OBJECT (demux, "TrackForced: %d",
1020 (context->flags & GST_MATROSKA_TRACK_FORCED) ? 1 : 0);
1024 /* lacing (like MPEG, where blocks don't end/start on frame
1026 case GST_MATROSKA_ID_TRACKFLAGLACING:{
1029 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1033 context->flags |= GST_MATROSKA_TRACK_LACING;
1035 context->flags &= ~GST_MATROSKA_TRACK_LACING;
1037 GST_DEBUG_OBJECT (demux, "TrackLacing: %d",
1038 (context->flags & GST_MATROSKA_TRACK_LACING) ? 1 : 0);
1042 /* default length (in time) of one data block in this track */
1043 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
1046 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1051 GST_WARNING_OBJECT (demux, "Invalid TrackDefaultDuration 0");
1055 GST_DEBUG_OBJECT (demux, "TrackDefaultDuration: %" G_GUINT64_FORMAT,
1057 context->default_duration = num;
1061 case GST_MATROSKA_ID_CONTENTENCODINGS:{
1062 ret = gst_matroska_read_common_read_track_encodings (&demux->common,
1067 case GST_MATROSKA_ID_TRACKTIMECODESCALE:{
1070 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
1074 GST_WARNING_OBJECT (demux, "Invalid TrackTimeCodeScale %lf", num);
1078 GST_DEBUG_OBJECT (demux, "TrackTimeCodeScale: %lf", num);
1079 context->timecodescale = num;
1084 GST_WARNING ("Unknown TrackEntry subelement 0x%x - ignoring", id);
1087 /* we ignore these because they're nothing useful (i.e. crap)
1088 * or simply not implemented yet. */
1089 case GST_MATROSKA_ID_TRACKMINCACHE:
1090 case GST_MATROSKA_ID_TRACKMAXCACHE:
1091 case GST_MATROSKA_ID_MAXBLOCKADDITIONID:
1092 case GST_MATROSKA_ID_TRACKATTACHMENTLINK:
1093 case GST_MATROSKA_ID_TRACKOVERLAY:
1094 case GST_MATROSKA_ID_TRACKTRANSLATE:
1095 case GST_MATROSKA_ID_TRACKOFFSET:
1096 case GST_MATROSKA_ID_CODECSETTINGS:
1097 case GST_MATROSKA_ID_CODECINFOURL:
1098 case GST_MATROSKA_ID_CODECDOWNLOADURL:
1099 case GST_MATROSKA_ID_CODECDECODEALL:
1100 ret = gst_ebml_read_skip (ebml);
1105 DEBUG_ELEMENT_STOP (demux, ebml, "TrackEntry", ret);
1107 /* Decode codec private data if necessary */
1108 if (context->encodings && context->encodings->len > 0 && context->codec_priv
1109 && context->codec_priv_size > 0) {
1110 if (!gst_matroska_decode_data (context->encodings,
1111 &context->codec_priv, &context->codec_priv_size,
1112 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
1113 GST_WARNING_OBJECT (demux, "Decoding codec private data failed");
1114 ret = GST_FLOW_ERROR;
1118 if (context->type == 0 || context->codec_id == NULL || (ret != GST_FLOW_OK
1119 && ret != GST_FLOW_EOS)) {
1120 if (ret == GST_FLOW_OK || ret == GST_FLOW_EOS)
1121 GST_WARNING_OBJECT (ebml, "Unknown stream/codec in track entry header");
1123 demux->common.num_streams--;
1124 g_ptr_array_remove_index (demux->common.src, demux->common.num_streams);
1125 g_assert (demux->common.src->len == demux->common.num_streams);
1127 gst_matroska_track_free (context);
1133 /* now create the GStreamer connectivity */
1134 switch (context->type) {
1135 case GST_MATROSKA_TRACK_TYPE_VIDEO:{
1136 GstMatroskaTrackVideoContext *videocontext =
1137 (GstMatroskaTrackVideoContext *) context;
1139 padname = g_strdup_printf ("video_%u", demux->num_v_streams++);
1140 templ = gst_element_class_get_pad_template (klass, "video_%u");
1141 caps = gst_matroska_demux_video_caps (videocontext,
1142 context->codec_id, context->codec_priv,
1143 context->codec_priv_size, &codec, &riff_fourcc);
1146 gst_tag_list_add (context->tags, GST_TAG_MERGE_REPLACE,
1147 GST_TAG_VIDEO_CODEC, codec, NULL);
1148 context->tags_changed = TRUE;
1154 case GST_MATROSKA_TRACK_TYPE_AUDIO:{
1155 GstMatroskaTrackAudioContext *audiocontext =
1156 (GstMatroskaTrackAudioContext *) context;
1158 padname = g_strdup_printf ("audio_%u", demux->num_a_streams++);
1159 templ = gst_element_class_get_pad_template (klass, "audio_%u");
1160 caps = gst_matroska_demux_audio_caps (audiocontext,
1161 context->codec_id, context->codec_priv, context->codec_priv_size,
1162 &codec, &riff_audio_fmt);
1165 gst_tag_list_add (context->tags, GST_TAG_MERGE_REPLACE,
1166 GST_TAG_AUDIO_CODEC, codec, NULL);
1167 context->tags_changed = TRUE;
1173 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:{
1174 GstMatroskaTrackSubtitleContext *subtitlecontext =
1175 (GstMatroskaTrackSubtitleContext *) context;
1177 padname = g_strdup_printf ("subtitle_%u", demux->num_t_streams++);
1178 templ = gst_element_class_get_pad_template (klass, "subtitle_%u");
1179 caps = gst_matroska_demux_subtitle_caps (subtitlecontext,
1180 context->codec_id, context->codec_priv, context->codec_priv_size);
1184 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1185 case GST_MATROSKA_TRACK_TYPE_LOGO:
1186 case GST_MATROSKA_TRACK_TYPE_BUTTONS:
1187 case GST_MATROSKA_TRACK_TYPE_CONTROL:
1189 /* we should already have quit by now */
1190 g_assert_not_reached ();
1193 if ((context->language == NULL || *context->language == '\0') &&
1194 (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO ||
1195 context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
1196 GST_LOG ("stream %d: language=eng (assuming default)", context->index);
1197 context->language = g_strdup ("eng");
1200 if (context->language) {
1203 /* Matroska contains ISO 639-2B codes, we want ISO 639-1 */
1204 lang = gst_tag_get_language_code (context->language);
1205 gst_tag_list_add (context->tags, GST_TAG_MERGE_REPLACE,
1206 GST_TAG_LANGUAGE_CODE, (lang) ? lang : context->language, NULL);
1207 context->tags_changed = TRUE;
1211 GST_WARNING_OBJECT (demux, "could not determine caps for stream with "
1212 "codec_id='%s'", context->codec_id);
1213 switch (context->type) {
1214 case GST_MATROSKA_TRACK_TYPE_VIDEO:
1215 caps = gst_caps_new_empty_simple ("video/x-unknown");
1217 case GST_MATROSKA_TRACK_TYPE_AUDIO:
1218 caps = gst_caps_new_empty_simple ("audio/x-unknown");
1220 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
1221 caps = gst_caps_new_empty_simple ("application/x-subtitle-unknown");
1223 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1225 caps = gst_caps_new_empty_simple ("application/x-matroska-unknown");
1228 gst_caps_set_simple (caps, "codec-id", G_TYPE_STRING, context->codec_id,
1231 /* add any unrecognised riff fourcc / audio format, but after codec-id */
1232 if (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO && riff_audio_fmt != 0)
1233 gst_caps_set_simple (caps, "format", G_TYPE_INT, riff_audio_fmt, NULL);
1234 else if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO && riff_fourcc != 0) {
1235 gchar *fstr = g_strdup_printf ("%" GST_FOURCC_FORMAT,
1236 GST_FOURCC_ARGS (riff_fourcc));
1237 gst_caps_set_simple (caps, "fourcc", G_TYPE_STRING, fstr, NULL);
1240 } else if (context->stream_headers != NULL) {
1241 gst_matroska_demux_add_stream_headers_to_caps (demux,
1242 context->stream_headers, caps);
1245 /* the pad in here */
1246 context->pad = gst_pad_new_from_template (templ, padname);
1247 context->caps = caps;
1249 gst_pad_set_event_function (context->pad,
1250 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_event));
1251 gst_pad_set_query_function (context->pad,
1252 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_query));
1254 GST_INFO_OBJECT (demux, "Adding pad '%s' with caps %" GST_PTR_FORMAT,
1257 gst_pad_set_element_private (context->pad, context);
1259 gst_pad_use_fixed_caps (context->pad);
1260 gst_pad_set_active (context->pad, TRUE);
1263 gst_pad_create_stream_id_printf (context->pad, GST_ELEMENT_CAST (demux),
1264 "%03" G_GUINT64_FORMAT, context->uid);
1266 gst_pad_get_sticky_event (demux->common.sinkpad, GST_EVENT_STREAM_START,
1269 if (gst_event_parse_group_id (stream_start, &demux->group_id))
1270 demux->have_group_id = TRUE;
1272 demux->have_group_id = FALSE;
1273 gst_event_unref (stream_start);
1274 } else if (!demux->have_group_id) {
1275 demux->have_group_id = TRUE;
1276 demux->group_id = gst_util_group_id_next ();
1279 stream_start = gst_event_new_stream_start (stream_id);
1281 if (demux->have_group_id)
1282 gst_event_set_group_id (stream_start, demux->group_id);
1283 stream_flags = GST_STREAM_FLAG_NONE;
1284 if (context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)
1285 stream_flags |= GST_STREAM_FLAG_SPARSE;
1286 if (context->flags & GST_MATROSKA_TRACK_DEFAULT)
1287 stream_flags |= GST_STREAM_FLAG_SELECT;
1288 gst_event_set_stream_flags (stream_start, stream_flags);
1289 gst_pad_push_event (context->pad, stream_start);
1290 gst_pad_set_caps (context->pad, context->caps);
1293 if (demux->common.global_tags) {
1294 GstEvent *tag_event;
1296 gst_tag_list_add (demux->common.global_tags, GST_TAG_MERGE_REPLACE,
1297 GST_TAG_CONTAINER_FORMAT, "Matroska", NULL);
1298 GST_DEBUG_OBJECT (context->pad, "Sending global_tags %p: %" GST_PTR_FORMAT,
1299 demux->common.global_tags, demux->common.global_tags);
1302 gst_event_new_tag (gst_tag_list_copy (demux->common.global_tags));
1304 gst_pad_push_event (context->pad, tag_event);
1307 if (G_UNLIKELY (context->tags_changed)) {
1308 GST_DEBUG_OBJECT (context->pad, "Sending tags %p: %"
1309 GST_PTR_FORMAT, context->tags, context->tags);
1310 gst_pad_push_event (context->pad,
1311 gst_event_new_tag (gst_tag_list_copy (context->tags)));
1312 context->tags_changed = FALSE;
1315 gst_element_add_pad (GST_ELEMENT (demux), context->pad);
1316 gst_flow_combiner_add_pad (demux->flowcombiner, context->pad);
1325 gst_matroska_demux_query (GstMatroskaDemux * demux, GstPad * pad,
1328 gboolean res = FALSE;
1329 GstMatroskaTrackContext *context = NULL;
1332 context = gst_pad_get_element_private (pad);
1335 switch (GST_QUERY_TYPE (query)) {
1336 case GST_QUERY_POSITION:
1340 gst_query_parse_position (query, &format, NULL);
1343 if (format == GST_FORMAT_TIME) {
1344 GST_OBJECT_LOCK (demux);
1346 gst_query_set_position (query, GST_FORMAT_TIME,
1347 MAX (context->pos, demux->stream_start_time) -
1348 demux->stream_start_time);
1350 gst_query_set_position (query, GST_FORMAT_TIME,
1351 MAX (demux->common.segment.position, demux->stream_start_time) -
1352 demux->stream_start_time);
1353 GST_OBJECT_UNLOCK (demux);
1354 } else if (format == GST_FORMAT_DEFAULT && context
1355 && context->default_duration) {
1356 GST_OBJECT_LOCK (demux);
1357 gst_query_set_position (query, GST_FORMAT_DEFAULT,
1358 context->pos / context->default_duration);
1359 GST_OBJECT_UNLOCK (demux);
1361 GST_DEBUG_OBJECT (demux,
1362 "only position query in TIME and DEFAULT format is supported");
1368 case GST_QUERY_DURATION:
1372 gst_query_parse_duration (query, &format, NULL);
1375 if (format == GST_FORMAT_TIME) {
1376 GST_OBJECT_LOCK (demux);
1377 gst_query_set_duration (query, GST_FORMAT_TIME,
1378 demux->common.segment.duration);
1379 GST_OBJECT_UNLOCK (demux);
1380 } else if (format == GST_FORMAT_DEFAULT && context
1381 && context->default_duration) {
1382 GST_OBJECT_LOCK (demux);
1383 gst_query_set_duration (query, GST_FORMAT_DEFAULT,
1384 demux->common.segment.duration / context->default_duration);
1385 GST_OBJECT_UNLOCK (demux);
1387 GST_DEBUG_OBJECT (demux,
1388 "only duration query in TIME and DEFAULT format is supported");
1394 case GST_QUERY_SEEKING:
1398 gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
1399 GST_OBJECT_LOCK (demux);
1400 if (fmt == GST_FORMAT_TIME) {
1403 if (demux->streaming) {
1404 /* assuming we'll be able to get an index ... */
1405 seekable = demux->seekable;
1410 gst_query_set_seeking (query, GST_FORMAT_TIME, seekable,
1411 0, demux->common.segment.duration);
1414 GST_OBJECT_UNLOCK (demux);
1417 case GST_QUERY_SEGMENT:
1422 format = demux->common.segment.format;
1425 gst_segment_to_stream_time (&demux->common.segment, format,
1426 demux->common.segment.start);
1427 if ((stop = demux->common.segment.stop) == -1)
1428 stop = demux->common.segment.duration;
1431 gst_segment_to_stream_time (&demux->common.segment, format, stop);
1433 gst_query_set_segment (query, demux->common.segment.rate, format, start,
1440 res = gst_pad_query_default (pad, (GstObject *) demux, query);
1443 GST_ELEMENT_CLASS (parent_class)->query (GST_ELEMENT_CAST (demux),
1452 gst_matroska_demux_element_query (GstElement * element, GstQuery * query)
1454 return gst_matroska_demux_query (GST_MATROSKA_DEMUX (element), NULL, query);
1458 gst_matroska_demux_handle_src_query (GstPad * pad, GstObject * parent,
1461 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
1463 return gst_matroska_demux_query (demux, pad, query);
1466 /* returns FALSE if there are no pads to deliver event to,
1467 * otherwise TRUE (whatever the outcome of event sending),
1468 * takes ownership of the passed event! */
1470 gst_matroska_demux_send_event (GstMatroskaDemux * demux, GstEvent * event)
1472 gboolean ret = FALSE;
1475 g_return_val_if_fail (event != NULL, FALSE);
1477 GST_DEBUG_OBJECT (demux, "Sending event of type %s to all source pads",
1478 GST_EVENT_TYPE_NAME (event));
1480 g_assert (demux->common.src->len == demux->common.num_streams);
1481 for (i = 0; i < demux->common.src->len; i++) {
1482 GstMatroskaTrackContext *stream;
1484 stream = g_ptr_array_index (demux->common.src, i);
1485 gst_event_ref (event);
1486 gst_pad_push_event (stream->pad, event);
1490 gst_event_unref (event);
1495 gst_matroska_demux_send_tags (GstMatroskaDemux * demux)
1499 if (G_UNLIKELY (demux->common.global_tags_changed)) {
1500 GstEvent *tag_event;
1501 gst_tag_list_add (demux->common.global_tags, GST_TAG_MERGE_REPLACE,
1502 GST_TAG_CONTAINER_FORMAT, "Matroska", NULL);
1503 GST_DEBUG_OBJECT (demux, "Sending global_tags %p : %" GST_PTR_FORMAT,
1504 demux->common.global_tags, demux->common.global_tags);
1507 gst_event_new_tag (gst_tag_list_copy (demux->common.global_tags));
1509 for (i = 0; i < demux->common.src->len; i++) {
1510 GstMatroskaTrackContext *stream;
1512 stream = g_ptr_array_index (demux->common.src, i);
1513 gst_pad_push_event (stream->pad, gst_event_ref (tag_event));
1516 gst_event_unref (tag_event);
1517 demux->common.global_tags_changed = FALSE;
1520 g_assert (demux->common.src->len == demux->common.num_streams);
1521 for (i = 0; i < demux->common.src->len; i++) {
1522 GstMatroskaTrackContext *stream;
1524 stream = g_ptr_array_index (demux->common.src, i);
1526 if (G_UNLIKELY (stream->tags_changed)) {
1527 GST_DEBUG_OBJECT (demux, "Sending tags %p for pad %s:%s : %"
1528 GST_PTR_FORMAT, stream->tags,
1529 GST_DEBUG_PAD_NAME (stream->pad), stream->tags);
1530 gst_pad_push_event (stream->pad,
1531 gst_event_new_tag (gst_tag_list_copy (stream->tags)));
1532 stream->tags_changed = FALSE;
1538 gst_matroska_demux_element_send_event (GstElement * element, GstEvent * event)
1540 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
1543 g_return_val_if_fail (event != NULL, FALSE);
1545 if (GST_EVENT_TYPE (event) == GST_EVENT_SEEK) {
1546 res = gst_matroska_demux_handle_seek_event (demux, NULL, event);
1548 GST_WARNING_OBJECT (demux, "Unhandled event of type %s",
1549 GST_EVENT_TYPE_NAME (event));
1552 gst_event_unref (event);
1557 gst_matroska_demux_move_to_entry (GstMatroskaDemux * demux,
1558 GstMatroskaIndex * entry, gboolean reset, gboolean update)
1562 GST_OBJECT_LOCK (demux);
1565 /* seek (relative to matroska segment) */
1566 /* position might be invalid; will error when streaming resumes ... */
1567 demux->common.offset = entry->pos + demux->common.ebml_segment_start;
1568 demux->next_cluster_offset = 0;
1570 GST_DEBUG_OBJECT (demux,
1571 "Seeked to offset %" G_GUINT64_FORMAT ", block %d, " "time %"
1572 GST_TIME_FORMAT, entry->pos + demux->common.ebml_segment_start,
1573 entry->block, GST_TIME_ARGS (entry->time));
1575 /* update the time */
1576 gst_matroska_read_common_reset_streams (&demux->common, entry->time, TRUE);
1577 gst_flow_combiner_reset (demux->flowcombiner);
1578 demux->common.segment.position = entry->time;
1579 demux->seek_block = entry->block;
1580 demux->seek_first = TRUE;
1581 demux->last_stop_end = GST_CLOCK_TIME_NONE;
1584 for (i = 0; i < demux->common.src->len; i++) {
1585 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
1588 stream->to_offset = G_MAXINT64;
1590 if (stream->from_offset != -1)
1591 stream->to_offset = stream->from_offset;
1593 stream->from_offset = -1;
1594 stream->from_time = GST_CLOCK_TIME_NONE;
1597 GST_OBJECT_UNLOCK (demux);
1603 gst_matroska_cluster_compare (gint64 * i1, gint64 * i2)
1613 /* searches for a cluster start from @pos,
1614 * return GST_FLOW_OK and cluster position in @pos if found */
1615 static GstFlowReturn
1616 gst_matroska_demux_search_cluster (GstMatroskaDemux * demux, gint64 * pos)
1618 gint64 newpos = *pos;
1620 GstFlowReturn ret = GST_FLOW_OK;
1621 const guint chunk = 64 * 1024;
1622 GstBuffer *buf = NULL;
1624 gpointer data = NULL;
1629 gint64 oldpos, oldlength;
1631 orig_offset = demux->common.offset;
1633 GST_LOG_OBJECT (demux, "searching cluster following offset %" G_GINT64_FORMAT,
1636 if (demux->clusters) {
1639 cpos = gst_util_array_binary_search (demux->clusters->data,
1640 demux->clusters->len, sizeof (gint64),
1641 (GCompareDataFunc) gst_matroska_cluster_compare,
1642 GST_SEARCH_MODE_AFTER, pos, NULL);
1645 GST_DEBUG_OBJECT (demux,
1646 "cluster reported at offset %" G_GINT64_FORMAT, *cpos);
1647 demux->common.offset = *cpos;
1648 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1649 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1650 if (ret == GST_FLOW_OK && id == GST_MATROSKA_ID_CLUSTER) {
1657 /* read in at newpos and scan for ebml cluster id */
1658 oldpos = oldlength = -1;
1660 GstByteReader reader;
1664 gst_buffer_unmap (buf, &map);
1665 gst_buffer_unref (buf);
1668 ret = gst_pad_pull_range (demux->common.sinkpad, newpos, chunk, &buf);
1669 if (ret != GST_FLOW_OK)
1671 GST_DEBUG_OBJECT (demux,
1672 "read buffer size %" G_GSIZE_FORMAT " at offset %" G_GINT64_FORMAT,
1673 gst_buffer_get_size (buf), newpos);
1674 gst_buffer_map (buf, &map, GST_MAP_READ);
1677 if (oldpos == newpos && oldlength == map.size) {
1678 GST_ERROR_OBJECT (demux, "Stuck at same position");
1679 ret = GST_FLOW_ERROR;
1683 oldlength = map.size;
1686 gst_byte_reader_init (&reader, data, size);
1688 cluster_pos = gst_byte_reader_masked_scan_uint32 (&reader, 0xffffffff,
1689 GST_MATROSKA_ID_CLUSTER, 0, gst_byte_reader_get_remaining (&reader));
1690 if (cluster_pos >= 0) {
1691 newpos += cluster_pos;
1692 /* prepare resuming at next byte */
1693 if (!gst_byte_reader_skip (&reader, cluster_pos + 1)) {
1694 GST_DEBUG_OBJECT (demux, "Need more data -> continue");
1697 GST_DEBUG_OBJECT (demux,
1698 "found cluster ebml id at offset %" G_GINT64_FORMAT, newpos);
1699 /* extra checks whether we really sync'ed to a cluster:
1700 * - either it is the first and only cluster
1701 * - either there is a cluster after this one
1702 * - either cluster length is undefined
1704 /* ok if first cluster (there may not a subsequent one) */
1705 if (newpos == demux->first_cluster_offset) {
1706 GST_DEBUG_OBJECT (demux, "cluster is first cluster -> OK");
1709 demux->common.offset = newpos;
1710 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1711 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1712 if (ret != GST_FLOW_OK) {
1713 GST_DEBUG_OBJECT (demux, "need more data -> continue");
1716 g_assert (id == GST_MATROSKA_ID_CLUSTER);
1717 GST_DEBUG_OBJECT (demux, "cluster size %" G_GUINT64_FORMAT ", prefix %d",
1719 /* ok if undefined length or first cluster */
1720 if (length == GST_EBML_SIZE_UNKNOWN || length == G_MAXUINT64) {
1721 GST_DEBUG_OBJECT (demux, "cluster has undefined length -> OK");
1725 demux->common.offset += length + needed;
1726 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1727 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1728 if (ret != GST_FLOW_OK)
1730 GST_DEBUG_OBJECT (demux, "next element is %scluster",
1731 id == GST_MATROSKA_ID_CLUSTER ? "" : "not ");
1732 if (id == GST_MATROSKA_ID_CLUSTER)
1734 /* not ok, resume */
1737 /* partial cluster id may have been in tail of buffer */
1738 newpos += MAX (gst_byte_reader_get_remaining (&reader), 4) - 3;
1743 gst_buffer_unmap (buf, &map);
1744 gst_buffer_unref (buf);
1749 demux->common.offset = orig_offset;
1754 /* bisect and scan through file for cluster starting before @time,
1755 * returns fake index entry with corresponding info on cluster */
1756 static GstMatroskaIndex *
1757 gst_matroska_demux_search_pos (GstMatroskaDemux * demux, GstClockTime time)
1759 GstMatroskaIndex *entry = NULL;
1760 GstMatroskaReadState current_state;
1761 GstClockTime otime, prev_cluster_time, current_cluster_time, cluster_time;
1762 gint64 opos, newpos, startpos = 0, current_offset;
1763 gint64 prev_cluster_offset = -1, current_cluster_offset, cluster_offset;
1764 const guint chunk = 64 * 1024;
1770 /* (under)estimate new position, resync using cluster ebml id,
1771 * and scan forward to appropriate cluster
1772 * (and re-estimate if need to go backward) */
1774 prev_cluster_time = GST_CLOCK_TIME_NONE;
1776 /* store some current state */
1777 current_state = demux->common.state;
1778 g_return_val_if_fail (current_state == GST_MATROSKA_READ_STATE_DATA, NULL);
1780 current_cluster_offset = demux->cluster_offset;
1781 current_cluster_time = demux->cluster_time;
1782 current_offset = demux->common.offset;
1784 demux->common.state = GST_MATROSKA_READ_STATE_SCANNING;
1786 /* estimate using start and current position */
1787 GST_OBJECT_LOCK (demux);
1788 opos = demux->common.offset - demux->common.ebml_segment_start;
1789 otime = demux->common.segment.position;
1790 GST_OBJECT_UNLOCK (demux);
1793 time = MAX (time, demux->stream_start_time);
1795 /* avoid division by zero in first estimation below */
1796 if (otime <= demux->stream_start_time)
1800 GST_LOG_OBJECT (demux,
1801 "opos: %" G_GUINT64_FORMAT ", otime: %" GST_TIME_FORMAT ", %"
1802 GST_TIME_FORMAT " in stream time (start %" GST_TIME_FORMAT "), time %"
1803 GST_TIME_FORMAT, opos, GST_TIME_ARGS (otime),
1804 GST_TIME_ARGS (otime - demux->stream_start_time),
1805 GST_TIME_ARGS (demux->stream_start_time), GST_TIME_ARGS (time));
1807 if (otime <= demux->stream_start_time) {
1811 gst_util_uint64_scale (opos - demux->common.ebml_segment_start,
1812 time - demux->stream_start_time,
1813 otime - demux->stream_start_time) - chunk;
1817 /* favour undershoot */
1818 newpos = newpos * 90 / 100;
1819 newpos += demux->common.ebml_segment_start;
1821 GST_DEBUG_OBJECT (demux,
1822 "estimated offset for %" GST_TIME_FORMAT ": %" G_GINT64_FORMAT,
1823 GST_TIME_ARGS (time), newpos);
1825 /* and at least start scanning before previous scan start to avoid looping */
1826 startpos = startpos * 90 / 100;
1827 if (startpos && startpos < newpos)
1830 /* read in at newpos and scan for ebml cluster id */
1834 ret = gst_matroska_demux_search_cluster (demux, &newpos);
1835 if (ret == GST_FLOW_EOS) {
1836 /* heuristic HACK */
1837 newpos = startpos * 80 / 100;
1838 GST_DEBUG_OBJECT (demux, "EOS; "
1839 "new estimated offset for %" GST_TIME_FORMAT ": %" G_GINT64_FORMAT,
1840 GST_TIME_ARGS (time), newpos);
1843 } else if (ret != GST_FLOW_OK) {
1850 /* then start scanning and parsing for cluster time,
1851 * re-estimate if overshoot, otherwise next cluster and so on */
1852 demux->common.offset = newpos;
1853 demux->cluster_time = cluster_time = GST_CLOCK_TIME_NONE;
1855 guint64 cluster_size = 0;
1857 /* peek and parse some elements */
1858 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1859 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1860 if (ret != GST_FLOW_OK)
1862 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
1863 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
1865 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
1866 if (ret != GST_FLOW_OK)
1869 if (id == GST_MATROSKA_ID_CLUSTER) {
1870 cluster_time = GST_CLOCK_TIME_NONE;
1871 if (length == G_MAXUINT64)
1874 cluster_size = length + needed;
1876 if (demux->cluster_time != GST_CLOCK_TIME_NONE &&
1877 cluster_time == GST_CLOCK_TIME_NONE) {
1878 cluster_time = demux->cluster_time * demux->common.time_scale;
1879 cluster_offset = demux->cluster_offset;
1880 GST_DEBUG_OBJECT (demux, "found cluster at offset %" G_GINT64_FORMAT
1881 " with time %" GST_TIME_FORMAT, cluster_offset,
1882 GST_TIME_ARGS (cluster_time));
1883 if (cluster_time > time) {
1884 GST_DEBUG_OBJECT (demux, "overshot target");
1885 /* cluster overshoots */
1886 if (cluster_offset == demux->first_cluster_offset) {
1887 /* but no prev one */
1888 GST_DEBUG_OBJECT (demux, "but using first cluster anyway");
1889 prev_cluster_time = cluster_time;
1890 prev_cluster_offset = cluster_offset;
1893 if (prev_cluster_time != GST_CLOCK_TIME_NONE) {
1894 /* prev cluster did not overshoot, so prev cluster is target */
1897 /* re-estimate using this new position info */
1898 opos = cluster_offset;
1899 otime = cluster_time;
1903 /* cluster undershoots, goto next one */
1904 prev_cluster_time = cluster_time;
1905 prev_cluster_offset = cluster_offset;
1906 /* skip cluster if length is defined,
1907 * otherwise will be skippingly parsed into */
1909 GST_DEBUG_OBJECT (demux, "skipping to next cluster");
1910 demux->common.offset = cluster_offset + cluster_size;
1911 demux->cluster_time = GST_CLOCK_TIME_NONE;
1913 GST_DEBUG_OBJECT (demux, "parsing/skipping cluster elements");
1920 if (ret == GST_FLOW_EOS) {
1921 if (prev_cluster_time != GST_CLOCK_TIME_NONE)
1927 entry = g_new0 (GstMatroskaIndex, 1);
1928 entry->time = prev_cluster_time;
1929 entry->pos = prev_cluster_offset - demux->common.ebml_segment_start;
1930 GST_DEBUG_OBJECT (demux, "simulated index entry; time %" GST_TIME_FORMAT
1931 ", pos %" G_GUINT64_FORMAT, GST_TIME_ARGS (entry->time), entry->pos);
1935 /* restore some state */
1936 demux->cluster_offset = current_cluster_offset;
1937 demux->cluster_time = current_cluster_time;
1938 demux->common.offset = current_offset;
1939 demux->common.state = current_state;
1945 gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
1946 GstPad * pad, GstEvent * event)
1948 GstMatroskaIndex *entry = NULL;
1949 GstMatroskaIndex scan_entry;
1951 GstSeekType cur_type, stop_type;
1953 gboolean flush, keyunit, before, after, snap_next;
1956 GstMatroskaTrackContext *track = NULL;
1957 GstSegment seeksegment = { 0, };
1958 gboolean update = TRUE;
1959 gboolean pad_locked = FALSE;
1961 GstSearchMode snap_dir;
1963 g_return_val_if_fail (event != NULL, FALSE);
1966 track = gst_pad_get_element_private (pad);
1968 GST_DEBUG_OBJECT (demux, "Have seek %" GST_PTR_FORMAT, event);
1970 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
1972 seqnum = gst_event_get_seqnum (event);
1974 /* we can only seek on time */
1975 if (format != GST_FORMAT_TIME) {
1976 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
1980 /* copy segment, we need this because we still need the old
1981 * segment when we close the current segment. */
1982 memcpy (&seeksegment, &demux->common.segment, sizeof (GstSegment));
1984 /* pull mode without index means that the actual duration is not known,
1985 * we might be playing a file that's still being recorded
1986 * so, invalidate our current duration, which is only a moving target,
1987 * and should not be used to clamp anything */
1988 if (!demux->streaming && !demux->common.index && demux->invalid_duration) {
1989 seeksegment.duration = GST_CLOCK_TIME_NONE;
1992 GST_DEBUG_OBJECT (demux, "configuring seek");
1993 /* Subtract stream_start_time so we always seek on a segment
1995 if (GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
1996 seeksegment.start -= demux->stream_start_time;
1997 seeksegment.position -= demux->stream_start_time;
1998 if (GST_CLOCK_TIME_IS_VALID (seeksegment.stop))
1999 seeksegment.stop -= demux->stream_start_time;
2001 seeksegment.stop = seeksegment.duration;
2004 gst_segment_do_seek (&seeksegment, rate, format, flags,
2005 cur_type, cur, stop_type, stop, &update);
2007 /* Restore the clip timestamp offset */
2008 if (GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
2009 seeksegment.position += demux->stream_start_time;
2010 seeksegment.start += demux->stream_start_time;
2011 if (!GST_CLOCK_TIME_IS_VALID (seeksegment.stop))
2012 seeksegment.stop = seeksegment.duration;
2013 if (GST_CLOCK_TIME_IS_VALID (seeksegment.stop))
2014 seeksegment.stop += demux->stream_start_time;
2017 /* restore segment duration (if any effect),
2018 * would be determined again when parsing, but anyway ... */
2019 seeksegment.duration = demux->common.segment.duration;
2021 flush = ! !(flags & GST_SEEK_FLAG_FLUSH);
2022 keyunit = ! !(flags & GST_SEEK_FLAG_KEY_UNIT);
2023 after = ! !(flags & GST_SEEK_FLAG_SNAP_AFTER);
2024 before = ! !(flags & GST_SEEK_FLAG_SNAP_BEFORE);
2026 /* always do full update if flushing,
2027 * otherwise problems might arise downstream with missing keyframes etc */
2028 update = update || flush;
2030 GST_DEBUG_OBJECT (demux, "New segment %" GST_SEGMENT_FORMAT, &seeksegment);
2032 /* check sanity before we start flushing and all that */
2033 snap_next = after && !before;
2034 if (seeksegment.rate < 0)
2035 snap_dir = snap_next ? GST_SEARCH_MODE_BEFORE : GST_SEARCH_MODE_AFTER;
2037 snap_dir = snap_next ? GST_SEARCH_MODE_AFTER : GST_SEARCH_MODE_BEFORE;
2039 GST_OBJECT_LOCK (demux);
2040 track = gst_matroska_read_common_get_seek_track (&demux->common, track);
2041 if ((entry = gst_matroska_read_common_do_index_seek (&demux->common, track,
2042 seeksegment.position, &demux->seek_index, &demux->seek_entry,
2043 snap_dir)) == NULL) {
2044 /* pull mode without index can scan later on */
2045 if (demux->streaming) {
2046 GST_DEBUG_OBJECT (demux, "No matching seek entry in index");
2047 GST_OBJECT_UNLOCK (demux);
2049 } else if (rate < 0.0) {
2050 /* FIXME: We should build an index during playback or when scanning
2051 * that can be used here. The reverse playback code requires seek_index
2052 * and seek_entry to be set!
2054 GST_DEBUG_OBJECT (demux,
2055 "No matching seek entry in index, needed for reverse playback");
2056 GST_OBJECT_UNLOCK (demux);
2060 GST_DEBUG_OBJECT (demux, "Seek position looks sane");
2061 GST_OBJECT_UNLOCK (demux);
2064 /* only have to update some segment,
2065 * but also still have to honour flush and so on */
2066 GST_DEBUG_OBJECT (demux, "... no update");
2067 /* bad goto, bad ... */
2071 if (demux->streaming)
2076 GstEvent *flush_event = gst_event_new_flush_start ();
2077 gst_event_set_seqnum (flush_event, seqnum);
2078 GST_DEBUG_OBJECT (demux, "Starting flush");
2079 gst_pad_push_event (demux->common.sinkpad, gst_event_ref (flush_event));
2080 gst_matroska_demux_send_event (demux, flush_event);
2082 GST_DEBUG_OBJECT (demux, "Non-flushing seek, pausing task");
2083 gst_pad_pause_task (demux->common.sinkpad);
2087 GST_PAD_STREAM_LOCK (demux->common.sinkpad);
2092 /* now grab the stream lock so that streaming cannot continue, for
2093 * non flushing seeks when the element is in PAUSED this could block
2095 GST_DEBUG_OBJECT (demux, "Waiting for streaming to stop");
2096 GST_PAD_STREAM_LOCK (demux->common.sinkpad);
2099 /* pull mode without index can do some scanning */
2100 if (!demux->streaming && !entry) {
2101 GstEvent *flush_event;
2103 /* need to stop flushing upstream as we need it next */
2105 flush_event = gst_event_new_flush_stop (TRUE);
2106 gst_event_set_seqnum (flush_event, seqnum);
2107 gst_pad_push_event (demux->common.sinkpad, flush_event);
2109 entry = gst_matroska_demux_search_pos (demux, seeksegment.position);
2110 /* keep local copy */
2112 scan_entry = *entry;
2114 entry = &scan_entry;
2116 GST_DEBUG_OBJECT (demux, "Scan failed to find matching position");
2118 flush_event = gst_event_new_flush_stop (TRUE);
2119 gst_event_set_seqnum (flush_event, seqnum);
2120 gst_matroska_demux_send_event (demux, flush_event);
2128 GST_DEBUG_OBJECT (demux, "seek to key unit, adjusting segment start from %"
2129 GST_TIME_FORMAT " to %" GST_TIME_FORMAT,
2130 GST_TIME_ARGS (seeksegment.start), GST_TIME_ARGS (entry->time));
2131 seeksegment.start = MAX (entry->time, demux->stream_start_time);
2132 seeksegment.position = seeksegment.start;
2133 seeksegment.time = seeksegment.start - demux->stream_start_time;
2136 if (demux->streaming) {
2137 GST_OBJECT_LOCK (demux);
2138 /* track real position we should start at */
2139 GST_DEBUG_OBJECT (demux, "storing segment start");
2140 demux->requested_seek_time = seeksegment.position;
2141 demux->seek_offset = entry->pos + demux->common.ebml_segment_start;
2142 GST_OBJECT_UNLOCK (demux);
2143 /* need to seek to cluster start to pick up cluster time */
2144 /* upstream takes care of flushing and all that
2145 * ... and newsegment event handling takes care of the rest */
2146 return perform_seek_to_offset (demux, rate,
2147 entry->pos + demux->common.ebml_segment_start, seqnum);
2152 GstEvent *flush_event = gst_event_new_flush_stop (TRUE);
2153 gst_event_set_seqnum (flush_event, seqnum);
2154 GST_DEBUG_OBJECT (demux, "Stopping flush");
2155 gst_pad_push_event (demux->common.sinkpad, gst_event_ref (flush_event));
2156 gst_matroska_demux_send_event (demux, flush_event);
2159 GST_OBJECT_LOCK (demux);
2160 /* now update the real segment info */
2161 GST_DEBUG_OBJECT (demux, "Committing new seek segment");
2162 memcpy (&demux->common.segment, &seeksegment, sizeof (GstSegment));
2163 GST_OBJECT_UNLOCK (demux);
2165 /* update some (segment) state */
2166 if (!gst_matroska_demux_move_to_entry (demux, entry, TRUE, update))
2169 /* notify start of new segment */
2170 if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
2173 msg = gst_message_new_segment_start (GST_OBJECT (demux),
2174 GST_FORMAT_TIME, demux->common.segment.start);
2175 gst_message_set_seqnum (msg, seqnum);
2176 gst_element_post_message (GST_ELEMENT (demux), msg);
2179 GST_OBJECT_LOCK (demux);
2180 if (demux->new_segment)
2181 gst_event_unref (demux->new_segment);
2183 /* On port from 0.10, discarded !update (for segment.update) here, FIXME? */
2184 demux->new_segment = gst_event_new_segment (&demux->common.segment);
2185 gst_event_set_seqnum (demux->new_segment, seqnum);
2186 if (demux->common.segment.rate < 0 && demux->common.segment.stop == -1)
2187 demux->to_time = demux->common.segment.position;
2189 demux->to_time = GST_CLOCK_TIME_NONE;
2190 GST_OBJECT_UNLOCK (demux);
2192 /* restart our task since it might have been stopped when we did the
2194 gst_pad_start_task (demux->common.sinkpad,
2195 (GstTaskFunction) gst_matroska_demux_loop, demux->common.sinkpad, NULL);
2197 /* streaming can continue now */
2199 GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
2207 GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
2209 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Got a seek error"));
2215 * Handle whether we can perform the seek event or if we have to let the chain
2216 * function handle seeks to build the seek indexes first.
2219 gst_matroska_demux_handle_seek_push (GstMatroskaDemux * demux, GstPad * pad,
2223 GstSeekType cur_type, stop_type;
2228 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
2233 /* we can only seek on time */
2234 if (format != GST_FORMAT_TIME) {
2235 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
2239 if (stop_type != GST_SEEK_TYPE_NONE && stop != GST_CLOCK_TIME_NONE) {
2240 GST_DEBUG_OBJECT (demux, "Seek end-time not supported in streaming mode");
2244 if (!(flags & GST_SEEK_FLAG_FLUSH)) {
2245 GST_DEBUG_OBJECT (demux,
2246 "Non-flushing seek not supported in streaming mode");
2250 if (flags & GST_SEEK_FLAG_SEGMENT) {
2251 GST_DEBUG_OBJECT (demux, "Segment seek not supported in streaming mode");
2255 /* check for having parsed index already */
2256 if (!demux->common.index_parsed) {
2257 gboolean building_index;
2260 if (!demux->index_offset) {
2261 GST_DEBUG_OBJECT (demux, "no index (location); no seek in push mode");
2265 GST_OBJECT_LOCK (demux);
2266 /* handle the seek event in the chain function */
2267 demux->common.state = GST_MATROSKA_READ_STATE_SEEK;
2268 /* no more seek can be issued until state reset to _DATA */
2270 /* copy the event */
2271 if (demux->seek_event)
2272 gst_event_unref (demux->seek_event);
2273 demux->seek_event = gst_event_ref (event);
2275 /* set the building_index flag so that only one thread can setup the
2276 * structures for index seeking. */
2277 building_index = demux->building_index;
2278 if (!building_index) {
2279 demux->building_index = TRUE;
2280 offset = demux->index_offset;
2282 GST_OBJECT_UNLOCK (demux);
2284 if (!building_index) {
2285 /* seek to the first subindex or legacy index */
2286 GST_INFO_OBJECT (demux, "Seeking to Cues at %" G_GUINT64_FORMAT, offset);
2287 return perform_seek_to_offset (demux, rate, offset,
2288 gst_event_get_seqnum (event));
2291 /* well, we are handling it already */
2295 /* delegate to tweaked regular seek */
2296 return gst_matroska_demux_handle_seek_event (demux, pad, event);
2300 gst_matroska_demux_handle_src_event (GstPad * pad, GstObject * parent,
2303 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
2304 gboolean res = TRUE;
2306 switch (GST_EVENT_TYPE (event)) {
2307 case GST_EVENT_SEEK:
2308 /* no seeking until we are (safely) ready */
2309 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
2310 GST_DEBUG_OBJECT (demux, "not ready for seeking yet");
2313 if (!demux->streaming)
2314 res = gst_matroska_demux_handle_seek_event (demux, pad, event);
2316 res = gst_matroska_demux_handle_seek_push (demux, pad, event);
2317 gst_event_unref (event);
2322 GstMatroskaTrackContext *context = gst_pad_get_element_private (pad);
2323 if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
2324 GstMatroskaTrackVideoContext *videocontext =
2325 (GstMatroskaTrackVideoContext *) context;
2327 GstClockTimeDiff diff;
2328 GstClockTime timestamp;
2330 gst_event_parse_qos (event, NULL, &proportion, &diff, ×tamp);
2332 GST_OBJECT_LOCK (demux);
2333 videocontext->earliest_time = timestamp + diff;
2334 GST_OBJECT_UNLOCK (demux);
2337 gst_event_unref (event);
2341 case GST_EVENT_TOC_SELECT:
2344 GstTocEntry *entry = NULL;
2345 GstEvent *seek_event;
2348 if (!demux->common.toc) {
2349 GST_DEBUG_OBJECT (demux, "no TOC to select");
2352 gst_event_parse_toc_select (event, &uid);
2354 GST_OBJECT_LOCK (demux);
2355 entry = gst_toc_find_entry (demux->common.toc, uid);
2356 if (entry == NULL) {
2357 GST_OBJECT_UNLOCK (demux);
2358 GST_WARNING_OBJECT (demux, "no TOC entry with given UID: %s", uid);
2361 gst_toc_entry_get_start_stop_times (entry, &start_pos, NULL);
2362 GST_OBJECT_UNLOCK (demux);
2363 seek_event = gst_event_new_seek (1.0,
2365 GST_SEEK_FLAG_FLUSH,
2366 GST_SEEK_TYPE_SET, start_pos, GST_SEEK_TYPE_SET, -1);
2367 res = gst_matroska_demux_handle_seek_event (demux, pad, seek_event);
2368 gst_event_unref (seek_event);
2372 GST_WARNING_OBJECT (demux, "received empty TOC select event");
2376 gst_event_unref (event);
2380 /* events we don't need to handle */
2381 case GST_EVENT_NAVIGATION:
2382 gst_event_unref (event);
2386 case GST_EVENT_LATENCY:
2388 res = gst_pad_push_event (demux->common.sinkpad, event);
2395 static GstFlowReturn
2396 gst_matroska_demux_seek_to_previous_keyframe (GstMatroskaDemux * demux)
2398 GstFlowReturn ret = GST_FLOW_EOS;
2399 gboolean done = TRUE;
2402 g_return_val_if_fail (demux->seek_index, GST_FLOW_EOS);
2403 g_return_val_if_fail (demux->seek_entry < demux->seek_index->len,
2406 GST_DEBUG_OBJECT (demux, "locating previous keyframe");
2408 if (!demux->seek_entry) {
2409 GST_DEBUG_OBJECT (demux, "no earlier index entry");
2413 for (i = 0; i < demux->common.src->len; i++) {
2414 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
2416 GST_DEBUG_OBJECT (demux, "segment start %" GST_TIME_FORMAT
2417 ", stream %d at %" GST_TIME_FORMAT,
2418 GST_TIME_ARGS (demux->common.segment.start), stream->index,
2419 GST_TIME_ARGS (stream->from_time));
2420 if (GST_CLOCK_TIME_IS_VALID (stream->from_time)) {
2421 if (stream->from_time > demux->common.segment.start) {
2422 GST_DEBUG_OBJECT (demux, "stream %d not finished yet", stream->index);
2426 /* nothing pushed for this stream;
2427 * likely seek entry did not start at keyframe, so all was skipped.
2428 * So we need an earlier entry */
2434 GstMatroskaIndex *entry;
2436 entry = &g_array_index (demux->seek_index, GstMatroskaIndex,
2437 --demux->seek_entry);
2438 if (!gst_matroska_demux_move_to_entry (demux, entry, FALSE, TRUE))
2448 static GstFlowReturn
2449 gst_matroska_demux_parse_tracks (GstMatroskaDemux * demux, GstEbmlRead * ebml)
2451 GstFlowReturn ret = GST_FLOW_OK;
2454 DEBUG_ELEMENT_START (demux, ebml, "Tracks");
2456 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2457 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
2461 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
2462 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
2466 /* one track within the "all-tracks" header */
2467 case GST_MATROSKA_ID_TRACKENTRY:
2468 ret = gst_matroska_demux_add_stream (demux, ebml);
2472 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
2477 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
2479 demux->tracks_parsed = TRUE;
2485 * Read signed/unsigned "EBML" numbers.
2486 * Return: number of bytes processed.
2490 gst_matroska_ebmlnum_uint (guint8 * data, guint size, guint64 * num)
2492 gint len_mask = 0x80, read = 1, n = 1, num_ffs = 0;
2500 while (read <= 8 && !(total & len_mask)) {
2507 if ((total &= (len_mask - 1)) == len_mask - 1)
2512 if (data[n] == 0xff)
2514 total = (total << 8) | data[n];
2518 if (read == num_ffs && total != 0)
2527 gst_matroska_ebmlnum_sint (guint8 * data, guint size, gint64 * num)
2532 /* read as unsigned number first */
2533 if ((res = gst_matroska_ebmlnum_uint (data, size, &unum)) < 0)
2537 if (unum == G_MAXUINT64)
2540 *num = unum - ((1 << ((7 * res) - 1)) - 1);
2546 * Mostly used for subtitles. We add void filler data for each
2547 * lagging stream to make sure we don't deadlock.
2551 gst_matroska_demux_sync_streams (GstMatroskaDemux * demux)
2555 GST_OBJECT_LOCK (demux);
2557 GST_LOG_OBJECT (demux, "Sync to %" GST_TIME_FORMAT,
2558 GST_TIME_ARGS (demux->common.segment.position));
2560 g_assert (demux->common.num_streams == demux->common.src->len);
2561 for (stream_nr = 0; stream_nr < demux->common.src->len; stream_nr++) {
2562 GstMatroskaTrackContext *context;
2564 context = g_ptr_array_index (demux->common.src, stream_nr);
2566 GST_LOG_OBJECT (demux,
2567 "Checking for resync on stream %d (%" GST_TIME_FORMAT ")", stream_nr,
2568 GST_TIME_ARGS (context->pos));
2570 if (G_LIKELY (context->type != GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
2571 GST_LOG_OBJECT (demux, "Skipping sync on non-subtitle stream");
2575 /* does it lag? 0.5 seconds is a random threshold...
2576 * lag need only be considered if we have advanced into requested segment */
2577 if (GST_CLOCK_TIME_IS_VALID (context->pos) &&
2578 GST_CLOCK_TIME_IS_VALID (demux->common.segment.position) &&
2579 demux->common.segment.position > demux->common.segment.start &&
2580 context->pos + (GST_SECOND / 2) < demux->common.segment.position) {
2583 guint64 start = context->pos;
2584 guint64 stop = demux->common.segment.position - (GST_SECOND / 2);
2586 GST_DEBUG_OBJECT (demux,
2587 "Synchronizing stream %d with other by advancing time from %"
2588 GST_TIME_FORMAT " to %" GST_TIME_FORMAT, stream_nr,
2589 GST_TIME_ARGS (start), GST_TIME_ARGS (stop));
2591 context->pos = stop;
2593 event = gst_event_new_gap (start, stop - start);
2594 GST_OBJECT_UNLOCK (demux);
2595 gst_pad_push_event (context->pad, event);
2596 GST_OBJECT_LOCK (demux);
2600 GST_OBJECT_UNLOCK (demux);
2603 static GstFlowReturn
2604 gst_matroska_demux_push_stream_headers (GstMatroskaDemux * demux,
2605 GstMatroskaTrackContext * stream)
2607 GstFlowReturn ret = GST_FLOW_OK;
2610 num = gst_buffer_list_length (stream->stream_headers);
2611 for (i = 0; i < num; ++i) {
2614 buf = gst_buffer_list_get (stream->stream_headers, i);
2615 buf = gst_buffer_copy (buf);
2617 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
2619 if (stream->set_discont) {
2620 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
2621 stream->set_discont = FALSE;
2623 GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DISCONT);
2626 /* push out all headers in one go and use last flow return */
2627 ret = gst_pad_push (stream->pad, buf);
2630 /* don't need these any longer */
2631 gst_buffer_list_unref (stream->stream_headers);
2632 stream->stream_headers = NULL;
2635 ret = gst_flow_combiner_update_flow (demux->flowcombiner, ret);
2641 gst_matroska_demux_push_dvd_clut_change_event (GstMatroskaDemux * demux,
2642 GstMatroskaTrackContext * stream)
2646 g_assert (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB));
2648 if (!stream->codec_priv)
2651 /* ideally, VobSub private data should be parsed and stored more convenient
2652 * elsewhere, but for now, only interested in a small part */
2654 /* make sure we have terminating 0 */
2655 buf = g_strndup (stream->codec_priv, stream->codec_priv_size);
2657 /* just locate and parse palette part */
2658 start = strstr (buf, "palette:");
2663 guint8 r, g, b, y, u, v;
2666 while (g_ascii_isspace (*start))
2668 for (i = 0; i < 16; i++) {
2669 if (sscanf (start, "%06x", &col) != 1)
2672 while ((*start == ',') || g_ascii_isspace (*start))
2674 /* sigh, need to convert this from vobsub pseudo-RGB to YUV */
2675 r = (col >> 16) & 0xff;
2676 g = (col >> 8) & 0xff;
2678 y = CLAMP ((0.1494 * r + 0.6061 * g + 0.2445 * b) * 219 / 255 + 16, 0,
2680 u = CLAMP (0.6066 * r - 0.4322 * g - 0.1744 * b + 128, 0, 255);
2681 v = CLAMP (-0.08435 * r - 0.3422 * g + 0.4266 * b + 128, 0, 255);
2682 clut[i] = (y << 16) | (u << 8) | v;
2685 /* got them all without problems; build and send event */
2689 s = gst_structure_new ("application/x-gst-dvd", "event", G_TYPE_STRING,
2690 "dvd-spu-clut-change", "clut00", G_TYPE_INT, clut[0], "clut01",
2691 G_TYPE_INT, clut[1], "clut02", G_TYPE_INT, clut[2], "clut03",
2692 G_TYPE_INT, clut[3], "clut04", G_TYPE_INT, clut[4], "clut05",
2693 G_TYPE_INT, clut[5], "clut06", G_TYPE_INT, clut[6], "clut07",
2694 G_TYPE_INT, clut[7], "clut08", G_TYPE_INT, clut[8], "clut09",
2695 G_TYPE_INT, clut[9], "clut10", G_TYPE_INT, clut[10], "clut11",
2696 G_TYPE_INT, clut[11], "clut12", G_TYPE_INT, clut[12], "clut13",
2697 G_TYPE_INT, clut[13], "clut14", G_TYPE_INT, clut[14], "clut15",
2698 G_TYPE_INT, clut[15], NULL);
2700 gst_pad_push_event (stream->pad,
2701 gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM_STICKY, s));
2708 gst_matroska_demux_push_codec_data_all (GstMatroskaDemux * demux)
2712 GST_OBJECT_LOCK (demux);
2714 g_assert (demux->common.num_streams == demux->common.src->len);
2715 for (stream_nr = 0; stream_nr < demux->common.src->len; stream_nr++) {
2716 GstMatroskaTrackContext *stream;
2718 stream = g_ptr_array_index (demux->common.src, stream_nr);
2720 if (stream->send_stream_headers) {
2721 if (stream->stream_headers != NULL) {
2722 gst_matroska_demux_push_stream_headers (demux, stream);
2724 /* FIXME: perhaps we can just disable and skip this stream then */
2725 GST_ELEMENT_ERROR (demux, STREAM, DECODE, (NULL),
2726 ("Failed to extract stream headers from codec private data"));
2728 stream->send_stream_headers = FALSE;
2731 if (stream->send_dvd_event) {
2732 gst_matroska_demux_push_dvd_clut_change_event (demux, stream);
2733 /* FIXME: should we send this event again after (flushing) seek ? */
2734 stream->send_dvd_event = FALSE;
2738 GST_OBJECT_UNLOCK (demux);
2741 static GstFlowReturn
2742 gst_matroska_demux_add_mpeg_seq_header (GstElement * element,
2743 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2746 guint seq_header_len;
2747 guint32 header, tmp;
2749 if (stream->codec_state) {
2750 seq_header = stream->codec_state;
2751 seq_header_len = stream->codec_state_size;
2752 } else if (stream->codec_priv) {
2753 seq_header = stream->codec_priv;
2754 seq_header_len = stream->codec_priv_size;
2759 /* Sequence header only needed for keyframes */
2760 if (GST_BUFFER_FLAG_IS_SET (*buf, GST_BUFFER_FLAG_DELTA_UNIT))
2763 if (gst_buffer_get_size (*buf) < 4)
2766 gst_buffer_extract (*buf, 0, &tmp, sizeof (guint32));
2767 header = GUINT32_FROM_BE (tmp);
2769 /* Sequence start code, if not found prepend */
2770 if (header != 0x000001b3) {
2773 GST_DEBUG_OBJECT (element, "Prepending MPEG sequence header");
2775 newbuf = gst_buffer_new_wrapped (g_memdup (seq_header, seq_header_len),
2778 gst_buffer_copy_into (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
2779 GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_MEMORY, 0,
2780 gst_buffer_get_size (*buf));
2782 gst_buffer_unref (*buf);
2789 static GstFlowReturn
2790 gst_matroska_demux_add_wvpk_header (GstElement * element,
2791 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2793 GstMatroskaTrackAudioContext *audiocontext =
2794 (GstMatroskaTrackAudioContext *) stream;
2795 GstBuffer *newbuf = NULL;
2796 GstMapInfo map, outmap;
2797 guint8 *buf_data, *data;
2805 wvh.version = GST_READ_UINT16_LE (stream->codec_priv);
2808 wvh.total_samples = -1;
2809 wvh.block_index = audiocontext->wvpk_block_index;
2811 if (audiocontext->channels <= 2) {
2812 guint32 block_samples, tmp;
2813 gsize size = gst_buffer_get_size (*buf);
2815 gst_buffer_extract (*buf, 0, &tmp, sizeof (guint32));
2816 block_samples = GUINT32_FROM_LE (tmp);
2817 /* we need to reconstruct the header of the wavpack block */
2819 /* -20 because ck_size is the size of the wavpack block -8
2820 * and lace_size is the size of the wavpack block + 12
2821 * (the three guint32 of the header that already are in the buffer) */
2822 wvh.ck_size = size + sizeof (Wavpack4Header) - 20;
2824 /* block_samples, flags and crc are already in the buffer */
2825 newbuf = gst_buffer_new_allocate (NULL, sizeof (Wavpack4Header) - 12, NULL);
2827 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2833 GST_WRITE_UINT32_LE (data + 4, wvh.ck_size);
2834 GST_WRITE_UINT16_LE (data + 8, wvh.version);
2835 GST_WRITE_UINT8 (data + 10, wvh.track_no);
2836 GST_WRITE_UINT8 (data + 11, wvh.index_no);
2837 GST_WRITE_UINT32_LE (data + 12, wvh.total_samples);
2838 GST_WRITE_UINT32_LE (data + 16, wvh.block_index);
2840 /* Append data from buf: */
2841 gst_buffer_copy_into (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
2842 GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_MEMORY, 0, size);
2844 gst_buffer_unref (*buf);
2846 audiocontext->wvpk_block_index += block_samples;
2848 guint8 *outdata = NULL;
2850 gsize buf_size, size, out_size = 0;
2851 guint32 block_samples, flags, crc, blocksize;
2853 gst_buffer_map (*buf, &map, GST_MAP_READ);
2854 buf_data = map.data;
2855 buf_size = map.size;
2858 GST_ERROR_OBJECT (element, "Too small wavpack buffer");
2859 gst_buffer_unmap (*buf, &map);
2860 return GST_FLOW_ERROR;
2866 block_samples = GST_READ_UINT32_LE (data);
2871 flags = GST_READ_UINT32_LE (data);
2874 crc = GST_READ_UINT32_LE (data);
2877 blocksize = GST_READ_UINT32_LE (data);
2881 if (blocksize == 0 || size < blocksize)
2884 g_assert ((newbuf == NULL) == (outdata == NULL));
2886 if (newbuf == NULL) {
2887 out_size = sizeof (Wavpack4Header) + blocksize;
2888 newbuf = gst_buffer_new_allocate (NULL, out_size, NULL);
2890 gst_buffer_copy_into (newbuf, *buf,
2891 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS, 0, -1);
2894 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2895 outdata = outmap.data;
2897 gst_buffer_unmap (newbuf, &outmap);
2898 out_size += sizeof (Wavpack4Header) + blocksize;
2899 gst_buffer_set_size (newbuf, out_size);
2900 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2901 outdata = outmap.data;
2904 outdata[outpos] = 'w';
2905 outdata[outpos + 1] = 'v';
2906 outdata[outpos + 2] = 'p';
2907 outdata[outpos + 3] = 'k';
2910 GST_WRITE_UINT32_LE (outdata + outpos,
2911 blocksize + sizeof (Wavpack4Header) - 8);
2912 GST_WRITE_UINT16_LE (outdata + outpos + 4, wvh.version);
2913 GST_WRITE_UINT8 (outdata + outpos + 6, wvh.track_no);
2914 GST_WRITE_UINT8 (outdata + outpos + 7, wvh.index_no);
2915 GST_WRITE_UINT32_LE (outdata + outpos + 8, wvh.total_samples);
2916 GST_WRITE_UINT32_LE (outdata + outpos + 12, wvh.block_index);
2917 GST_WRITE_UINT32_LE (outdata + outpos + 16, block_samples);
2918 GST_WRITE_UINT32_LE (outdata + outpos + 20, flags);
2919 GST_WRITE_UINT32_LE (outdata + outpos + 24, crc);
2922 memmove (outdata + outpos, data, blocksize);
2923 outpos += blocksize;
2927 gst_buffer_unmap (*buf, &map);
2928 gst_buffer_unref (*buf);
2931 gst_buffer_unmap (newbuf, &outmap);
2934 audiocontext->wvpk_block_index += block_samples;
2940 /* @text must be null-terminated */
2942 gst_matroska_demux_subtitle_chunk_has_tag (GstElement * element,
2947 g_return_val_if_fail (text != NULL, FALSE);
2949 /* yes, this might all lead to false positives ... */
2950 tag = (gchar *) text;
2951 while ((tag = strchr (tag, '<'))) {
2953 if (*tag != '\0' && *(tag + 1) == '>') {
2954 /* some common convenience ones */
2955 /* maybe any character will do here ? */
2968 if (strstr (text, "<span"))
2974 static GstFlowReturn
2975 gst_matroska_demux_check_subtitle_buffer (GstElement * element,
2976 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2978 GstMatroskaTrackSubtitleContext *sub_stream;
2979 const gchar *encoding;
2984 gboolean needs_unmap = TRUE;
2986 sub_stream = (GstMatroskaTrackSubtitleContext *) stream;
2988 if (!gst_buffer_get_size (*buf) || !gst_buffer_map (*buf, &map, GST_MAP_READ))
2991 /* Need \0-terminator at the end */
2992 if (map.data[map.size - 1] != '\0') {
2993 newbuf = gst_buffer_new_and_alloc (map.size + 1);
2995 /* Copy old buffer and add a 0 at the end */
2996 gst_buffer_fill (newbuf, 0, map.data, map.size);
2997 gst_buffer_memset (newbuf, map.size, 0, 1);
2998 gst_buffer_unmap (*buf, &map);
3000 gst_buffer_copy_into (newbuf, *buf,
3001 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS |
3002 GST_BUFFER_COPY_META, 0, -1);
3003 gst_buffer_unref (*buf);
3005 gst_buffer_map (*buf, &map, GST_MAP_READ);
3008 if (!sub_stream->invalid_utf8) {
3009 if (g_utf8_validate ((gchar *) map.data, map.size - 1, NULL)) {
3012 GST_WARNING_OBJECT (element, "subtitle stream %" G_GUINT64_FORMAT
3013 " is not valid UTF-8, this is broken according to the matroska"
3014 " specification", stream->num);
3015 sub_stream->invalid_utf8 = TRUE;
3018 /* file with broken non-UTF8 subtitle, do the best we can do to fix it */
3019 encoding = g_getenv ("GST_SUBTITLE_ENCODING");
3020 if (encoding == NULL || *encoding == '\0') {
3021 /* if local encoding is UTF-8 and no encoding specified
3022 * via the environment variable, assume ISO-8859-15 */
3023 if (g_get_charset (&encoding)) {
3024 encoding = "ISO-8859-15";
3029 g_convert_with_fallback ((gchar *) map.data, map.size, "UTF-8", encoding,
3030 (char *) "*", NULL, NULL, &err);
3033 GST_LOG_OBJECT (element, "could not convert string from '%s' to UTF-8: %s",
3034 encoding, err->message);
3038 /* invalid input encoding, fall back to ISO-8859-15 (always succeeds) */
3039 encoding = "ISO-8859-15";
3041 g_convert_with_fallback ((gchar *) map.data, map.size, "UTF-8",
3042 encoding, (char *) "*", NULL, NULL, NULL);
3045 GST_LOG_OBJECT (element, "converted subtitle text from %s to UTF-8 %s",
3046 encoding, (err) ? "(using ISO-8859-15 as fallback)" : "");
3049 utf8 = g_strdup ("invalid subtitle");
3051 newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
3052 gst_buffer_unmap (*buf, &map);
3053 gst_buffer_copy_into (newbuf, *buf,
3054 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_META,
3056 gst_buffer_unref (*buf);
3059 gst_buffer_map (*buf, &map, GST_MAP_READ);
3063 if (sub_stream->check_markup) {
3064 /* caps claim markup text, so we need to escape text,
3065 * except if text is already markup and then needs no further escaping */
3066 sub_stream->seen_markup_tag = sub_stream->seen_markup_tag ||
3067 gst_matroska_demux_subtitle_chunk_has_tag (element, (gchar *) map.data);
3069 if (!sub_stream->seen_markup_tag) {
3070 utf8 = g_markup_escape_text ((gchar *) map.data, map.size);
3072 newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
3073 gst_buffer_unmap (*buf, &map);
3074 gst_buffer_copy_into (newbuf, *buf,
3075 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS |
3076 GST_BUFFER_COPY_META, 0, -1);
3077 gst_buffer_unref (*buf);
3080 needs_unmap = FALSE;
3085 gst_buffer_unmap (*buf, &map);
3090 static GstFlowReturn
3091 gst_matroska_demux_check_aac (GstElement * element,
3092 GstMatroskaTrackContext * stream, GstBuffer ** buf)
3097 gst_buffer_extract (*buf, 0, data, 2);
3098 size = gst_buffer_get_size (*buf);
3100 if (size > 2 && data[0] == 0xff && (data[1] >> 4 == 0x0f)) {
3103 /* tss, ADTS data, remove codec_data
3104 * still assume it is at least parsed */
3105 stream->caps = gst_caps_make_writable (stream->caps);
3106 s = gst_caps_get_structure (stream->caps, 0);
3108 gst_structure_remove_field (s, "codec_data");
3109 gst_pad_set_caps (stream->pad, stream->caps);
3110 GST_DEBUG_OBJECT (element, "ADTS AAC audio data; removing codec-data, "
3111 "new caps: %" GST_PTR_FORMAT, stream->caps);
3114 /* disable subsequent checking */
3115 stream->postprocess_frame = NULL;
3121 gst_matroska_demux_align_buffer (GstMatroskaDemux * demux,
3122 GstBuffer * buffer, gsize alignment)
3126 gst_buffer_map (buffer, &map, GST_MAP_READ);
3128 if (map.size < sizeof (guintptr)) {
3129 gst_buffer_unmap (buffer, &map);
3133 if (((guintptr) map.data) & (alignment - 1)) {
3134 GstBuffer *new_buffer;
3135 GstAllocationParams params = { 0, alignment - 1, 0, 0, };
3137 new_buffer = gst_buffer_new_allocate (NULL,
3138 gst_buffer_get_size (buffer), ¶ms);
3140 /* Copy data "by hand", so ensure alignment is kept: */
3141 gst_buffer_fill (new_buffer, 0, map.data, map.size);
3143 gst_buffer_copy_into (new_buffer, buffer, GST_BUFFER_COPY_METADATA, 0, -1);
3144 GST_DEBUG_OBJECT (demux,
3145 "We want output aligned on %" G_GSIZE_FORMAT ", reallocated",
3148 gst_buffer_unmap (buffer, &map);
3149 gst_buffer_unref (buffer);
3154 gst_buffer_unmap (buffer, &map);
3158 static GstFlowReturn
3159 gst_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux,
3160 GstEbmlRead * ebml, guint64 cluster_time, guint64 cluster_offset,
3161 gboolean is_simpleblock)
3163 GstMatroskaTrackContext *stream = NULL;
3164 GstFlowReturn ret = GST_FLOW_OK;
3165 gboolean readblock = FALSE;
3167 guint64 block_duration = -1;
3168 GstBuffer *buf = NULL;
3170 gint stream_num = -1, n, laces = 0;
3172 gint *lace_size = NULL;
3175 gint64 referenceblock = 0;
3177 GstClockTime buffer_timestamp;
3179 offset = gst_ebml_read_get_offset (ebml);
3181 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3182 if (!is_simpleblock) {
3183 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK) {
3187 id = GST_MATROSKA_ID_SIMPLEBLOCK;
3191 /* one block inside the group. Note, block parsing is one
3192 * of the harder things, so this code is a bit complicated.
3193 * See http://www.matroska.org/ for documentation. */
3194 case GST_MATROSKA_ID_SIMPLEBLOCK:
3195 case GST_MATROSKA_ID_BLOCK:
3201 gst_buffer_unmap (buf, &map);
3202 gst_buffer_unref (buf);
3205 if ((ret = gst_ebml_read_buffer (ebml, &id, &buf)) != GST_FLOW_OK)
3208 gst_buffer_map (buf, &map, GST_MAP_READ);
3212 /* first byte(s): blocknum */
3213 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
3218 /* fetch stream from num */
3219 stream_num = gst_matroska_read_common_stream_from_num (&demux->common,
3221 if (G_UNLIKELY (size < 3)) {
3222 GST_WARNING_OBJECT (demux, "Invalid size %u", size);
3223 /* non-fatal, try next block(group) */
3226 } else if (G_UNLIKELY (stream_num < 0 ||
3227 stream_num >= demux->common.num_streams)) {
3228 /* let's not give up on a stray invalid track number */
3229 GST_WARNING_OBJECT (demux,
3230 "Invalid stream %d for track number %" G_GUINT64_FORMAT
3231 "; ignoring block", stream_num, num);
3235 stream = g_ptr_array_index (demux->common.src, stream_num);
3237 /* time (relative to cluster time) */
3238 time = ((gint16) GST_READ_UINT16_BE (data));
3241 flags = GST_READ_UINT8 (data);
3245 GST_LOG_OBJECT (demux, "time %" G_GUINT64_FORMAT ", flags %d", time,
3248 switch ((flags & 0x06) >> 1) {
3249 case 0x0: /* no lacing */
3251 lace_size = g_new (gint, 1);
3252 lace_size[0] = size;
3255 case 0x1: /* xiph lacing */
3256 case 0x2: /* fixed-size lacing */
3257 case 0x3: /* EBML lacing */
3259 goto invalid_lacing;
3260 laces = GST_READ_UINT8 (data) + 1;
3263 lace_size = g_new0 (gint, laces);
3265 switch ((flags & 0x06) >> 1) {
3266 case 0x1: /* xiph lacing */ {
3267 guint temp, total = 0;
3269 for (n = 0; ret == GST_FLOW_OK && n < laces - 1; n++) {
3272 goto invalid_lacing;
3273 temp = GST_READ_UINT8 (data);
3274 lace_size[n] += temp;
3280 total += lace_size[n];
3282 lace_size[n] = size - total;
3286 case 0x2: /* fixed-size lacing */
3287 for (n = 0; n < laces; n++)
3288 lace_size[n] = size / laces;
3291 case 0x3: /* EBML lacing */ {
3294 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
3298 total = lace_size[0] = num;
3299 for (n = 1; ret == GST_FLOW_OK && n < laces - 1; n++) {
3303 if ((r = gst_matroska_ebmlnum_sint (data, size, &snum)) < 0)
3307 lace_size[n] = lace_size[n - 1] + snum;
3308 total += lace_size[n];
3311 lace_size[n] = size - total;
3318 if (ret != GST_FLOW_OK)
3325 case GST_MATROSKA_ID_BLOCKDURATION:{
3326 ret = gst_ebml_read_uint (ebml, &id, &block_duration);
3327 GST_DEBUG_OBJECT (demux, "BlockDuration: %" G_GUINT64_FORMAT,
3332 case GST_MATROSKA_ID_REFERENCEBLOCK:{
3333 ret = gst_ebml_read_sint (ebml, &id, &referenceblock);
3334 GST_DEBUG_OBJECT (demux, "ReferenceBlock: %" G_GINT64_FORMAT,
3339 case GST_MATROSKA_ID_CODECSTATE:{
3341 guint64 data_len = 0;
3344 gst_ebml_read_binary (ebml, &id, &data,
3345 &data_len)) != GST_FLOW_OK)
3348 if (G_UNLIKELY (stream == NULL)) {
3349 GST_WARNING_OBJECT (demux,
3350 "Unexpected CodecState subelement - ignoring");
3354 g_free (stream->codec_state);
3355 stream->codec_state = data;
3356 stream->codec_state_size = data_len;
3358 /* Decode if necessary */
3359 if (stream->encodings && stream->encodings->len > 0
3360 && stream->codec_state && stream->codec_state_size > 0) {
3361 if (!gst_matroska_decode_data (stream->encodings,
3362 &stream->codec_state, &stream->codec_state_size,
3363 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
3364 GST_WARNING_OBJECT (demux, "Decoding codec state failed");
3368 GST_DEBUG_OBJECT (demux, "CodecState of %" G_GSIZE_FORMAT " bytes",
3369 stream->codec_state_size);
3374 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3378 case GST_MATROSKA_ID_BLOCKVIRTUAL:
3379 case GST_MATROSKA_ID_BLOCKADDITIONS:
3380 case GST_MATROSKA_ID_REFERENCEPRIORITY:
3381 case GST_MATROSKA_ID_REFERENCEVIRTUAL:
3382 case GST_MATROSKA_ID_SLICES:
3383 GST_DEBUG_OBJECT (demux,
3384 "Skipping BlockGroup subelement 0x%x - ignoring", id);
3385 ret = gst_ebml_read_skip (ebml);
3393 /* reading a number or so could have failed */
3394 if (ret != GST_FLOW_OK)
3397 if (ret == GST_FLOW_OK && readblock) {
3398 gboolean invisible_frame = FALSE;
3399 gboolean delta_unit = FALSE;
3400 guint64 duration = 0;
3401 gint64 lace_time = 0;
3403 stream = g_ptr_array_index (demux->common.src, stream_num);
3405 if (cluster_time != GST_CLOCK_TIME_NONE) {
3406 /* FIXME: What to do with negative timestamps? Give timestamp 0 or -1?
3407 * Drop unless the lace contains timestamp 0? */
3408 if (time < 0 && (-time) > cluster_time) {
3411 if (stream->timecodescale == 1.0)
3412 lace_time = (cluster_time + time) * demux->common.time_scale;
3415 gst_util_guint64_to_gdouble ((cluster_time + time) *
3416 demux->common.time_scale) * stream->timecodescale;
3419 lace_time = GST_CLOCK_TIME_NONE;
3422 /* need to refresh segment info ASAP */
3423 if (GST_CLOCK_TIME_IS_VALID (lace_time) && demux->need_segment) {
3424 GstSegment *segment = &demux->common.segment;
3426 GstEvent *segment_event;
3428 if (!GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
3429 demux->stream_start_time = lace_time;
3430 GST_DEBUG_OBJECT (demux,
3431 "Setting stream start time to %" GST_TIME_FORMAT,
3432 GST_TIME_ARGS (lace_time));
3434 clace_time = MAX (lace_time, demux->stream_start_time);
3435 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.position) &&
3436 demux->common.segment.position != 0) {
3437 GST_DEBUG_OBJECT (demux,
3438 "using stored seek position %" GST_TIME_FORMAT,
3439 GST_TIME_ARGS (demux->common.segment.position));
3440 clace_time = demux->common.segment.position + demux->stream_start_time;
3441 segment->position = GST_CLOCK_TIME_NONE;
3443 segment->start = clace_time;
3444 segment->stop = GST_CLOCK_TIME_NONE;
3445 segment->time = segment->start - demux->stream_start_time;
3446 segment->position = segment->start - demux->stream_start_time;
3447 GST_DEBUG_OBJECT (demux,
3448 "generated segment starting at %" GST_TIME_FORMAT ": %"
3449 GST_SEGMENT_FORMAT, GST_TIME_ARGS (lace_time), segment);
3450 /* now convey our segment notion downstream */
3451 segment_event = gst_event_new_segment (segment);
3452 if (demux->segment_seqnum)
3453 gst_event_set_seqnum (segment_event, demux->segment_seqnum);
3454 gst_matroska_demux_send_event (demux, segment_event);
3455 demux->need_segment = FALSE;
3456 demux->segment_seqnum = 0;
3459 /* send pending codec data headers for all streams,
3460 * before we perform sync across all streams */
3461 gst_matroska_demux_push_codec_data_all (demux);
3463 if (block_duration != -1) {
3464 if (stream->timecodescale == 1.0)
3465 duration = gst_util_uint64_scale (block_duration,
3466 demux->common.time_scale, 1);
3469 gst_util_gdouble_to_guint64 (gst_util_guint64_to_gdouble
3470 (gst_util_uint64_scale (block_duration, demux->common.time_scale,
3471 1)) * stream->timecodescale);
3472 } else if (stream->default_duration) {
3473 duration = stream->default_duration * laces;
3475 /* else duration is diff between timecode of this and next block */
3477 /* For SimpleBlock, look at the keyframe bit in flags. Otherwise,
3478 a ReferenceBlock implies that this is not a keyframe. In either
3479 case, it only makes sense for video streams. */
3480 if (stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
3481 if ((is_simpleblock && !(flags & 0x80)) || referenceblock) {
3483 invisible_frame = ((flags & 0x08)) &&
3484 (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8) ||
3485 !strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP9));
3489 for (n = 0; n < laces; n++) {
3492 if (G_UNLIKELY (lace_size[n] > size)) {
3493 GST_WARNING_OBJECT (demux, "Invalid lace size");
3497 /* QoS for video track with an index. the assumption is that
3498 index entries point to keyframes, but if that is not true we
3499 will instad skip until the next keyframe. */
3500 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
3501 stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
3502 stream->index_table && demux->common.segment.rate > 0.0) {
3503 GstMatroskaTrackVideoContext *videocontext =
3504 (GstMatroskaTrackVideoContext *) stream;
3505 GstClockTime earliest_time;
3506 GstClockTime earliest_stream_time;
3508 GST_OBJECT_LOCK (demux);
3509 earliest_time = videocontext->earliest_time;
3510 GST_OBJECT_UNLOCK (demux);
3511 earliest_stream_time = gst_segment_to_position (&demux->common.segment,
3512 GST_FORMAT_TIME, earliest_time);
3514 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
3515 GST_CLOCK_TIME_IS_VALID (earliest_stream_time) &&
3516 lace_time <= earliest_stream_time) {
3517 /* find index entry (keyframe) <= earliest_stream_time */
3518 GstMatroskaIndex *entry =
3519 gst_util_array_binary_search (stream->index_table->data,
3520 stream->index_table->len, sizeof (GstMatroskaIndex),
3521 (GCompareDataFunc) gst_matroska_index_seek_find,
3522 GST_SEARCH_MODE_BEFORE, &earliest_stream_time, NULL);
3524 /* if that entry (keyframe) is after the current the current
3525 buffer, we can skip pushing (and thus decoding) all
3526 buffers until that keyframe. */
3527 if (entry && GST_CLOCK_TIME_IS_VALID (entry->time) &&
3528 entry->time > lace_time) {
3529 GST_LOG_OBJECT (demux, "Skipping lace before late keyframe");
3530 stream->set_discont = TRUE;
3536 sub = gst_buffer_copy_region (buf, GST_BUFFER_COPY_ALL,
3537 gst_buffer_get_size (buf) - size, lace_size[n]);
3538 GST_DEBUG_OBJECT (demux, "created subbuffer %p", sub);
3541 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
3543 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
3545 if (invisible_frame)
3546 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DECODE_ONLY);
3548 if (stream->encodings != NULL && stream->encodings->len > 0)
3549 sub = gst_matroska_decode_buffer (stream, sub);
3552 GST_WARNING_OBJECT (demux, "Decoding buffer failed");
3556 buffer_timestamp = gst_matroska_track_get_buffer_timestamp (stream, sub);
3558 if (!stream->dts_only) {
3559 GST_BUFFER_PTS (sub) = lace_time;
3561 GST_BUFFER_DTS (sub) = lace_time;
3562 if (stream->intra_only)
3563 GST_BUFFER_PTS (sub) = lace_time;
3566 if (GST_CLOCK_TIME_IS_VALID (lace_time)) {
3567 GstClockTime last_stop_end;
3569 /* Check if this stream is after segment stop */
3570 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop) &&
3571 lace_time >= demux->common.segment.stop) {
3572 GST_DEBUG_OBJECT (demux,
3573 "Stream %d after segment stop %" GST_TIME_FORMAT, stream->index,
3574 GST_TIME_ARGS (demux->common.segment.stop));
3575 gst_buffer_unref (sub);
3578 if (offset >= stream->to_offset
3579 || (GST_CLOCK_TIME_IS_VALID (demux->to_time)
3580 && lace_time > demux->to_time)) {
3581 GST_DEBUG_OBJECT (demux, "Stream %d after playback section",
3583 gst_buffer_unref (sub);
3587 /* handle gaps, e.g. non-zero start-time, or an cue index entry
3588 * that landed us with timestamps not quite intended */
3589 GST_OBJECT_LOCK (demux);
3590 if (demux->max_gap_time &&
3591 GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) &&
3592 demux->common.segment.rate > 0.0) {
3593 GstClockTimeDiff diff;
3595 /* only send segments with increasing start times,
3596 * otherwise if these go back and forth downstream (sinks) increase
3597 * accumulated time and running_time */
3598 diff = GST_CLOCK_DIFF (demux->last_stop_end, lace_time);
3599 if (diff > 0 && diff > demux->max_gap_time
3600 && lace_time > demux->common.segment.start
3601 && (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop)
3602 || lace_time < demux->common.segment.stop)) {
3604 GST_DEBUG_OBJECT (demux,
3605 "Gap of %" G_GINT64_FORMAT " ns detected in"
3606 "stream %d (%" GST_TIME_FORMAT " -> %" GST_TIME_FORMAT "). "
3607 "Sending updated SEGMENT events", diff,
3608 stream->index, GST_TIME_ARGS (stream->pos),
3609 GST_TIME_ARGS (lace_time));
3611 event = gst_event_new_gap (demux->last_stop_end, diff);
3612 GST_OBJECT_UNLOCK (demux);
3613 gst_pad_push_event (stream->pad, event);
3614 GST_OBJECT_LOCK (demux);
3618 if (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.position)
3619 || demux->common.segment.position < lace_time) {
3620 demux->common.segment.position = lace_time;
3622 GST_OBJECT_UNLOCK (demux);
3624 last_stop_end = lace_time;
3626 GST_BUFFER_DURATION (sub) = duration / laces;
3627 last_stop_end += GST_BUFFER_DURATION (sub);
3630 if (!GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) ||
3631 demux->last_stop_end < last_stop_end)
3632 demux->last_stop_end = last_stop_end;
3634 GST_OBJECT_LOCK (demux);
3635 if (demux->common.segment.duration == -1 ||
3636 demux->stream_start_time + demux->common.segment.duration <
3638 demux->common.segment.duration =
3639 last_stop_end - demux->stream_start_time;
3640 GST_OBJECT_UNLOCK (demux);
3641 if (!demux->invalid_duration) {
3642 gst_element_post_message (GST_ELEMENT_CAST (demux),
3643 gst_message_new_duration_changed (GST_OBJECT_CAST (demux)));
3644 demux->invalid_duration = TRUE;
3647 GST_OBJECT_UNLOCK (demux);
3651 stream->pos = lace_time;
3653 gst_matroska_demux_sync_streams (demux);
3655 if (stream->set_discont) {
3656 GST_DEBUG_OBJECT (demux, "marking DISCONT");
3657 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DISCONT);
3658 stream->set_discont = FALSE;
3660 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DISCONT);
3663 /* reverse playback book-keeping */
3664 if (!GST_CLOCK_TIME_IS_VALID (stream->from_time))
3665 stream->from_time = lace_time;
3666 if (stream->from_offset == -1)
3667 stream->from_offset = offset;
3669 GST_DEBUG_OBJECT (demux,
3670 "Pushing lace %d, data of size %" G_GSIZE_FORMAT
3671 " for stream %d, time=%" GST_TIME_FORMAT " and duration=%"
3672 GST_TIME_FORMAT, n, gst_buffer_get_size (sub), stream_num,
3673 GST_TIME_ARGS (buffer_timestamp),
3674 GST_TIME_ARGS (GST_BUFFER_DURATION (sub)));
3677 if (demux->common.element_index) {
3678 if (stream->index_writer_id == -1)
3679 gst_index_get_writer_id (demux->common.element_index,
3680 GST_OBJECT (stream->pad), &stream->index_writer_id);
3682 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
3683 G_GUINT64_FORMAT " for writer id %d",
3684 GST_TIME_ARGS (buffer_timestamp), cluster_offset,
3685 stream->index_writer_id);
3686 gst_index_add_association (demux->common.element_index,
3687 stream->index_writer_id, GST_BUFFER_FLAG_IS_SET (sub,
3688 GST_BUFFER_FLAG_DELTA_UNIT) ? 0 : GST_ASSOCIATION_FLAG_KEY_UNIT,
3689 GST_FORMAT_TIME, buffer_timestamp, GST_FORMAT_BYTES, cluster_offset,
3694 /* Postprocess the buffers depending on the codec used */
3695 if (stream->postprocess_frame) {
3696 GST_LOG_OBJECT (demux, "running post process");
3697 ret = stream->postprocess_frame (GST_ELEMENT (demux), stream, &sub);
3700 /* At this point, we have a sub-buffer pointing at data within a larger
3701 buffer. This data might not be aligned with anything. If the data is
3702 raw samples though, we want it aligned to the raw type (eg, 4 bytes
3703 for 32 bit samples, etc), or bad things will happen downstream as
3704 elements typically assume minimal alignment.
3705 Therefore, create an aligned copy if necessary. */
3706 g_assert (stream->alignment <= G_MEM_ALIGN);
3707 sub = gst_matroska_demux_align_buffer (demux, sub, stream->alignment);
3709 if (GST_BUFFER_PTS_IS_VALID (sub)) {
3710 stream->pos = GST_BUFFER_PTS (sub);
3711 if (GST_BUFFER_DURATION_IS_VALID (sub))
3712 stream->pos += GST_BUFFER_DURATION (sub);
3713 } else if (GST_BUFFER_DTS_IS_VALID (sub)) {
3714 stream->pos = GST_BUFFER_DTS (sub);
3715 if (GST_BUFFER_DURATION_IS_VALID (sub))
3716 stream->pos += GST_BUFFER_DURATION (sub);
3719 ret = gst_pad_push (stream->pad, sub);
3721 if (demux->common.segment.rate < 0) {
3722 if (lace_time > demux->common.segment.stop && ret == GST_FLOW_EOS) {
3723 /* In reverse playback we can get a GST_FLOW_EOS when
3724 * we are at the end of the segment, so we just need to jump
3725 * back to the previous section. */
3726 GST_DEBUG_OBJECT (demux, "downstream has reached end of segment");
3731 ret = gst_flow_combiner_update_pad_flow (demux->flowcombiner,
3735 size -= lace_size[n];
3736 if (lace_time != GST_CLOCK_TIME_NONE && duration)
3737 lace_time += duration / laces;
3739 lace_time = GST_CLOCK_TIME_NONE;
3745 gst_buffer_unmap (buf, &map);
3746 gst_buffer_unref (buf);
3758 ret = gst_flow_combiner_update_pad_flow (demux->flowcombiner, stream->pad,
3764 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Invalid lacing size"));
3765 /* non-fatal, try next block(group) */
3771 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Data error"));
3772 /* non-fatal, try next block(group) */
3778 /* return FALSE if block(group) should be skipped (due to a seek) */
3779 static inline gboolean
3780 gst_matroska_demux_seek_block (GstMatroskaDemux * demux)
3782 if (G_UNLIKELY (demux->seek_block)) {
3783 if (!(--demux->seek_block)) {
3786 GST_LOG_OBJECT (demux, "should skip block due to seek");
3794 static GstFlowReturn
3795 gst_matroska_demux_parse_contents_seekentry (GstMatroskaDemux * demux,
3799 guint64 seek_pos = (guint64) - 1;
3800 guint32 seek_id = 0;
3803 DEBUG_ELEMENT_START (demux, ebml, "Seek");
3805 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3806 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
3810 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3811 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3815 case GST_MATROSKA_ID_SEEKID:
3819 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
3822 GST_DEBUG_OBJECT (demux, "SeekID: %" G_GUINT64_FORMAT, t);
3827 case GST_MATROSKA_ID_SEEKPOSITION:
3831 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
3834 if (t > G_MAXINT64) {
3835 GST_WARNING_OBJECT (demux,
3836 "Too large SeekPosition %" G_GUINT64_FORMAT, t);
3840 GST_DEBUG_OBJECT (demux, "SeekPosition: %" G_GUINT64_FORMAT, t);
3846 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3852 if (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)
3855 if (!seek_id || seek_pos == (guint64) - 1) {
3856 GST_WARNING_OBJECT (demux, "Incomplete seekhead entry (0x%x/%"
3857 G_GUINT64_FORMAT ")", seek_id, seek_pos);
3862 case GST_MATROSKA_ID_SEEKHEAD:
3865 case GST_MATROSKA_ID_CUES:
3866 case GST_MATROSKA_ID_TAGS:
3867 case GST_MATROSKA_ID_TRACKS:
3868 case GST_MATROSKA_ID_SEGMENTINFO:
3869 case GST_MATROSKA_ID_ATTACHMENTS:
3870 case GST_MATROSKA_ID_CHAPTERS:
3872 guint64 before_pos, length;
3876 length = gst_matroska_read_common_get_length (&demux->common);
3877 before_pos = demux->common.offset;
3879 if (length == (guint64) - 1) {
3880 GST_DEBUG_OBJECT (demux, "no upstream length, skipping SeakHead entry");
3884 /* check for validity */
3885 if (seek_pos + demux->common.ebml_segment_start + 12 >= length) {
3886 GST_WARNING_OBJECT (demux,
3887 "SeekHead reference lies outside file!" " (%"
3888 G_GUINT64_FORMAT "+%" G_GUINT64_FORMAT "+12 >= %"
3889 G_GUINT64_FORMAT ")", seek_pos, demux->common.ebml_segment_start,
3894 /* only pick up index location when streaming */
3895 if (demux->streaming) {
3896 if (seek_id == GST_MATROSKA_ID_CUES) {
3897 demux->index_offset = seek_pos + demux->common.ebml_segment_start;
3898 GST_DEBUG_OBJECT (demux, "Cues located at offset %" G_GUINT64_FORMAT,
3899 demux->index_offset);
3905 demux->common.offset = seek_pos + demux->common.ebml_segment_start;
3908 if ((ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
3909 GST_ELEMENT_CAST (demux), &id, &length, &needed)) !=
3913 if (id != seek_id) {
3914 GST_WARNING_OBJECT (demux,
3915 "We looked for ID=0x%x but got ID=0x%x (pos=%" G_GUINT64_FORMAT ")",
3916 seek_id, id, seek_pos + demux->common.ebml_segment_start);
3919 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
3924 demux->common.offset = before_pos;
3928 case GST_MATROSKA_ID_CLUSTER:
3930 guint64 pos = seek_pos + demux->common.ebml_segment_start;
3932 GST_LOG_OBJECT (demux, "Cluster position");
3933 if (G_UNLIKELY (!demux->clusters))
3934 demux->clusters = g_array_sized_new (TRUE, TRUE, sizeof (guint64), 100);
3935 g_array_append_val (demux->clusters, pos);
3940 GST_DEBUG_OBJECT (demux, "Ignoring Seek entry for ID=0x%x", seek_id);
3943 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
3948 static GstFlowReturn
3949 gst_matroska_demux_parse_contents (GstMatroskaDemux * demux, GstEbmlRead * ebml)
3951 GstFlowReturn ret = GST_FLOW_OK;
3954 DEBUG_ELEMENT_START (demux, ebml, "SeekHead");
3956 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3957 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
3961 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3962 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3966 case GST_MATROSKA_ID_SEEKENTRY:
3968 ret = gst_matroska_demux_parse_contents_seekentry (demux, ebml);
3969 /* Ignore EOS and errors here */
3970 if (ret != GST_FLOW_OK) {
3971 GST_DEBUG_OBJECT (demux, "Ignoring %s", gst_flow_get_name (ret));
3978 ret = gst_matroska_read_common_parse_skip (&demux->common,
3979 ebml, "SeekHead", id);
3984 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
3986 /* Sort clusters by position for easier searching */
3987 if (demux->clusters)
3988 g_array_sort (demux->clusters, (GCompareFunc) gst_matroska_cluster_compare);
3993 #define GST_FLOW_OVERFLOW GST_FLOW_CUSTOM_ERROR
3995 #define MAX_BLOCK_SIZE (15 * 1024 * 1024)
3997 static inline GstFlowReturn
3998 gst_matroska_demux_check_read_size (GstMatroskaDemux * demux, guint64 bytes)
4000 if (G_UNLIKELY (bytes > MAX_BLOCK_SIZE)) {
4001 /* only a few blocks are expected/allowed to be large,
4002 * and will be recursed into, whereas others will be read and must fit */
4003 if (demux->streaming) {
4004 /* fatal in streaming case, as we can't step over easily */
4005 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4006 ("reading large block of size %" G_GUINT64_FORMAT " not supported; "
4007 "file might be corrupt.", bytes));
4008 return GST_FLOW_ERROR;
4010 /* indicate higher level to quietly give up */
4011 GST_DEBUG_OBJECT (demux,
4012 "too large block of size %" G_GUINT64_FORMAT, bytes);
4013 return GST_FLOW_ERROR;
4020 /* returns TRUE if we truely are in error state, and should give up */
4021 static inline GstFlowReturn
4022 gst_matroska_demux_check_parse_error (GstMatroskaDemux * demux)
4024 if (!demux->streaming && demux->next_cluster_offset > 0) {
4025 /* just repositioning to where next cluster should be and try from there */
4026 GST_WARNING_OBJECT (demux, "parse error, trying next cluster expected at %"
4027 G_GUINT64_FORMAT, demux->next_cluster_offset);
4028 demux->common.offset = demux->next_cluster_offset;
4029 demux->next_cluster_offset = 0;
4035 /* sigh, one last attempt above and beyond call of duty ...;
4036 * search for cluster mark following current pos */
4037 pos = demux->common.offset;
4038 GST_WARNING_OBJECT (demux, "parse error, looking for next cluster");
4039 if ((ret = gst_matroska_demux_search_cluster (demux, &pos)) != GST_FLOW_OK) {
4040 /* did not work, give up */
4043 GST_DEBUG_OBJECT (demux, "... found at %" G_GUINT64_FORMAT, pos);
4044 /* try that position */
4045 demux->common.offset = pos;
4051 static inline GstFlowReturn
4052 gst_matroska_demux_flush (GstMatroskaDemux * demux, guint flush)
4054 GST_LOG_OBJECT (demux, "skipping %d bytes", flush);
4055 demux->common.offset += flush;
4056 if (demux->streaming) {
4059 /* hard to skip large blocks when streaming */
4060 ret = gst_matroska_demux_check_read_size (demux, flush);
4061 if (ret != GST_FLOW_OK)
4063 if (flush <= gst_adapter_available (demux->common.adapter))
4064 gst_adapter_flush (demux->common.adapter, flush);
4066 return GST_FLOW_EOS;
4071 /* initializes @ebml with @bytes from input stream at current offset.
4072 * Returns EOS if insufficient available,
4073 * ERROR if too much was attempted to read. */
4074 static inline GstFlowReturn
4075 gst_matroska_demux_take (GstMatroskaDemux * demux, guint64 bytes,
4078 GstBuffer *buffer = NULL;
4079 GstFlowReturn ret = GST_FLOW_OK;
4081 GST_LOG_OBJECT (demux, "taking %" G_GUINT64_FORMAT " bytes for parsing",
4083 ret = gst_matroska_demux_check_read_size (demux, bytes);
4084 if (G_UNLIKELY (ret != GST_FLOW_OK)) {
4085 if (!demux->streaming) {
4086 /* in pull mode, we can skip */
4087 if ((ret = gst_matroska_demux_flush (demux, bytes)) == GST_FLOW_OK)
4088 ret = GST_FLOW_OVERFLOW;
4090 /* otherwise fatal */
4091 ret = GST_FLOW_ERROR;
4095 if (demux->streaming) {
4096 if (gst_adapter_available (demux->common.adapter) >= bytes)
4097 buffer = gst_adapter_take_buffer (demux->common.adapter, bytes);
4101 ret = gst_matroska_read_common_peek_bytes (&demux->common,
4102 demux->common.offset, bytes, &buffer, NULL);
4103 if (G_LIKELY (buffer)) {
4104 gst_ebml_read_init (ebml, GST_ELEMENT_CAST (demux), buffer,
4105 demux->common.offset);
4106 demux->common.offset += bytes;
4113 gst_matroska_demux_check_seekability (GstMatroskaDemux * demux)
4116 gboolean seekable = FALSE;
4117 gint64 start = -1, stop = -1;
4119 query = gst_query_new_seeking (GST_FORMAT_BYTES);
4120 if (!gst_pad_peer_query (demux->common.sinkpad, query)) {
4121 GST_DEBUG_OBJECT (demux, "seeking query failed");
4125 gst_query_parse_seeking (query, NULL, &seekable, &start, &stop);
4127 /* try harder to query upstream size if we didn't get it the first time */
4128 if (seekable && stop == -1) {
4129 GST_DEBUG_OBJECT (demux, "doing duration query to fix up unset stop");
4130 gst_pad_peer_query_duration (demux->common.sinkpad, GST_FORMAT_BYTES,
4134 /* if upstream doesn't know the size, it's likely that it's not seekable in
4135 * practice even if it technically may be seekable */
4136 if (seekable && (start != 0 || stop <= start)) {
4137 GST_DEBUG_OBJECT (demux, "seekable but unknown start/stop -> disable");
4142 GST_INFO_OBJECT (demux, "seekable: %d (%" G_GUINT64_FORMAT " - %"
4143 G_GUINT64_FORMAT ")", seekable, start, stop);
4144 demux->seekable = seekable;
4146 gst_query_unref (query);
4149 static GstFlowReturn
4150 gst_matroska_demux_find_tracks (GstMatroskaDemux * demux)
4156 GstFlowReturn ret = GST_FLOW_OK;
4158 GST_WARNING_OBJECT (demux,
4159 "Found Cluster element before Tracks, searching Tracks");
4162 before_pos = demux->common.offset;
4164 /* Search Tracks element */
4166 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4167 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4168 if (ret != GST_FLOW_OK)
4171 if (id != GST_MATROSKA_ID_TRACKS) {
4172 /* we may be skipping large cluster here, so forego size check etc */
4173 /* ... but we can't skip undefined size; force error */
4174 if (length == G_MAXUINT64) {
4175 ret = gst_matroska_demux_check_read_size (demux, length);
4178 demux->common.offset += needed;
4179 demux->common.offset += length;
4184 /* will lead to track parsing ... */
4185 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4190 demux->common.offset = before_pos;
4195 #define GST_READ_CHECK(stmt) \
4197 if (G_UNLIKELY ((ret = (stmt)) != GST_FLOW_OK)) { \
4198 if (ret == GST_FLOW_OVERFLOW) { \
4199 ret = GST_FLOW_OK; \
4205 static GstFlowReturn
4206 gst_matroska_demux_parse_id (GstMatroskaDemux * demux, guint32 id,
4207 guint64 length, guint needed)
4209 GstEbmlRead ebml = { 0, };
4210 GstFlowReturn ret = GST_FLOW_OK;
4213 GST_LOG_OBJECT (demux, "Parsing Element id 0x%x, "
4214 "size %" G_GUINT64_FORMAT ", prefix %d", id, length, needed);
4216 /* if we plan to read and parse this element, we need prefix (id + length)
4217 * and the contents */
4218 /* mind about overflow wrap-around when dealing with undefined size */
4220 if (G_LIKELY (length != G_MAXUINT64))
4223 switch (demux->common.state) {
4224 case GST_MATROSKA_READ_STATE_START:
4226 case GST_EBML_ID_HEADER:
4227 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4228 ret = gst_matroska_read_common_parse_header (&demux->common, &ebml);
4229 if (ret != GST_FLOW_OK)
4231 demux->common.state = GST_MATROSKA_READ_STATE_SEGMENT;
4232 gst_matroska_demux_check_seekability (demux);
4235 goto invalid_header;
4239 case GST_MATROSKA_READ_STATE_SEGMENT:
4241 case GST_MATROSKA_ID_SEGMENT:
4242 /* eat segment prefix */
4243 GST_READ_CHECK (gst_matroska_demux_flush (demux, needed));
4244 GST_DEBUG_OBJECT (demux,
4245 "Found Segment start at offset %" G_GUINT64_FORMAT " with size %"
4246 G_GUINT64_FORMAT, demux->common.offset, length);
4247 /* seeks are from the beginning of the segment,
4248 * after the segment ID/length */
4249 demux->common.ebml_segment_start = demux->common.offset;
4251 length = G_MAXUINT64;
4252 demux->common.ebml_segment_length = length;
4253 demux->common.state = GST_MATROSKA_READ_STATE_HEADER;
4256 GST_WARNING_OBJECT (demux,
4257 "Expected a Segment ID (0x%x), but received 0x%x!",
4258 GST_MATROSKA_ID_SEGMENT, id);
4259 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4263 case GST_MATROSKA_READ_STATE_SCANNING:
4264 if (id != GST_MATROSKA_ID_CLUSTER &&
4265 id != GST_MATROSKA_ID_CLUSTERTIMECODE)
4268 case GST_MATROSKA_READ_STATE_HEADER:
4269 case GST_MATROSKA_READ_STATE_DATA:
4270 case GST_MATROSKA_READ_STATE_SEEK:
4272 case GST_MATROSKA_ID_SEGMENTINFO:
4273 if (!demux->common.segmentinfo_parsed) {
4274 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4275 ret = gst_matroska_read_common_parse_info (&demux->common,
4276 GST_ELEMENT_CAST (demux), &ebml);
4277 if (ret == GST_FLOW_OK)
4278 gst_matroska_demux_send_tags (demux);
4280 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4283 case GST_MATROSKA_ID_TRACKS:
4284 if (!demux->tracks_parsed) {
4285 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4286 ret = gst_matroska_demux_parse_tracks (demux, &ebml);
4288 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4291 case GST_MATROSKA_ID_CLUSTER:
4292 if (G_UNLIKELY (!demux->tracks_parsed)) {
4293 if (demux->streaming) {
4294 GST_DEBUG_OBJECT (demux, "Cluster before Track");
4295 goto not_streamable;
4297 ret = gst_matroska_demux_find_tracks (demux);
4298 if (!demux->tracks_parsed)
4302 if (G_UNLIKELY (demux->common.state
4303 == GST_MATROSKA_READ_STATE_HEADER)) {
4304 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
4305 demux->first_cluster_offset = demux->common.offset;
4306 GST_DEBUG_OBJECT (demux, "signaling no more pads");
4307 gst_element_no_more_pads (GST_ELEMENT (demux));
4308 /* send initial segment - we wait till we know the first
4309 incoming timestamp, so we can properly set the start of
4311 demux->need_segment = TRUE;
4313 demux->cluster_time = GST_CLOCK_TIME_NONE;
4314 demux->cluster_offset = demux->common.offset;
4315 if (G_UNLIKELY (!demux->seek_first && demux->seek_block)) {
4316 GST_DEBUG_OBJECT (demux, "seek target block %" G_GUINT64_FORMAT
4317 " not found in Cluster, trying next Cluster's first block instead",
4319 demux->seek_block = 0;
4321 demux->seek_first = FALSE;
4322 /* record next cluster for recovery */
4323 if (read != G_MAXUINT64)
4324 demux->next_cluster_offset = demux->cluster_offset + read;
4325 /* eat cluster prefix */
4326 gst_matroska_demux_flush (demux, needed);
4328 case GST_MATROSKA_ID_CLUSTERTIMECODE:
4332 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4333 if ((ret = gst_ebml_read_uint (&ebml, &id, &num)) != GST_FLOW_OK)
4335 GST_DEBUG_OBJECT (demux, "ClusterTimeCode: %" G_GUINT64_FORMAT, num);
4336 demux->cluster_time = num;
4338 if (demux->common.element_index) {
4339 if (demux->common.element_index_writer_id == -1)
4340 gst_index_get_writer_id (demux->common.element_index,
4341 GST_OBJECT (demux), &demux->common.element_index_writer_id);
4342 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
4343 G_GUINT64_FORMAT " for writer id %d",
4344 GST_TIME_ARGS (demux->cluster_time), demux->cluster_offset,
4345 demux->common.element_index_writer_id);
4346 gst_index_add_association (demux->common.element_index,
4347 demux->common.element_index_writer_id,
4348 GST_ASSOCIATION_FLAG_KEY_UNIT,
4349 GST_FORMAT_TIME, demux->cluster_time,
4350 GST_FORMAT_BYTES, demux->cluster_offset, NULL);
4355 case GST_MATROSKA_ID_BLOCKGROUP:
4356 if (!gst_matroska_demux_seek_block (demux))
4358 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4359 DEBUG_ELEMENT_START (demux, &ebml, "BlockGroup");
4360 if ((ret = gst_ebml_read_master (&ebml, &id)) == GST_FLOW_OK) {
4361 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4362 &ebml, demux->cluster_time, demux->cluster_offset, FALSE);
4364 DEBUG_ELEMENT_STOP (demux, &ebml, "BlockGroup", ret);
4366 case GST_MATROSKA_ID_SIMPLEBLOCK:
4367 if (!gst_matroska_demux_seek_block (demux))
4369 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4370 DEBUG_ELEMENT_START (demux, &ebml, "SimpleBlock");
4371 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4372 &ebml, demux->cluster_time, demux->cluster_offset, TRUE);
4373 DEBUG_ELEMENT_STOP (demux, &ebml, "SimpleBlock", ret);
4375 case GST_MATROSKA_ID_ATTACHMENTS:
4376 if (!demux->common.attachments_parsed) {
4377 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4378 ret = gst_matroska_read_common_parse_attachments (&demux->common,
4379 GST_ELEMENT_CAST (demux), &ebml);
4380 if (ret == GST_FLOW_OK)
4381 gst_matroska_demux_send_tags (demux);
4383 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4386 case GST_MATROSKA_ID_TAGS:
4387 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4388 ret = gst_matroska_read_common_parse_metadata (&demux->common,
4389 GST_ELEMENT_CAST (demux), &ebml);
4390 if (ret == GST_FLOW_OK)
4391 gst_matroska_demux_send_tags (demux);
4393 case GST_MATROSKA_ID_CHAPTERS:
4394 if (!demux->common.chapters_parsed) {
4395 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4397 gst_matroska_read_common_parse_chapters (&demux->common, &ebml);
4399 if (demux->common.toc) {
4400 gst_matroska_demux_send_event (demux,
4401 gst_event_new_toc (demux->common.toc, FALSE));
4404 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4406 case GST_MATROSKA_ID_SEEKHEAD:
4407 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4408 ret = gst_matroska_demux_parse_contents (demux, &ebml);
4410 case GST_MATROSKA_ID_CUES:
4411 if (demux->common.index_parsed) {
4412 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4415 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4416 ret = gst_matroska_read_common_parse_index (&demux->common, &ebml);
4417 /* only push based; delayed index building */
4418 if (ret == GST_FLOW_OK
4419 && demux->common.state == GST_MATROSKA_READ_STATE_SEEK) {
4422 GST_OBJECT_LOCK (demux);
4423 event = demux->seek_event;
4424 demux->seek_event = NULL;
4425 GST_OBJECT_UNLOCK (demux);
4428 /* unlikely to fail, since we managed to seek to this point */
4429 if (!gst_matroska_demux_handle_seek_event (demux, NULL, event)) {
4430 gst_event_unref (event);
4433 gst_event_unref (event);
4434 /* resume data handling, main thread clear to seek again */
4435 GST_OBJECT_LOCK (demux);
4436 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
4437 GST_OBJECT_UNLOCK (demux);
4440 case GST_MATROSKA_ID_POSITION:
4441 case GST_MATROSKA_ID_PREVSIZE:
4442 case GST_MATROSKA_ID_ENCRYPTEDBLOCK:
4443 case GST_MATROSKA_ID_SILENTTRACKS:
4444 GST_DEBUG_OBJECT (demux,
4445 "Skipping Cluster subelement 0x%x - ignoring", id);
4449 GST_DEBUG_OBJECT (demux, "skipping Element 0x%x", id);
4450 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4456 if (ret == GST_FLOW_PARSE)
4460 gst_ebml_read_clear (&ebml);
4466 /* simply exit, maybe not enough data yet */
4467 /* no ebml to clear if read error */
4472 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4473 ("Failed to parse Element 0x%x", id));
4474 ret = GST_FLOW_ERROR;
4479 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4480 ("File layout does not permit streaming"));
4481 ret = GST_FLOW_ERROR;
4486 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4487 ("No Tracks element found"));
4488 ret = GST_FLOW_ERROR;
4493 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Invalid header"));
4494 ret = GST_FLOW_ERROR;
4499 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Failed to seek"));
4500 ret = GST_FLOW_ERROR;
4506 gst_matroska_demux_loop (GstPad * pad)
4508 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (pad));
4514 /* If we have to close a segment, send a new segment to do this now */
4515 if (G_LIKELY (demux->common.state == GST_MATROSKA_READ_STATE_DATA)) {
4516 if (G_UNLIKELY (demux->new_segment)) {
4517 gst_matroska_demux_send_event (demux, demux->new_segment);
4518 demux->new_segment = NULL;
4522 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4523 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4524 if (ret == GST_FLOW_EOS) {
4526 } else if (ret == GST_FLOW_FLUSHING) {
4528 } else if (ret != GST_FLOW_OK) {
4529 ret = gst_matroska_demux_check_parse_error (demux);
4531 /* Only handle EOS as no error if we're outside the segment already */
4532 if (ret == GST_FLOW_EOS && (demux->common.ebml_segment_length != G_MAXUINT64
4533 && demux->common.offset >=
4534 demux->common.ebml_segment_start +
4535 demux->common.ebml_segment_length))
4537 else if (ret != GST_FLOW_OK)
4543 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
4544 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
4547 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4548 if (ret == GST_FLOW_EOS)
4550 if (ret != GST_FLOW_OK)
4553 /* check if we're at the end of a configured segment */
4554 if (G_LIKELY (demux->common.src->len)) {
4557 g_assert (demux->common.num_streams == demux->common.src->len);
4558 for (i = 0; i < demux->common.src->len; i++) {
4559 GstMatroskaTrackContext *context = g_ptr_array_index (demux->common.src,
4561 GST_DEBUG_OBJECT (context->pad, "pos %" GST_TIME_FORMAT,
4562 GST_TIME_ARGS (context->pos));
4563 if (context->eos == FALSE)
4567 GST_INFO_OBJECT (demux, "All streams are EOS");
4573 if (G_UNLIKELY (demux->cached_length == G_MAXUINT64 ||
4574 demux->common.offset >= demux->cached_length)) {
4575 demux->cached_length = gst_matroska_read_common_get_length (&demux->common);
4576 if (demux->common.offset == demux->cached_length) {
4577 GST_LOG_OBJECT (demux, "Reached end of stream");
4588 if (demux->common.segment.rate < 0.0) {
4589 ret = gst_matroska_demux_seek_to_previous_keyframe (demux);
4590 if (ret == GST_FLOW_OK)
4597 const gchar *reason = gst_flow_get_name (ret);
4598 gboolean push_eos = FALSE;
4600 GST_LOG_OBJECT (demux, "pausing task, reason %s", reason);
4601 gst_pad_pause_task (demux->common.sinkpad);
4603 if (ret == GST_FLOW_EOS) {
4604 /* perform EOS logic */
4606 /* If we were in the headers, make sure we send no-more-pads.
4607 This will ensure decodebin2 does not get stuck thinking
4608 the chain is not complete yet, and waiting indefinitely. */
4609 if (G_UNLIKELY (demux->common.state == GST_MATROSKA_READ_STATE_HEADER)) {
4610 if (demux->common.src->len == 0) {
4611 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
4612 ("No pads created"));
4614 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL),
4615 ("Failed to finish reading headers"));
4617 gst_element_no_more_pads (GST_ELEMENT (demux));
4620 if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
4623 /* for segment playback we need to post when (in stream time)
4624 * we stopped, this is either stop (when set) or the duration. */
4625 if ((stop = demux->common.segment.stop) == -1)
4626 stop = demux->last_stop_end;
4628 GST_LOG_OBJECT (demux, "Sending segment done, at end of segment");
4629 gst_element_post_message (GST_ELEMENT (demux),
4630 gst_message_new_segment_done (GST_OBJECT (demux), GST_FORMAT_TIME,
4632 gst_matroska_demux_send_event (demux,
4633 gst_event_new_segment_done (GST_FORMAT_TIME, stop));
4637 } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS) {
4638 /* for fatal errors we post an error message */
4639 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
4640 ("stream stopped, reason %s", reason));
4644 /* send EOS, and prevent hanging if no streams yet */
4645 GST_LOG_OBJECT (demux, "Sending EOS, at end of stream");
4646 if (!gst_matroska_demux_send_event (demux, gst_event_new_eos ()) &&
4647 (ret == GST_FLOW_EOS)) {
4648 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4649 (NULL), ("got eos but no streams (yet)"));
4657 * Create and push a flushing seek event upstream
4660 perform_seek_to_offset (GstMatroskaDemux * demux, gdouble rate, guint64 offset,
4666 GST_DEBUG_OBJECT (demux, "Seeking to %" G_GUINT64_FORMAT, offset);
4669 gst_event_new_seek (rate, GST_FORMAT_BYTES,
4670 GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, GST_SEEK_TYPE_SET, offset,
4671 GST_SEEK_TYPE_NONE, -1);
4672 gst_event_set_seqnum (event, seqnum);
4674 res = gst_pad_push_event (demux->common.sinkpad, event);
4676 /* segment event will update offset */
4680 static GstFlowReturn
4681 gst_matroska_demux_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
4683 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4685 GstFlowReturn ret = GST_FLOW_OK;
4690 if (G_UNLIKELY (GST_BUFFER_IS_DISCONT (buffer))) {
4691 GST_DEBUG_OBJECT (demux, "got DISCONT");
4692 gst_adapter_clear (demux->common.adapter);
4693 GST_OBJECT_LOCK (demux);
4694 gst_matroska_read_common_reset_streams (&demux->common,
4695 GST_CLOCK_TIME_NONE, FALSE);
4696 GST_OBJECT_UNLOCK (demux);
4699 gst_adapter_push (demux->common.adapter, buffer);
4703 available = gst_adapter_available (demux->common.adapter);
4705 ret = gst_matroska_read_common_peek_id_length_push (&demux->common,
4706 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4707 if (G_UNLIKELY (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)) {
4708 if (demux->common.ebml_segment_length != G_MAXUINT64
4709 && demux->common.offset >=
4710 demux->common.ebml_segment_start + demux->common.ebml_segment_length)
4715 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
4716 "size %" G_GUINT64_FORMAT ", needed %d, available %d",
4717 demux->common.offset, id, length, needed, available);
4719 if (needed > available)
4722 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4723 if (ret == GST_FLOW_EOS) {
4724 /* need more data */
4726 } else if (ret != GST_FLOW_OK) {
4733 gst_matroska_demux_handle_sink_event (GstPad * pad, GstObject * parent,
4736 gboolean res = TRUE;
4737 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4739 GST_DEBUG_OBJECT (demux,
4740 "have event type %s: %p on sink pad", GST_EVENT_TYPE_NAME (event), event);
4742 switch (GST_EVENT_TYPE (event)) {
4743 case GST_EVENT_SEGMENT:
4745 const GstSegment *segment;
4747 /* some debug output */
4748 gst_event_parse_segment (event, &segment);
4749 /* FIXME: do we need to update segment base here (like accum in 0.10)? */
4750 GST_DEBUG_OBJECT (demux,
4751 "received format %d segment %" GST_SEGMENT_FORMAT, segment->format,
4754 if (demux->common.state < GST_MATROSKA_READ_STATE_DATA) {
4755 GST_DEBUG_OBJECT (demux, "still starting");
4759 /* we only expect a BYTE segment, e.g. following a seek */
4760 if (segment->format != GST_FORMAT_BYTES) {
4761 GST_DEBUG_OBJECT (demux, "unsupported segment format, ignoring");
4765 GST_DEBUG_OBJECT (demux, "clearing segment state");
4766 GST_OBJECT_LOCK (demux);
4767 /* clear current segment leftover */
4768 gst_adapter_clear (demux->common.adapter);
4769 /* and some streaming setup */
4770 demux->common.offset = segment->start;
4771 /* accumulate base based on current position */
4772 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.position))
4773 demux->common.segment.base +=
4774 (MAX (demux->common.segment.position, demux->stream_start_time)
4775 - demux->stream_start_time) / fabs (demux->common.segment.rate);
4776 /* do not know where we are;
4777 * need to come across a cluster and generate segment */
4778 demux->common.segment.position = GST_CLOCK_TIME_NONE;
4779 demux->cluster_time = GST_CLOCK_TIME_NONE;
4780 demux->cluster_offset = 0;
4781 demux->need_segment = TRUE;
4782 demux->segment_seqnum = gst_event_get_seqnum (event);
4783 /* but keep some of the upstream segment */
4784 demux->common.segment.rate = segment->rate;
4785 /* also check if need to keep some of the requested seek position */
4786 if (demux->seek_offset == segment->start) {
4787 GST_DEBUG_OBJECT (demux, "position matches requested seek");
4788 demux->common.segment.position = demux->requested_seek_time;
4790 GST_DEBUG_OBJECT (demux, "unexpected segment position");
4792 demux->requested_seek_time = GST_CLOCK_TIME_NONE;
4793 demux->seek_offset = -1;
4794 GST_OBJECT_UNLOCK (demux);
4796 /* chain will send initial segment after pads have been added,
4797 * or otherwise come up with one */
4798 GST_DEBUG_OBJECT (demux, "eating event");
4799 gst_event_unref (event);
4805 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
4806 gst_event_unref (event);
4807 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4808 (NULL), ("got eos and didn't receive a complete header object"));
4809 } else if (demux->common.num_streams == 0) {
4810 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4811 (NULL), ("got eos but no streams (yet)"));
4813 gst_matroska_demux_send_event (demux, event);
4817 case GST_EVENT_FLUSH_STOP:
4821 gst_adapter_clear (demux->common.adapter);
4822 GST_OBJECT_LOCK (demux);
4823 gst_matroska_read_common_reset_streams (&demux->common,
4824 GST_CLOCK_TIME_NONE, TRUE);
4825 gst_flow_combiner_reset (demux->flowcombiner);
4826 dur = demux->common.segment.duration;
4827 gst_segment_init (&demux->common.segment, GST_FORMAT_TIME);
4828 demux->common.segment.duration = dur;
4829 demux->cluster_time = GST_CLOCK_TIME_NONE;
4830 demux->cluster_offset = 0;
4831 GST_OBJECT_UNLOCK (demux);
4835 res = gst_pad_event_default (pad, parent, event);
4843 gst_matroska_demux_sink_activate (GstPad * sinkpad, GstObject * parent)
4845 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4847 gboolean pull_mode = FALSE;
4849 query = gst_query_new_scheduling ();
4851 if (gst_pad_peer_query (sinkpad, query))
4852 pull_mode = gst_query_has_scheduling_mode_with_flags (query,
4853 GST_PAD_MODE_PULL, GST_SCHEDULING_FLAG_SEEKABLE);
4855 gst_query_unref (query);
4858 GST_DEBUG ("going to pull mode");
4859 demux->streaming = FALSE;
4860 return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PULL, TRUE);
4862 GST_DEBUG ("going to push (streaming) mode");
4863 demux->streaming = TRUE;
4864 return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PUSH, TRUE);
4869 gst_matroska_demux_sink_activate_mode (GstPad * sinkpad, GstObject * parent,
4870 GstPadMode mode, gboolean active)
4873 case GST_PAD_MODE_PULL:
4875 /* if we have a scheduler we can start the task */
4876 gst_pad_start_task (sinkpad, (GstTaskFunction) gst_matroska_demux_loop,
4879 gst_pad_stop_task (sinkpad);
4882 case GST_PAD_MODE_PUSH:
4890 gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext *
4891 videocontext, const gchar * codec_id, guint8 * data, guint size,
4892 gchar ** codec_name, guint32 * riff_fourcc)
4894 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) videocontext;
4895 GstCaps *caps = NULL;
4897 g_assert (videocontext != NULL);
4898 g_assert (codec_name != NULL);
4903 /* TODO: check if we have all codec types from matroska-ids.h
4904 * check if we have to do more special things with codec_private
4907 * GST_MATROSKA_CODEC_ID_VIDEO_QUICKTIME
4908 * GST_MATROSKA_CODEC_ID_VIDEO_SNOW
4911 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VFW_FOURCC)) {
4912 gst_riff_strf_vids *vids = NULL;
4915 GstBuffer *buf = NULL;
4917 vids = (gst_riff_strf_vids *) data;
4919 /* assure size is big enough */
4921 GST_WARNING ("Too small BITMAPINFOHEADER (%d bytes)", size);
4924 if (size < sizeof (gst_riff_strf_vids)) {
4925 vids = g_new (gst_riff_strf_vids, 1);
4926 memcpy (vids, data, size);
4929 context->dts_only = TRUE; /* VFW files only store DTS */
4931 /* little-endian -> byte-order */
4932 vids->size = GUINT32_FROM_LE (vids->size);
4933 vids->width = GUINT32_FROM_LE (vids->width);
4934 vids->height = GUINT32_FROM_LE (vids->height);
4935 vids->planes = GUINT16_FROM_LE (vids->planes);
4936 vids->bit_cnt = GUINT16_FROM_LE (vids->bit_cnt);
4937 vids->compression = GUINT32_FROM_LE (vids->compression);
4938 vids->image_size = GUINT32_FROM_LE (vids->image_size);
4939 vids->xpels_meter = GUINT32_FROM_LE (vids->xpels_meter);
4940 vids->ypels_meter = GUINT32_FROM_LE (vids->ypels_meter);
4941 vids->num_colors = GUINT32_FROM_LE (vids->num_colors);
4942 vids->imp_colors = GUINT32_FROM_LE (vids->imp_colors);
4944 if (size > sizeof (gst_riff_strf_vids)) { /* some extra_data */
4945 gsize offset = sizeof (gst_riff_strf_vids);
4948 gst_buffer_new_wrapped (g_memdup ((guint8 *) vids + offset,
4949 size - offset), size - offset);
4953 *riff_fourcc = vids->compression;
4955 caps = gst_riff_create_video_caps (vids->compression, NULL, vids,
4956 buf, NULL, codec_name);
4959 GST_WARNING ("Unhandled RIFF fourcc %" GST_FOURCC_FORMAT,
4960 GST_FOURCC_ARGS (vids->compression));
4962 static GstStaticCaps intra_caps = GST_STATIC_CAPS ("image/jpeg; "
4963 "video/x-raw; image/png; video/x-dv; video/x-huffyuv; video/x-ffv; "
4964 "video/x-compressed-yuv");
4965 context->intra_only =
4966 gst_caps_can_intersect (gst_static_caps_get (&intra_caps), caps);
4970 gst_buffer_unref (buf);
4972 if (vids != (gst_riff_strf_vids *) data)
4975 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_UNCOMPRESSED)) {
4977 GstVideoFormat format;
4979 gst_video_info_init (&info);
4980 switch (videocontext->fourcc) {
4981 case GST_MAKE_FOURCC ('I', '4', '2', '0'):
4982 format = GST_VIDEO_FORMAT_I420;
4984 case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
4985 format = GST_VIDEO_FORMAT_YUY2;
4987 case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
4988 format = GST_VIDEO_FORMAT_YV12;
4990 case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
4991 format = GST_VIDEO_FORMAT_UYVY;
4993 case GST_MAKE_FOURCC ('A', 'Y', 'U', 'V'):
4994 format = GST_VIDEO_FORMAT_AYUV;
4996 case GST_MAKE_FOURCC ('Y', '8', '0', '0'):
4997 case GST_MAKE_FOURCC ('Y', '8', ' ', ' '):
4998 format = GST_VIDEO_FORMAT_GRAY8;
5000 case GST_MAKE_FOURCC ('R', 'G', 'B', 24):
5001 format = GST_VIDEO_FORMAT_RGB;
5003 case GST_MAKE_FOURCC ('B', 'G', 'R', 24):
5004 format = GST_VIDEO_FORMAT_BGR;
5007 GST_DEBUG ("Unknown fourcc %" GST_FOURCC_FORMAT,
5008 GST_FOURCC_ARGS (videocontext->fourcc));
5012 context->intra_only = TRUE;
5014 gst_video_info_set_format (&info, format, videocontext->pixel_width,
5015 videocontext->pixel_height);
5016 caps = gst_video_info_to_caps (&info);
5017 *codec_name = gst_pb_utils_get_codec_description (caps);
5018 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_SP)) {
5019 caps = gst_caps_new_simple ("video/x-divx",
5020 "divxversion", G_TYPE_INT, 4, NULL);
5021 *codec_name = g_strdup ("MPEG-4 simple profile");
5022 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP) ||
5023 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AP)) {
5024 caps = gst_caps_new_simple ("video/mpeg",
5025 "mpegversion", G_TYPE_INT, 4,
5026 "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
5030 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
5031 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5032 gst_buffer_unref (priv);
5034 gst_codec_utils_mpeg4video_caps_set_level_and_profile (caps, data, size);
5036 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP))
5037 *codec_name = g_strdup ("MPEG-4 advanced simple profile");
5039 *codec_name = g_strdup ("MPEG-4 advanced profile");
5040 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MSMPEG4V3)) {
5042 caps = gst_caps_new_full (gst_structure_new ("video/x-divx",
5043 "divxversion", G_TYPE_INT, 3, NULL),
5044 gst_structure_new ("video/x-msmpeg",
5045 "msmpegversion", G_TYPE_INT, 43, NULL), NULL);
5047 caps = gst_caps_new_simple ("video/x-msmpeg",
5048 "msmpegversion", G_TYPE_INT, 43, NULL);
5049 *codec_name = g_strdup ("Microsoft MPEG-4 v.3");
5050 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1) ||
5051 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG2)) {
5054 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1))
5059 caps = gst_caps_new_simple ("video/mpeg",
5060 "systemstream", G_TYPE_BOOLEAN, FALSE,
5061 "mpegversion", G_TYPE_INT, mpegversion, NULL);
5062 *codec_name = g_strdup_printf ("MPEG-%d video", mpegversion);
5063 context->postprocess_frame = gst_matroska_demux_add_mpeg_seq_header;
5064 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MJPEG)) {
5065 caps = gst_caps_new_empty_simple ("image/jpeg");
5066 *codec_name = g_strdup ("Motion-JPEG");
5067 context->intra_only = TRUE;
5068 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AVC)) {
5069 caps = gst_caps_new_empty_simple ("video/x-h264");
5073 /* First byte is the version, second is the profile indication, and third
5074 * is the 5 contraint_set_flags and 3 reserved bits. Fourth byte is the
5075 * level indication. */
5076 gst_codec_utils_h264_caps_set_level_and_profile (caps, data + 1,
5079 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
5080 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5081 gst_buffer_unref (priv);
5083 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "avc",
5084 "alignment", G_TYPE_STRING, "au", NULL);
5086 GST_WARNING ("No codec data found, assuming output is byte-stream");
5087 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
5090 *codec_name = g_strdup ("H264");
5091 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEGH_HEVC)) {
5092 caps = gst_caps_new_empty_simple ("video/x-h265");
5096 gst_codec_utils_h265_caps_set_level_tier_and_profile (caps, data + 1,
5099 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
5100 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5101 gst_buffer_unref (priv);
5103 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "hvc1",
5104 "alignment", G_TYPE_STRING, "au", NULL);
5106 GST_WARNING ("No codec data found, assuming output is byte-stream");
5107 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
5110 *codec_name = g_strdup ("HEVC");
5111 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1)) ||
5112 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2)) ||
5113 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3)) ||
5114 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))) {
5115 gint rmversion = -1;
5117 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1))
5119 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2))
5121 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3))
5123 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))
5126 caps = gst_caps_new_simple ("video/x-pn-realvideo",
5127 "rmversion", G_TYPE_INT, rmversion, NULL);
5128 GST_DEBUG ("data:%p, size:0x%x", data, size);
5129 /* We need to extract the extradata ! */
5130 if (data && (size >= 0x22)) {
5135 subformat = GST_READ_UINT32_BE (data + 0x1a);
5136 rformat = GST_READ_UINT32_BE (data + 0x1e);
5139 gst_buffer_new_wrapped (g_memdup (data + 0x1a, size - 0x1a),
5141 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, "format",
5142 G_TYPE_INT, rformat, "subformat", G_TYPE_INT, subformat, NULL);
5143 gst_buffer_unref (priv);
5146 *codec_name = g_strdup_printf ("RealVideo %d.0", rmversion);
5147 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_THEORA)) {
5148 caps = gst_caps_new_empty_simple ("video/x-theora");
5149 context->stream_headers =
5150 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
5151 context->codec_priv_size);
5152 /* FIXME: mark stream as broken and skip if there are no stream headers */
5153 context->send_stream_headers = TRUE;
5154 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_DIRAC)) {
5155 caps = gst_caps_new_empty_simple ("video/x-dirac");
5156 *codec_name = g_strdup_printf ("Dirac");
5157 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8)) {
5158 caps = gst_caps_new_empty_simple ("video/x-vp8");
5159 *codec_name = g_strdup_printf ("On2 VP8");
5160 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP9)) {
5161 caps = gst_caps_new_empty_simple ("video/x-vp9");
5162 *codec_name = g_strdup_printf ("On2 VP9");
5164 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
5170 GstStructure *structure;
5172 for (i = 0; i < gst_caps_get_size (caps); i++) {
5173 structure = gst_caps_get_structure (caps, i);
5175 /* FIXME: use the real unit here! */
5176 GST_DEBUG ("video size %dx%d, target display size %dx%d (any unit)",
5177 videocontext->pixel_width,
5178 videocontext->pixel_height,
5179 videocontext->display_width, videocontext->display_height);
5181 /* pixel width and height are the w and h of the video in pixels */
5182 if (videocontext->pixel_width > 0 && videocontext->pixel_height > 0) {
5183 gint w = videocontext->pixel_width;
5184 gint h = videocontext->pixel_height;
5186 gst_structure_set (structure,
5187 "width", G_TYPE_INT, w, "height", G_TYPE_INT, h, NULL);
5190 if (videocontext->display_width > 0 || videocontext->display_height > 0) {
5193 if (videocontext->display_width <= 0)
5194 videocontext->display_width = videocontext->pixel_width;
5195 if (videocontext->display_height <= 0)
5196 videocontext->display_height = videocontext->pixel_height;
5198 /* calculate the pixel aspect ratio using the display and pixel w/h */
5199 n = videocontext->display_width * videocontext->pixel_height;
5200 d = videocontext->display_height * videocontext->pixel_width;
5201 GST_DEBUG ("setting PAR to %d/%d", n, d);
5202 gst_structure_set (structure, "pixel-aspect-ratio",
5204 videocontext->display_width * videocontext->pixel_height,
5205 videocontext->display_height * videocontext->pixel_width, NULL);
5208 if (videocontext->default_fps > 0.0) {
5211 gst_util_double_to_fraction (videocontext->default_fps, &fps_n, &fps_d);
5213 GST_DEBUG ("using default fps %d/%d", fps_n, fps_d);
5215 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION, fps_n,
5217 } else if (context->default_duration > 0) {
5220 gst_video_guess_framerate (context->default_duration, &fps_n, &fps_d);
5222 GST_INFO ("using default duration %" G_GUINT64_FORMAT
5223 " framerate %d/%d", context->default_duration, fps_n, fps_d);
5225 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
5226 fps_n, fps_d, NULL);
5228 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
5232 if (videocontext->parent.flags & GST_MATROSKA_VIDEOTRACK_INTERLACED)
5233 gst_structure_set (structure, "interlace-mode", G_TYPE_STRING,
5237 caps = gst_caps_simplify (caps);
5244 * Some AAC specific code... *sigh*
5245 * FIXME: maybe we should use '15' and code the sample rate explicitly
5246 * if the sample rate doesn't match the predefined rates exactly? (tpm)
5250 aac_rate_idx (gint rate)
5254 else if (75132 <= rate)
5256 else if (55426 <= rate)
5258 else if (46009 <= rate)
5260 else if (37566 <= rate)
5262 else if (27713 <= rate)
5264 else if (23004 <= rate)
5266 else if (18783 <= rate)
5268 else if (13856 <= rate)
5270 else if (11502 <= rate)
5272 else if (9391 <= rate)
5279 aac_profile_idx (const gchar * codec_id)
5283 if (strlen (codec_id) <= 12)
5285 else if (!strncmp (&codec_id[12], "MAIN", 4))
5287 else if (!strncmp (&codec_id[12], "LC", 2))
5289 else if (!strncmp (&codec_id[12], "SSR", 3))
5298 round_up_pow2 (guint n)
5309 #define AAC_SYNC_EXTENSION_TYPE 0x02b7
5312 gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext *
5313 audiocontext, const gchar * codec_id, guint8 * data, guint size,
5314 gchar ** codec_name, guint16 * riff_audio_fmt)
5316 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) audiocontext;
5317 GstCaps *caps = NULL;
5319 g_assert (audiocontext != NULL);
5320 g_assert (codec_name != NULL);
5323 *riff_audio_fmt = 0;
5325 /* TODO: check if we have all codec types from matroska-ids.h
5326 * check if we have to do more special things with codec_private
5327 * check if we need bitdepth in different places too
5328 * implement channel position magic
5330 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID9
5331 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID10
5332 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDMC
5333 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDM2
5336 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1) ||
5337 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2) ||
5338 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L3)) {
5341 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1))
5343 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2))
5348 caps = gst_caps_new_simple ("audio/mpeg",
5349 "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, layer, NULL);
5350 *codec_name = g_strdup_printf ("MPEG-1 layer %d", layer);
5351 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE) ||
5352 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_LE)) {
5355 GstAudioFormat format;
5357 sign = (audiocontext->bitdepth != 8);
5358 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE))
5359 endianness = G_BIG_ENDIAN;
5361 endianness = G_LITTLE_ENDIAN;
5363 format = gst_audio_format_build_integer (sign, endianness,
5364 audiocontext->bitdepth, audiocontext->bitdepth);
5366 /* FIXME: Channel mask and reordering */
5367 caps = gst_caps_new_simple ("audio/x-raw",
5368 "format", G_TYPE_STRING, gst_audio_format_to_string (format),
5369 "layout", G_TYPE_STRING, "interleaved", NULL);
5371 *codec_name = g_strdup_printf ("Raw %d-bit PCM audio",
5372 audiocontext->bitdepth);
5373 context->alignment = GST_ROUND_UP_8 (audiocontext->bitdepth) / 8;
5374 context->alignment = round_up_pow2 (context->alignment);
5375 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_FLOAT)) {
5376 const gchar *format;
5377 if (audiocontext->bitdepth == 32)
5381 /* FIXME: Channel mask and reordering */
5382 caps = gst_caps_new_simple ("audio/x-raw",
5383 "format", G_TYPE_STRING, format,
5384 "layout", G_TYPE_STRING, "interleaved", NULL);
5385 *codec_name = g_strdup_printf ("Raw %d-bit floating-point audio",
5386 audiocontext->bitdepth);
5387 context->alignment = audiocontext->bitdepth / 8;
5388 context->alignment = round_up_pow2 (context->alignment);
5389 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AC3,
5390 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AC3))) {
5391 caps = gst_caps_new_simple ("audio/x-ac3",
5392 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5393 *codec_name = g_strdup ("AC-3 audio");
5394 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_EAC3,
5395 strlen (GST_MATROSKA_CODEC_ID_AUDIO_EAC3))) {
5396 caps = gst_caps_new_simple ("audio/x-eac3",
5397 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5398 *codec_name = g_strdup ("E-AC-3 audio");
5399 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TRUEHD,
5400 strlen (GST_MATROSKA_CODEC_ID_AUDIO_TRUEHD))) {
5401 caps = gst_caps_new_empty_simple ("audio/x-true-hd");
5402 *codec_name = g_strdup ("Dolby TrueHD");
5403 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_DTS)) {
5404 caps = gst_caps_new_empty_simple ("audio/x-dts");
5405 *codec_name = g_strdup ("DTS audio");
5406 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_VORBIS)) {
5407 caps = gst_caps_new_empty_simple ("audio/x-vorbis");
5408 context->stream_headers =
5409 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
5410 context->codec_priv_size);
5411 /* FIXME: mark stream as broken and skip if there are no stream headers */
5412 context->send_stream_headers = TRUE;
5413 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_FLAC)) {
5414 caps = gst_caps_new_empty_simple ("audio/x-flac");
5415 context->stream_headers =
5416 gst_matroska_parse_flac_stream_headers (context->codec_priv,
5417 context->codec_priv_size);
5418 /* FIXME: mark stream as broken and skip if there are no stream headers */
5419 context->send_stream_headers = TRUE;
5420 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_SPEEX)) {
5421 caps = gst_caps_new_empty_simple ("audio/x-speex");
5422 context->stream_headers =
5423 gst_matroska_parse_speex_stream_headers (context->codec_priv,
5424 context->codec_priv_size);
5425 /* FIXME: mark stream as broken and skip if there are no stream headers */
5426 context->send_stream_headers = TRUE;
5427 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_OPUS)) {
5428 caps = gst_caps_new_empty_simple ("audio/x-opus");
5429 *codec_name = g_strdup ("Opus");
5430 context->stream_headers =
5431 gst_matroska_parse_opus_stream_headers (context->codec_priv,
5432 context->codec_priv_size);
5433 if (context->stream_headers) {
5434 /* There was a valid header. Multistream headers are more than
5435 * 19 bytes, as they include an extra channel mapping table. */
5436 gboolean multistream = (context->codec_priv_size > 19);
5437 gst_caps_set_simple (caps, "multistream", G_TYPE_BOOLEAN, multistream,
5440 /* FIXME: mark stream as broken and skip if there are no stream headers */
5441 context->send_stream_headers = TRUE;
5442 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_ACM)) {
5443 gst_riff_strf_auds auds;
5445 if (data && size >= 18) {
5446 GstBuffer *codec_data = NULL;
5448 /* little-endian -> byte-order */
5449 auds.format = GST_READ_UINT16_LE (data);
5450 auds.channels = GST_READ_UINT16_LE (data + 2);
5451 auds.rate = GST_READ_UINT32_LE (data + 4);
5452 auds.av_bps = GST_READ_UINT32_LE (data + 8);
5453 auds.blockalign = GST_READ_UINT16_LE (data + 12);
5454 auds.bits_per_sample = GST_READ_UINT16_LE (data + 16);
5456 /* 18 is the waveformatex size */
5458 codec_data = gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY,
5459 data + 18, size - 18, 0, size - 18, NULL, NULL);
5463 *riff_audio_fmt = auds.format;
5465 /* FIXME: Handle reorder map */
5466 caps = gst_riff_create_audio_caps (auds.format, NULL, &auds, NULL,
5467 codec_data, codec_name, NULL);
5469 gst_buffer_unref (codec_data);
5472 GST_WARNING ("Unhandled RIFF audio format 0x%02x", auds.format);
5475 GST_WARNING ("Invalid codec data size (%d expected, got %d)", 18, size);
5477 } else if (g_str_has_prefix (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC)) {
5478 GstBuffer *priv = NULL;
5480 gint rate_idx, profile;
5481 guint8 *data = NULL;
5483 /* unspecified AAC profile with opaque private codec data */
5484 if (strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC) == 0) {
5485 if (context->codec_priv_size >= 2) {
5486 guint obj_type, freq_index, explicit_freq_bytes = 0;
5488 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
5490 freq_index = (GST_READ_UINT16_BE (context->codec_priv) & 0x780) >> 7;
5491 obj_type = (GST_READ_UINT16_BE (context->codec_priv) & 0xF800) >> 11;
5492 if (freq_index == 15)
5493 explicit_freq_bytes = 3;
5494 GST_DEBUG ("obj_type = %u, freq_index = %u", obj_type, freq_index);
5495 priv = gst_buffer_new_wrapped (g_memdup (context->codec_priv,
5496 context->codec_priv_size), context->codec_priv_size);
5497 /* assume SBR if samplerate <= 24kHz */
5498 if (obj_type == 5 || (freq_index >= 6 && freq_index != 15) ||
5499 (context->codec_priv_size == (5 + explicit_freq_bytes))) {
5500 audiocontext->samplerate *= 2;
5503 GST_WARNING ("Opaque A_AAC codec ID, but no codec private data");
5504 /* this is pretty broken;
5505 * maybe we need to make up some default private,
5506 * or maybe ADTS data got dumped in.
5507 * Let's set up some private data now, and check actual data later */
5508 /* just try this and see what happens ... */
5509 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
5510 context->postprocess_frame = gst_matroska_demux_check_aac;
5514 /* make up decoder-specific data if it is not supplied */
5518 priv = gst_buffer_new_allocate (NULL, 5, NULL);
5519 gst_buffer_map (priv, &map, GST_MAP_WRITE);
5521 rate_idx = aac_rate_idx (audiocontext->samplerate);
5522 profile = aac_profile_idx (codec_id);
5524 data[0] = ((profile + 1) << 3) | ((rate_idx & 0xE) >> 1);
5525 data[1] = ((rate_idx & 0x1) << 7) | (audiocontext->channels << 3);
5527 if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2,
5528 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2))) {
5530 gst_buffer_unmap (priv, &map);
5531 gst_buffer_set_size (priv, 2);
5532 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4,
5533 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4))) {
5536 if (g_strrstr (codec_id, "SBR")) {
5537 /* HE-AAC (aka SBR AAC) */
5538 audiocontext->samplerate *= 2;
5539 rate_idx = aac_rate_idx (audiocontext->samplerate);
5540 data[2] = AAC_SYNC_EXTENSION_TYPE >> 3;
5541 data[3] = ((AAC_SYNC_EXTENSION_TYPE & 0x07) << 5) | 5;
5542 data[4] = (1 << 7) | (rate_idx << 3);
5543 gst_buffer_unmap (priv, &map);
5545 gst_buffer_unmap (priv, &map);
5546 gst_buffer_set_size (priv, 2);
5549 gst_buffer_unmap (priv, &map);
5550 gst_buffer_unref (priv);
5552 GST_ERROR ("Unknown AAC profile and no codec private data");
5557 caps = gst_caps_new_simple ("audio/mpeg",
5558 "mpegversion", G_TYPE_INT, mpegversion,
5559 "framed", G_TYPE_BOOLEAN, TRUE,
5560 "stream-format", G_TYPE_STRING, "raw", NULL);
5561 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5562 if (context->codec_priv && context->codec_priv_size > 0)
5563 gst_codec_utils_aac_caps_set_level_and_profile (caps,
5564 context->codec_priv, context->codec_priv_size);
5565 *codec_name = g_strdup_printf ("MPEG-%d AAC audio", mpegversion);
5566 gst_buffer_unref (priv);
5568 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TTA)) {
5569 caps = gst_caps_new_simple ("audio/x-tta",
5570 "width", G_TYPE_INT, audiocontext->bitdepth, NULL);
5571 *codec_name = g_strdup ("TTA audio");
5572 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_WAVPACK4)) {
5573 caps = gst_caps_new_simple ("audio/x-wavpack",
5574 "width", G_TYPE_INT, audiocontext->bitdepth,
5575 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5576 *codec_name = g_strdup ("Wavpack audio");
5577 context->postprocess_frame = gst_matroska_demux_add_wvpk_header;
5578 audiocontext->wvpk_block_index = 0;
5579 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4)) ||
5580 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_28_8)) ||
5581 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))) {
5582 gint raversion = -1;
5584 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4))
5586 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))
5591 caps = gst_caps_new_simple ("audio/x-pn-realaudio",
5592 "raversion", G_TYPE_INT, raversion, NULL);
5593 /* Extract extra information from caps, mapping varies based on codec */
5594 if (data && (size >= 0x50)) {
5601 guint extra_data_size;
5603 GST_ERROR ("real audio raversion:%d", raversion);
5604 if (raversion == 8) {
5606 flavor = GST_READ_UINT16_BE (data + 22);
5607 packet_size = GST_READ_UINT32_BE (data + 24);
5608 height = GST_READ_UINT16_BE (data + 40);
5609 leaf_size = GST_READ_UINT16_BE (data + 44);
5610 sample_width = GST_READ_UINT16_BE (data + 58);
5611 extra_data_size = GST_READ_UINT32_BE (data + 74);
5614 ("flavor:%d, packet_size:%d, height:%d, leaf_size:%d, sample_width:%d, extra_data_size:%d",
5615 flavor, packet_size, height, leaf_size, sample_width,
5617 gst_caps_set_simple (caps, "flavor", G_TYPE_INT, flavor, "packet_size",
5618 G_TYPE_INT, packet_size, "height", G_TYPE_INT, height, "leaf_size",
5619 G_TYPE_INT, leaf_size, "width", G_TYPE_INT, sample_width, NULL);
5621 if ((size - 78) >= extra_data_size) {
5622 priv = gst_buffer_new_wrapped (g_memdup (data + 78, extra_data_size),
5624 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5625 gst_buffer_unref (priv);
5630 *codec_name = g_strdup_printf ("RealAudio %d.0", raversion);
5631 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_SIPR)) {
5632 caps = gst_caps_new_empty_simple ("audio/x-sipro");
5633 *codec_name = g_strdup ("Sipro/ACELP.NET Voice Codec");
5634 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_RALF)) {
5635 caps = gst_caps_new_empty_simple ("audio/x-ralf-mpeg4-generic");
5636 *codec_name = g_strdup ("Real Audio Lossless");
5637 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_ATRC)) {
5638 caps = gst_caps_new_empty_simple ("audio/x-vnd.sony.atrac3");
5639 *codec_name = g_strdup ("Sony ATRAC3");
5641 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
5646 if (audiocontext->samplerate > 0 && audiocontext->channels > 0) {
5649 for (i = 0; i < gst_caps_get_size (caps); i++) {
5650 gst_structure_set (gst_caps_get_structure (caps, i),
5651 "channels", G_TYPE_INT, audiocontext->channels,
5652 "rate", G_TYPE_INT, audiocontext->samplerate, NULL);
5656 caps = gst_caps_simplify (caps);
5663 gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
5664 subtitlecontext, const gchar * codec_id, gpointer data, guint size)
5666 GstCaps *caps = NULL;
5667 GstMatroskaTrackContext *context =
5668 (GstMatroskaTrackContext *) subtitlecontext;
5670 /* for backwards compatibility */
5671 if (!g_ascii_strcasecmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASCII))
5672 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8;
5673 else if (!g_ascii_strcasecmp (codec_id, "S_SSA"))
5674 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_SSA;
5675 else if (!g_ascii_strcasecmp (codec_id, "S_ASS"))
5676 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_ASS;
5677 else if (!g_ascii_strcasecmp (codec_id, "S_USF"))
5678 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_USF;
5680 /* TODO: Add GST_MATROSKA_CODEC_ID_SUBTITLE_BMP support
5681 * Check if we have to do something with codec_private */
5682 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8)) {
5683 /* well, plain text simply does not have a lot of markup ... */
5684 caps = gst_caps_new_simple ("text/x-raw", "format", G_TYPE_STRING,
5685 "pango-markup", NULL);
5686 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5687 subtitlecontext->check_markup = TRUE;
5688 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_SSA)) {
5689 caps = gst_caps_new_empty_simple ("application/x-ssa");
5690 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5691 subtitlecontext->check_markup = FALSE;
5692 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASS)) {
5693 caps = gst_caps_new_empty_simple ("application/x-ass");
5694 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5695 subtitlecontext->check_markup = FALSE;
5696 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_USF)) {
5697 caps = gst_caps_new_empty_simple ("application/x-usf");
5698 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5699 subtitlecontext->check_markup = FALSE;
5700 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB)) {
5701 caps = gst_caps_new_empty_simple ("subpicture/x-dvd");
5702 ((GstMatroskaTrackContext *) subtitlecontext)->send_dvd_event = TRUE;
5703 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_HDMVPGS)) {
5704 caps = gst_caps_new_empty_simple ("subpicture/x-pgs");
5705 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_KATE)) {
5706 caps = gst_caps_new_empty_simple ("subtitle/x-kate");
5707 context->stream_headers =
5708 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
5709 context->codec_priv_size);
5710 /* FIXME: mark stream as broken and skip if there are no stream headers */
5711 context->send_stream_headers = TRUE;
5713 GST_DEBUG ("Unknown subtitle stream: codec_id='%s'", codec_id);
5714 caps = gst_caps_new_empty_simple ("application/x-subtitle-unknown");
5717 if (data != NULL && size > 0) {
5720 buf = gst_buffer_new_wrapped (g_memdup (data, size), size);
5721 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, buf, NULL);
5722 gst_buffer_unref (buf);
5730 gst_matroska_demux_set_index (GstElement * element, GstIndex * index)
5732 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5734 GST_OBJECT_LOCK (demux);
5735 if (demux->common.element_index)
5736 gst_object_unref (demux->common.element_index);
5737 demux->common.element_index = index ? gst_object_ref (index) : NULL;
5738 GST_OBJECT_UNLOCK (demux);
5739 GST_DEBUG_OBJECT (demux, "Set index %" GST_PTR_FORMAT,
5740 demux->common.element_index);
5744 gst_matroska_demux_get_index (GstElement * element)
5746 GstIndex *result = NULL;
5747 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5749 GST_OBJECT_LOCK (demux);
5750 if (demux->common.element_index)
5751 result = gst_object_ref (demux->common.element_index);
5752 GST_OBJECT_UNLOCK (demux);
5754 GST_DEBUG_OBJECT (demux, "Returning index %" GST_PTR_FORMAT, result);
5760 static GstStateChangeReturn
5761 gst_matroska_demux_change_state (GstElement * element,
5762 GstStateChange transition)
5764 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5765 GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
5767 /* handle upwards state changes here */
5768 switch (transition) {
5773 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
5775 /* handle downwards state changes */
5776 switch (transition) {
5777 case GST_STATE_CHANGE_PAUSED_TO_READY:
5778 gst_matroska_demux_reset (GST_ELEMENT (demux));
5788 gst_matroska_demux_set_property (GObject * object,
5789 guint prop_id, const GValue * value, GParamSpec * pspec)
5791 GstMatroskaDemux *demux;
5793 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
5794 demux = GST_MATROSKA_DEMUX (object);
5797 case PROP_MAX_GAP_TIME:
5798 GST_OBJECT_LOCK (demux);
5799 demux->max_gap_time = g_value_get_uint64 (value);
5800 GST_OBJECT_UNLOCK (demux);
5803 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
5809 gst_matroska_demux_get_property (GObject * object,
5810 guint prop_id, GValue * value, GParamSpec * pspec)
5812 GstMatroskaDemux *demux;
5814 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
5815 demux = GST_MATROSKA_DEMUX (object);
5818 case PROP_MAX_GAP_TIME:
5819 GST_OBJECT_LOCK (demux);
5820 g_value_set_uint64 (value, demux->max_gap_time);
5821 GST_OBJECT_UNLOCK (demux);
5824 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
5830 gst_matroska_demux_plugin_init (GstPlugin * plugin)
5834 /* parser helper separate debug */
5835 GST_DEBUG_CATEGORY_INIT (ebmlread_debug, "ebmlread",
5836 0, "EBML stream helper class");
5838 /* create an elementfactory for the matroska_demux element */
5839 if (!gst_element_register (plugin, "matroskademux",
5840 GST_RANK_PRIMARY, GST_TYPE_MATROSKA_DEMUX))