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.freedesktop.org>");
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);
1126 gst_matroska_track_free (context);
1131 /* now create the GStreamer connectivity */
1132 switch (context->type) {
1133 case GST_MATROSKA_TRACK_TYPE_VIDEO:{
1134 GstMatroskaTrackVideoContext *videocontext =
1135 (GstMatroskaTrackVideoContext *) context;
1137 padname = g_strdup_printf ("video_%u", demux->num_v_streams++);
1138 templ = gst_element_class_get_pad_template (klass, "video_%u");
1139 caps = gst_matroska_demux_video_caps (videocontext,
1140 context->codec_id, context->codec_priv,
1141 context->codec_priv_size, &codec, &riff_fourcc);
1144 gst_tag_list_add (context->tags, GST_TAG_MERGE_REPLACE,
1145 GST_TAG_VIDEO_CODEC, codec, NULL);
1146 context->tags_changed = TRUE;
1152 case GST_MATROSKA_TRACK_TYPE_AUDIO:{
1153 GstMatroskaTrackAudioContext *audiocontext =
1154 (GstMatroskaTrackAudioContext *) context;
1156 padname = g_strdup_printf ("audio_%u", demux->num_a_streams++);
1157 templ = gst_element_class_get_pad_template (klass, "audio_%u");
1158 caps = gst_matroska_demux_audio_caps (audiocontext,
1159 context->codec_id, context->codec_priv, context->codec_priv_size,
1160 &codec, &riff_audio_fmt);
1163 gst_tag_list_add (context->tags, GST_TAG_MERGE_REPLACE,
1164 GST_TAG_AUDIO_CODEC, codec, NULL);
1165 context->tags_changed = TRUE;
1171 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:{
1172 GstMatroskaTrackSubtitleContext *subtitlecontext =
1173 (GstMatroskaTrackSubtitleContext *) context;
1175 padname = g_strdup_printf ("subtitle_%u", demux->num_t_streams++);
1176 templ = gst_element_class_get_pad_template (klass, "subtitle_%u");
1177 caps = gst_matroska_demux_subtitle_caps (subtitlecontext,
1178 context->codec_id, context->codec_priv, context->codec_priv_size);
1182 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1183 case GST_MATROSKA_TRACK_TYPE_LOGO:
1184 case GST_MATROSKA_TRACK_TYPE_BUTTONS:
1185 case GST_MATROSKA_TRACK_TYPE_CONTROL:
1187 /* we should already have quit by now */
1188 g_assert_not_reached ();
1191 if ((context->language == NULL || *context->language == '\0') &&
1192 (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO ||
1193 context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
1194 GST_LOG ("stream %d: language=eng (assuming default)", context->index);
1195 context->language = g_strdup ("eng");
1198 if (context->language) {
1201 /* Matroska contains ISO 639-2B codes, we want ISO 639-1 */
1202 lang = gst_tag_get_language_code (context->language);
1203 gst_tag_list_add (context->tags, GST_TAG_MERGE_REPLACE,
1204 GST_TAG_LANGUAGE_CODE, (lang) ? lang : context->language, NULL);
1205 context->tags_changed = TRUE;
1209 GST_WARNING_OBJECT (demux, "could not determine caps for stream with "
1210 "codec_id='%s'", context->codec_id);
1211 switch (context->type) {
1212 case GST_MATROSKA_TRACK_TYPE_VIDEO:
1213 caps = gst_caps_new_empty_simple ("video/x-unknown");
1215 case GST_MATROSKA_TRACK_TYPE_AUDIO:
1216 caps = gst_caps_new_empty_simple ("audio/x-unknown");
1218 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
1219 caps = gst_caps_new_empty_simple ("application/x-subtitle-unknown");
1221 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1223 caps = gst_caps_new_empty_simple ("application/x-matroska-unknown");
1226 gst_caps_set_simple (caps, "codec-id", G_TYPE_STRING, context->codec_id,
1229 /* add any unrecognised riff fourcc / audio format, but after codec-id */
1230 if (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO && riff_audio_fmt != 0)
1231 gst_caps_set_simple (caps, "format", G_TYPE_INT, riff_audio_fmt, NULL);
1232 else if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO && riff_fourcc != 0) {
1233 gchar *fstr = g_strdup_printf ("%" GST_FOURCC_FORMAT,
1234 GST_FOURCC_ARGS (riff_fourcc));
1235 gst_caps_set_simple (caps, "fourcc", G_TYPE_STRING, fstr, NULL);
1238 } else if (context->stream_headers != NULL) {
1239 gst_matroska_demux_add_stream_headers_to_caps (demux,
1240 context->stream_headers, caps);
1243 /* the pad in here */
1244 context->pad = gst_pad_new_from_template (templ, padname);
1245 context->caps = caps;
1247 gst_pad_set_event_function (context->pad,
1248 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_event));
1249 gst_pad_set_query_function (context->pad,
1250 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_query));
1252 GST_INFO_OBJECT (demux, "Adding pad '%s' with caps %" GST_PTR_FORMAT,
1255 gst_pad_set_element_private (context->pad, context);
1257 gst_pad_use_fixed_caps (context->pad);
1258 gst_pad_set_active (context->pad, TRUE);
1261 gst_pad_create_stream_id_printf (context->pad, GST_ELEMENT_CAST (demux),
1262 "%03" G_GUINT64_FORMAT, context->uid);
1264 gst_pad_get_sticky_event (demux->common.sinkpad, GST_EVENT_STREAM_START,
1267 if (gst_event_parse_group_id (stream_start, &demux->group_id))
1268 demux->have_group_id = TRUE;
1270 demux->have_group_id = FALSE;
1271 gst_event_unref (stream_start);
1272 } else if (!demux->have_group_id) {
1273 demux->have_group_id = TRUE;
1274 demux->group_id = gst_util_group_id_next ();
1277 stream_start = gst_event_new_stream_start (stream_id);
1279 if (demux->have_group_id)
1280 gst_event_set_group_id (stream_start, demux->group_id);
1281 stream_flags = GST_STREAM_FLAG_NONE;
1282 if (context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)
1283 stream_flags |= GST_STREAM_FLAG_SPARSE;
1284 if (context->flags & GST_MATROSKA_TRACK_DEFAULT)
1285 stream_flags |= GST_STREAM_FLAG_SELECT;
1286 gst_event_set_stream_flags (stream_start, stream_flags);
1287 gst_pad_push_event (context->pad, stream_start);
1288 gst_pad_set_caps (context->pad, context->caps);
1291 if (demux->common.global_tags) {
1292 GstEvent *tag_event;
1294 gst_tag_list_add (demux->common.global_tags, GST_TAG_MERGE_REPLACE,
1295 GST_TAG_CONTAINER_FORMAT, "Matroska", NULL);
1296 GST_DEBUG_OBJECT (context->pad, "Sending global_tags %p: %" GST_PTR_FORMAT,
1297 demux->common.global_tags, demux->common.global_tags);
1300 gst_event_new_tag (gst_tag_list_copy (demux->common.global_tags));
1302 gst_pad_push_event (context->pad, tag_event);
1305 if (G_UNLIKELY (context->tags_changed)) {
1306 GST_DEBUG_OBJECT (context->pad, "Sending tags %p: %"
1307 GST_PTR_FORMAT, context->tags, context->tags);
1308 gst_pad_push_event (context->pad,
1309 gst_event_new_tag (gst_tag_list_copy (context->tags)));
1310 context->tags_changed = FALSE;
1313 gst_element_add_pad (GST_ELEMENT (demux), context->pad);
1314 gst_flow_combiner_add_pad (demux->flowcombiner, context->pad);
1323 gst_matroska_demux_query (GstMatroskaDemux * demux, GstPad * pad,
1326 gboolean res = FALSE;
1327 GstMatroskaTrackContext *context = NULL;
1330 context = gst_pad_get_element_private (pad);
1333 switch (GST_QUERY_TYPE (query)) {
1334 case GST_QUERY_POSITION:
1338 gst_query_parse_position (query, &format, NULL);
1341 if (format == GST_FORMAT_TIME) {
1342 GST_OBJECT_LOCK (demux);
1344 gst_query_set_position (query, GST_FORMAT_TIME,
1345 MAX (context->pos, demux->stream_start_time) -
1346 demux->stream_start_time);
1348 gst_query_set_position (query, GST_FORMAT_TIME,
1349 MAX (demux->common.segment.position, demux->stream_start_time) -
1350 demux->stream_start_time);
1351 GST_OBJECT_UNLOCK (demux);
1352 } else if (format == GST_FORMAT_DEFAULT && context
1353 && context->default_duration) {
1354 GST_OBJECT_LOCK (demux);
1355 gst_query_set_position (query, GST_FORMAT_DEFAULT,
1356 context->pos / context->default_duration);
1357 GST_OBJECT_UNLOCK (demux);
1359 GST_DEBUG_OBJECT (demux,
1360 "only position query in TIME and DEFAULT format is supported");
1366 case GST_QUERY_DURATION:
1370 gst_query_parse_duration (query, &format, NULL);
1373 if (format == GST_FORMAT_TIME) {
1374 GST_OBJECT_LOCK (demux);
1375 gst_query_set_duration (query, GST_FORMAT_TIME,
1376 demux->common.segment.duration);
1377 GST_OBJECT_UNLOCK (demux);
1378 } else if (format == GST_FORMAT_DEFAULT && context
1379 && context->default_duration) {
1380 GST_OBJECT_LOCK (demux);
1381 gst_query_set_duration (query, GST_FORMAT_DEFAULT,
1382 demux->common.segment.duration / context->default_duration);
1383 GST_OBJECT_UNLOCK (demux);
1385 GST_DEBUG_OBJECT (demux,
1386 "only duration query in TIME and DEFAULT format is supported");
1392 case GST_QUERY_SEEKING:
1396 gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
1397 GST_OBJECT_LOCK (demux);
1398 if (fmt == GST_FORMAT_TIME) {
1401 if (demux->streaming) {
1402 /* assuming we'll be able to get an index ... */
1403 seekable = demux->seekable;
1408 gst_query_set_seeking (query, GST_FORMAT_TIME, seekable,
1409 0, demux->common.segment.duration);
1412 GST_OBJECT_UNLOCK (demux);
1415 case GST_QUERY_SEGMENT:
1420 format = demux->common.segment.format;
1423 gst_segment_to_stream_time (&demux->common.segment, format,
1424 demux->common.segment.start);
1425 if ((stop = demux->common.segment.stop) == -1)
1426 stop = demux->common.segment.duration;
1429 gst_segment_to_stream_time (&demux->common.segment, format, stop);
1431 gst_query_set_segment (query, demux->common.segment.rate, format, start,
1438 res = gst_pad_query_default (pad, (GstObject *) demux, query);
1441 GST_ELEMENT_CLASS (parent_class)->query (GST_ELEMENT_CAST (demux),
1450 gst_matroska_demux_element_query (GstElement * element, GstQuery * query)
1452 return gst_matroska_demux_query (GST_MATROSKA_DEMUX (element), NULL, query);
1456 gst_matroska_demux_handle_src_query (GstPad * pad, GstObject * parent,
1459 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
1461 return gst_matroska_demux_query (demux, pad, query);
1464 /* returns FALSE if there are no pads to deliver event to,
1465 * otherwise TRUE (whatever the outcome of event sending),
1466 * takes ownership of the passed event! */
1468 gst_matroska_demux_send_event (GstMatroskaDemux * demux, GstEvent * event)
1470 gboolean ret = FALSE;
1473 g_return_val_if_fail (event != NULL, FALSE);
1475 GST_DEBUG_OBJECT (demux, "Sending event of type %s to all source pads",
1476 GST_EVENT_TYPE_NAME (event));
1478 g_assert (demux->common.src->len == demux->common.num_streams);
1479 for (i = 0; i < demux->common.src->len; i++) {
1480 GstMatroskaTrackContext *stream;
1482 stream = g_ptr_array_index (demux->common.src, i);
1483 gst_event_ref (event);
1484 gst_pad_push_event (stream->pad, event);
1488 gst_event_unref (event);
1493 gst_matroska_demux_send_tags (GstMatroskaDemux * demux)
1497 if (G_UNLIKELY (demux->common.global_tags_changed)) {
1498 GstEvent *tag_event;
1499 gst_tag_list_add (demux->common.global_tags, GST_TAG_MERGE_REPLACE,
1500 GST_TAG_CONTAINER_FORMAT, "Matroska", NULL);
1501 GST_DEBUG_OBJECT (demux, "Sending global_tags %p : %" GST_PTR_FORMAT,
1502 demux->common.global_tags, demux->common.global_tags);
1505 gst_event_new_tag (gst_tag_list_copy (demux->common.global_tags));
1507 for (i = 0; i < demux->common.src->len; i++) {
1508 GstMatroskaTrackContext *stream;
1510 stream = g_ptr_array_index (demux->common.src, i);
1511 gst_pad_push_event (stream->pad, gst_event_ref (tag_event));
1514 gst_event_unref (tag_event);
1515 demux->common.global_tags_changed = FALSE;
1518 g_assert (demux->common.src->len == demux->common.num_streams);
1519 for (i = 0; i < demux->common.src->len; i++) {
1520 GstMatroskaTrackContext *stream;
1522 stream = g_ptr_array_index (demux->common.src, i);
1524 if (G_UNLIKELY (stream->tags_changed)) {
1525 GST_DEBUG_OBJECT (demux, "Sending tags %p for pad %s:%s : %"
1526 GST_PTR_FORMAT, stream->tags,
1527 GST_DEBUG_PAD_NAME (stream->pad), stream->tags);
1528 gst_pad_push_event (stream->pad,
1529 gst_event_new_tag (gst_tag_list_copy (stream->tags)));
1530 stream->tags_changed = FALSE;
1536 gst_matroska_demux_element_send_event (GstElement * element, GstEvent * event)
1538 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
1541 g_return_val_if_fail (event != NULL, FALSE);
1543 if (GST_EVENT_TYPE (event) == GST_EVENT_SEEK) {
1544 res = gst_matroska_demux_handle_seek_event (demux, NULL, event);
1546 GST_WARNING_OBJECT (demux, "Unhandled event of type %s",
1547 GST_EVENT_TYPE_NAME (event));
1550 gst_event_unref (event);
1555 gst_matroska_demux_move_to_entry (GstMatroskaDemux * demux,
1556 GstMatroskaIndex * entry, gboolean reset, gboolean update)
1560 GST_OBJECT_LOCK (demux);
1563 /* seek (relative to matroska segment) */
1564 /* position might be invalid; will error when streaming resumes ... */
1565 demux->common.offset = entry->pos + demux->common.ebml_segment_start;
1566 demux->next_cluster_offset = 0;
1568 GST_DEBUG_OBJECT (demux,
1569 "Seeked to offset %" G_GUINT64_FORMAT ", block %d, " "time %"
1570 GST_TIME_FORMAT, entry->pos + demux->common.ebml_segment_start,
1571 entry->block, GST_TIME_ARGS (entry->time));
1573 /* update the time */
1574 gst_matroska_read_common_reset_streams (&demux->common, entry->time, TRUE);
1575 gst_flow_combiner_reset (demux->flowcombiner);
1576 demux->common.segment.position = entry->time;
1577 demux->seek_block = entry->block;
1578 demux->seek_first = TRUE;
1579 demux->last_stop_end = GST_CLOCK_TIME_NONE;
1582 for (i = 0; i < demux->common.src->len; i++) {
1583 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
1586 stream->to_offset = G_MAXINT64;
1588 if (stream->from_offset != -1)
1589 stream->to_offset = stream->from_offset;
1591 stream->from_offset = -1;
1592 stream->from_time = GST_CLOCK_TIME_NONE;
1595 GST_OBJECT_UNLOCK (demux);
1601 gst_matroska_cluster_compare (gint64 * i1, gint64 * i2)
1611 /* searches for a cluster start from @pos,
1612 * return GST_FLOW_OK and cluster position in @pos if found */
1613 static GstFlowReturn
1614 gst_matroska_demux_search_cluster (GstMatroskaDemux * demux, gint64 * pos)
1616 gint64 newpos = *pos;
1618 GstFlowReturn ret = GST_FLOW_OK;
1619 const guint chunk = 64 * 1024;
1620 GstBuffer *buf = NULL;
1622 gpointer data = NULL;
1627 gint64 oldpos, oldlength;
1629 orig_offset = demux->common.offset;
1631 GST_LOG_OBJECT (demux, "searching cluster following offset %" G_GINT64_FORMAT,
1634 if (demux->clusters) {
1637 cpos = gst_util_array_binary_search (demux->clusters->data,
1638 demux->clusters->len, sizeof (gint64),
1639 (GCompareDataFunc) gst_matroska_cluster_compare,
1640 GST_SEARCH_MODE_AFTER, pos, NULL);
1643 GST_DEBUG_OBJECT (demux,
1644 "cluster reported at offset %" G_GINT64_FORMAT, *cpos);
1645 demux->common.offset = *cpos;
1646 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1647 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1648 if (ret == GST_FLOW_OK && id == GST_MATROSKA_ID_CLUSTER) {
1655 /* read in at newpos and scan for ebml cluster id */
1656 oldpos = oldlength = -1;
1658 GstByteReader reader;
1662 gst_buffer_unmap (buf, &map);
1663 gst_buffer_unref (buf);
1666 ret = gst_pad_pull_range (demux->common.sinkpad, newpos, chunk, &buf);
1667 if (ret != GST_FLOW_OK)
1669 GST_DEBUG_OBJECT (demux,
1670 "read buffer size %" G_GSIZE_FORMAT " at offset %" G_GINT64_FORMAT,
1671 gst_buffer_get_size (buf), newpos);
1672 gst_buffer_map (buf, &map, GST_MAP_READ);
1675 if (oldpos == newpos && oldlength == map.size) {
1676 GST_ERROR_OBJECT (demux, "Stuck at same position");
1677 ret = GST_FLOW_ERROR;
1681 oldlength = map.size;
1684 gst_byte_reader_init (&reader, data, size);
1686 cluster_pos = gst_byte_reader_masked_scan_uint32 (&reader, 0xffffffff,
1687 GST_MATROSKA_ID_CLUSTER, 0, gst_byte_reader_get_remaining (&reader));
1688 if (cluster_pos >= 0) {
1689 newpos += cluster_pos;
1690 /* prepare resuming at next byte */
1691 if (!gst_byte_reader_skip (&reader, cluster_pos + 1)) {
1692 GST_DEBUG_OBJECT (demux, "Need more data -> continue");
1695 GST_DEBUG_OBJECT (demux,
1696 "found cluster ebml id at offset %" G_GINT64_FORMAT, newpos);
1697 /* extra checks whether we really sync'ed to a cluster:
1698 * - either it is the first and only cluster
1699 * - either there is a cluster after this one
1700 * - either cluster length is undefined
1702 /* ok if first cluster (there may not a subsequent one) */
1703 if (newpos == demux->first_cluster_offset) {
1704 GST_DEBUG_OBJECT (demux, "cluster is first cluster -> OK");
1707 demux->common.offset = newpos;
1708 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1709 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1710 if (ret != GST_FLOW_OK) {
1711 GST_DEBUG_OBJECT (demux, "need more data -> continue");
1714 g_assert (id == GST_MATROSKA_ID_CLUSTER);
1715 GST_DEBUG_OBJECT (demux, "cluster size %" G_GUINT64_FORMAT ", prefix %d",
1717 /* ok if undefined length or first cluster */
1718 if (length == GST_EBML_SIZE_UNKNOWN || length == G_MAXUINT64) {
1719 GST_DEBUG_OBJECT (demux, "cluster has undefined length -> OK");
1723 demux->common.offset += length + needed;
1724 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1725 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1726 if (ret != GST_FLOW_OK)
1728 GST_DEBUG_OBJECT (demux, "next element is %scluster",
1729 id == GST_MATROSKA_ID_CLUSTER ? "" : "not ");
1730 if (id == GST_MATROSKA_ID_CLUSTER)
1732 /* not ok, resume */
1735 /* partial cluster id may have been in tail of buffer */
1736 newpos += MAX (gst_byte_reader_get_remaining (&reader), 4) - 3;
1741 gst_buffer_unmap (buf, &map);
1742 gst_buffer_unref (buf);
1747 demux->common.offset = orig_offset;
1752 /* bisect and scan through file for cluster starting before @time,
1753 * returns fake index entry with corresponding info on cluster */
1754 static GstMatroskaIndex *
1755 gst_matroska_demux_search_pos (GstMatroskaDemux * demux, GstClockTime time)
1757 GstMatroskaIndex *entry = NULL;
1758 GstMatroskaReadState current_state;
1759 GstClockTime otime, prev_cluster_time, current_cluster_time, cluster_time;
1760 gint64 opos, newpos, startpos = 0, current_offset;
1761 gint64 prev_cluster_offset = -1, current_cluster_offset, cluster_offset;
1762 const guint chunk = 64 * 1024;
1768 /* (under)estimate new position, resync using cluster ebml id,
1769 * and scan forward to appropriate cluster
1770 * (and re-estimate if need to go backward) */
1772 prev_cluster_time = GST_CLOCK_TIME_NONE;
1774 /* store some current state */
1775 current_state = demux->common.state;
1776 g_return_val_if_fail (current_state == GST_MATROSKA_READ_STATE_DATA, NULL);
1778 current_cluster_offset = demux->cluster_offset;
1779 current_cluster_time = demux->cluster_time;
1780 current_offset = demux->common.offset;
1782 demux->common.state = GST_MATROSKA_READ_STATE_SCANNING;
1784 /* estimate using start and current position */
1785 GST_OBJECT_LOCK (demux);
1786 opos = demux->common.offset - demux->common.ebml_segment_start;
1787 otime = demux->common.segment.position;
1788 GST_OBJECT_UNLOCK (demux);
1791 time = MAX (time, demux->stream_start_time);
1793 /* avoid division by zero in first estimation below */
1794 if (otime <= demux->stream_start_time)
1798 GST_LOG_OBJECT (demux,
1799 "opos: %" G_GUINT64_FORMAT ", otime: %" GST_TIME_FORMAT ", %"
1800 GST_TIME_FORMAT " in stream time (start %" GST_TIME_FORMAT "), time %"
1801 GST_TIME_FORMAT, opos, GST_TIME_ARGS (otime),
1802 GST_TIME_ARGS (otime - demux->stream_start_time),
1803 GST_TIME_ARGS (demux->stream_start_time), GST_TIME_ARGS (time));
1805 if (otime <= demux->stream_start_time) {
1809 gst_util_uint64_scale (opos - demux->common.ebml_segment_start,
1810 time - demux->stream_start_time,
1811 otime - demux->stream_start_time) - chunk;
1815 /* favour undershoot */
1816 newpos = newpos * 90 / 100;
1817 newpos += demux->common.ebml_segment_start;
1819 GST_DEBUG_OBJECT (demux,
1820 "estimated offset for %" GST_TIME_FORMAT ": %" G_GINT64_FORMAT,
1821 GST_TIME_ARGS (time), newpos);
1823 /* and at least start scanning before previous scan start to avoid looping */
1824 startpos = startpos * 90 / 100;
1825 if (startpos && startpos < newpos)
1828 /* read in at newpos and scan for ebml cluster id */
1832 ret = gst_matroska_demux_search_cluster (demux, &newpos);
1833 if (ret == GST_FLOW_EOS) {
1834 /* heuristic HACK */
1835 newpos = startpos * 80 / 100;
1836 GST_DEBUG_OBJECT (demux, "EOS; "
1837 "new estimated offset for %" GST_TIME_FORMAT ": %" G_GINT64_FORMAT,
1838 GST_TIME_ARGS (time), newpos);
1841 } else if (ret != GST_FLOW_OK) {
1848 /* then start scanning and parsing for cluster time,
1849 * re-estimate if overshoot, otherwise next cluster and so on */
1850 demux->common.offset = newpos;
1851 demux->cluster_time = cluster_time = GST_CLOCK_TIME_NONE;
1853 guint64 cluster_size = 0;
1855 /* peek and parse some elements */
1856 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1857 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1858 if (ret != GST_FLOW_OK)
1860 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
1861 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
1863 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
1864 if (ret != GST_FLOW_OK)
1867 if (id == GST_MATROSKA_ID_CLUSTER) {
1868 cluster_time = GST_CLOCK_TIME_NONE;
1869 if (length == G_MAXUINT64)
1872 cluster_size = length + needed;
1874 if (demux->cluster_time != GST_CLOCK_TIME_NONE &&
1875 cluster_time == GST_CLOCK_TIME_NONE) {
1876 cluster_time = demux->cluster_time * demux->common.time_scale;
1877 cluster_offset = demux->cluster_offset;
1878 GST_DEBUG_OBJECT (demux, "found cluster at offset %" G_GINT64_FORMAT
1879 " with time %" GST_TIME_FORMAT, cluster_offset,
1880 GST_TIME_ARGS (cluster_time));
1881 if (cluster_time > time) {
1882 GST_DEBUG_OBJECT (demux, "overshot target");
1883 /* cluster overshoots */
1884 if (cluster_offset == demux->first_cluster_offset) {
1885 /* but no prev one */
1886 GST_DEBUG_OBJECT (demux, "but using first cluster anyway");
1887 prev_cluster_time = cluster_time;
1888 prev_cluster_offset = cluster_offset;
1891 if (prev_cluster_time != GST_CLOCK_TIME_NONE) {
1892 /* prev cluster did not overshoot, so prev cluster is target */
1895 /* re-estimate using this new position info */
1896 opos = cluster_offset;
1897 otime = cluster_time;
1901 /* cluster undershoots, goto next one */
1902 prev_cluster_time = cluster_time;
1903 prev_cluster_offset = cluster_offset;
1904 /* skip cluster if length is defined,
1905 * otherwise will be skippingly parsed into */
1907 GST_DEBUG_OBJECT (demux, "skipping to next cluster");
1908 demux->common.offset = cluster_offset + cluster_size;
1909 demux->cluster_time = GST_CLOCK_TIME_NONE;
1911 GST_DEBUG_OBJECT (demux, "parsing/skipping cluster elements");
1918 if (ret == GST_FLOW_EOS) {
1919 if (prev_cluster_time != GST_CLOCK_TIME_NONE)
1925 entry = g_new0 (GstMatroskaIndex, 1);
1926 entry->time = prev_cluster_time;
1927 entry->pos = prev_cluster_offset - demux->common.ebml_segment_start;
1928 GST_DEBUG_OBJECT (demux, "simulated index entry; time %" GST_TIME_FORMAT
1929 ", pos %" G_GUINT64_FORMAT, GST_TIME_ARGS (entry->time), entry->pos);
1933 /* restore some state */
1934 demux->cluster_offset = current_cluster_offset;
1935 demux->cluster_time = current_cluster_time;
1936 demux->common.offset = current_offset;
1937 demux->common.state = current_state;
1943 gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
1944 GstPad * pad, GstEvent * event)
1946 GstMatroskaIndex *entry = NULL;
1947 GstMatroskaIndex scan_entry;
1949 GstSeekType cur_type, stop_type;
1951 gboolean flush, keyunit, before, after, snap_next;
1954 GstMatroskaTrackContext *track = NULL;
1955 GstSegment seeksegment = { 0, };
1956 gboolean update = TRUE;
1957 gboolean pad_locked = FALSE;
1959 GstSearchMode snap_dir;
1961 g_return_val_if_fail (event != NULL, FALSE);
1964 track = gst_pad_get_element_private (pad);
1966 GST_DEBUG_OBJECT (demux, "Have seek %" GST_PTR_FORMAT, event);
1968 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
1970 seqnum = gst_event_get_seqnum (event);
1972 /* we can only seek on time */
1973 if (format != GST_FORMAT_TIME) {
1974 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
1978 /* copy segment, we need this because we still need the old
1979 * segment when we close the current segment. */
1980 memcpy (&seeksegment, &demux->common.segment, sizeof (GstSegment));
1982 /* pull mode without index means that the actual duration is not known,
1983 * we might be playing a file that's still being recorded
1984 * so, invalidate our current duration, which is only a moving target,
1985 * and should not be used to clamp anything */
1986 if (!demux->streaming && !demux->common.index && demux->invalid_duration) {
1987 seeksegment.duration = GST_CLOCK_TIME_NONE;
1990 GST_DEBUG_OBJECT (demux, "configuring seek");
1991 /* Subtract stream_start_time so we always seek on a segment
1993 if (GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
1994 seeksegment.start -= demux->stream_start_time;
1995 seeksegment.position -= demux->stream_start_time;
1996 if (GST_CLOCK_TIME_IS_VALID (seeksegment.stop))
1997 seeksegment.stop -= demux->stream_start_time;
1999 seeksegment.stop = seeksegment.duration;
2002 gst_segment_do_seek (&seeksegment, rate, format, flags,
2003 cur_type, cur, stop_type, stop, &update);
2005 /* Restore the clip timestamp offset */
2006 if (GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
2007 seeksegment.position += demux->stream_start_time;
2008 seeksegment.start += demux->stream_start_time;
2009 if (!GST_CLOCK_TIME_IS_VALID (seeksegment.stop))
2010 seeksegment.stop = seeksegment.duration;
2011 if (GST_CLOCK_TIME_IS_VALID (seeksegment.stop))
2012 seeksegment.stop += demux->stream_start_time;
2015 /* restore segment duration (if any effect),
2016 * would be determined again when parsing, but anyway ... */
2017 seeksegment.duration = demux->common.segment.duration;
2019 flush = ! !(flags & GST_SEEK_FLAG_FLUSH);
2020 keyunit = ! !(flags & GST_SEEK_FLAG_KEY_UNIT);
2021 after = ! !(flags & GST_SEEK_FLAG_SNAP_AFTER);
2022 before = ! !(flags & GST_SEEK_FLAG_SNAP_BEFORE);
2024 /* always do full update if flushing,
2025 * otherwise problems might arise downstream with missing keyframes etc */
2026 update = update || flush;
2028 GST_DEBUG_OBJECT (demux, "New segment %" GST_SEGMENT_FORMAT, &seeksegment);
2030 /* check sanity before we start flushing and all that */
2031 snap_next = after && !before;
2032 if (seeksegment.rate < 0)
2033 snap_dir = snap_next ? GST_SEARCH_MODE_BEFORE : GST_SEARCH_MODE_AFTER;
2035 snap_dir = snap_next ? GST_SEARCH_MODE_AFTER : GST_SEARCH_MODE_BEFORE;
2037 GST_OBJECT_LOCK (demux);
2038 track = gst_matroska_read_common_get_seek_track (&demux->common, track);
2039 if ((entry = gst_matroska_read_common_do_index_seek (&demux->common, track,
2040 seeksegment.position, &demux->seek_index, &demux->seek_entry,
2041 snap_dir)) == NULL) {
2042 /* pull mode without index can scan later on */
2043 if (demux->streaming) {
2044 GST_DEBUG_OBJECT (demux, "No matching seek entry in index");
2045 GST_OBJECT_UNLOCK (demux);
2047 } else if (rate < 0.0) {
2048 /* FIXME: We should build an index during playback or when scanning
2049 * that can be used here. The reverse playback code requires seek_index
2050 * and seek_entry to be set!
2052 GST_DEBUG_OBJECT (demux,
2053 "No matching seek entry in index, needed for reverse playback");
2054 GST_OBJECT_UNLOCK (demux);
2058 GST_DEBUG_OBJECT (demux, "Seek position looks sane");
2059 GST_OBJECT_UNLOCK (demux);
2062 /* only have to update some segment,
2063 * but also still have to honour flush and so on */
2064 GST_DEBUG_OBJECT (demux, "... no update");
2065 /* bad goto, bad ... */
2069 if (demux->streaming)
2074 GstEvent *flush_event = gst_event_new_flush_start ();
2075 gst_event_set_seqnum (flush_event, seqnum);
2076 GST_DEBUG_OBJECT (demux, "Starting flush");
2077 gst_pad_push_event (demux->common.sinkpad, gst_event_ref (flush_event));
2078 gst_matroska_demux_send_event (demux, flush_event);
2080 GST_DEBUG_OBJECT (demux, "Non-flushing seek, pausing task");
2081 gst_pad_pause_task (demux->common.sinkpad);
2085 GST_PAD_STREAM_LOCK (demux->common.sinkpad);
2090 /* now grab the stream lock so that streaming cannot continue, for
2091 * non flushing seeks when the element is in PAUSED this could block
2093 GST_DEBUG_OBJECT (demux, "Waiting for streaming to stop");
2094 GST_PAD_STREAM_LOCK (demux->common.sinkpad);
2097 /* pull mode without index can do some scanning */
2098 if (!demux->streaming && !entry) {
2099 GstEvent *flush_event;
2101 /* need to stop flushing upstream as we need it next */
2103 flush_event = gst_event_new_flush_stop (TRUE);
2104 gst_event_set_seqnum (flush_event, seqnum);
2105 gst_pad_push_event (demux->common.sinkpad, flush_event);
2107 entry = gst_matroska_demux_search_pos (demux, seeksegment.position);
2108 /* keep local copy */
2110 scan_entry = *entry;
2112 entry = &scan_entry;
2114 GST_DEBUG_OBJECT (demux, "Scan failed to find matching position");
2116 flush_event = gst_event_new_flush_stop (TRUE);
2117 gst_event_set_seqnum (flush_event, seqnum);
2118 gst_matroska_demux_send_event (demux, flush_event);
2126 GST_DEBUG_OBJECT (demux, "seek to key unit, adjusting segment start from %"
2127 GST_TIME_FORMAT " to %" GST_TIME_FORMAT,
2128 GST_TIME_ARGS (seeksegment.start), GST_TIME_ARGS (entry->time));
2129 seeksegment.start = MAX (entry->time, demux->stream_start_time);
2130 seeksegment.position = seeksegment.start;
2131 seeksegment.time = seeksegment.start - demux->stream_start_time;
2134 if (demux->streaming) {
2135 GST_OBJECT_LOCK (demux);
2136 /* track real position we should start at */
2137 GST_DEBUG_OBJECT (demux, "storing segment start");
2138 demux->requested_seek_time = seeksegment.position;
2139 demux->seek_offset = entry->pos + demux->common.ebml_segment_start;
2140 GST_OBJECT_UNLOCK (demux);
2141 /* need to seek to cluster start to pick up cluster time */
2142 /* upstream takes care of flushing and all that
2143 * ... and newsegment event handling takes care of the rest */
2144 return perform_seek_to_offset (demux, rate,
2145 entry->pos + demux->common.ebml_segment_start, seqnum);
2150 GstEvent *flush_event = gst_event_new_flush_stop (TRUE);
2151 gst_event_set_seqnum (flush_event, seqnum);
2152 GST_DEBUG_OBJECT (demux, "Stopping flush");
2153 gst_pad_push_event (demux->common.sinkpad, gst_event_ref (flush_event));
2154 gst_matroska_demux_send_event (demux, flush_event);
2157 GST_OBJECT_LOCK (demux);
2158 /* now update the real segment info */
2159 GST_DEBUG_OBJECT (demux, "Committing new seek segment");
2160 memcpy (&demux->common.segment, &seeksegment, sizeof (GstSegment));
2161 GST_OBJECT_UNLOCK (demux);
2163 /* update some (segment) state */
2164 if (!gst_matroska_demux_move_to_entry (demux, entry, TRUE, update))
2167 /* notify start of new segment */
2168 if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
2171 msg = gst_message_new_segment_start (GST_OBJECT (demux),
2172 GST_FORMAT_TIME, demux->common.segment.start);
2173 gst_message_set_seqnum (msg, seqnum);
2174 gst_element_post_message (GST_ELEMENT (demux), msg);
2177 GST_OBJECT_LOCK (demux);
2178 if (demux->new_segment)
2179 gst_event_unref (demux->new_segment);
2181 /* On port from 0.10, discarded !update (for segment.update) here, FIXME? */
2182 demux->new_segment = gst_event_new_segment (&demux->common.segment);
2183 gst_event_set_seqnum (demux->new_segment, seqnum);
2184 if (demux->common.segment.rate < 0 && demux->common.segment.stop == -1)
2185 demux->to_time = demux->common.segment.position;
2187 demux->to_time = GST_CLOCK_TIME_NONE;
2188 GST_OBJECT_UNLOCK (demux);
2190 /* restart our task since it might have been stopped when we did the
2192 gst_pad_start_task (demux->common.sinkpad,
2193 (GstTaskFunction) gst_matroska_demux_loop, demux->common.sinkpad, NULL);
2195 /* streaming can continue now */
2197 GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
2205 GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
2207 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Got a seek error"));
2213 * Handle whether we can perform the seek event or if we have to let the chain
2214 * function handle seeks to build the seek indexes first.
2217 gst_matroska_demux_handle_seek_push (GstMatroskaDemux * demux, GstPad * pad,
2221 GstSeekType cur_type, stop_type;
2226 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
2231 /* we can only seek on time */
2232 if (format != GST_FORMAT_TIME) {
2233 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
2237 if (stop_type != GST_SEEK_TYPE_NONE && stop != GST_CLOCK_TIME_NONE) {
2238 GST_DEBUG_OBJECT (demux, "Seek end-time not supported in streaming mode");
2242 if (!(flags & GST_SEEK_FLAG_FLUSH)) {
2243 GST_DEBUG_OBJECT (demux,
2244 "Non-flushing seek not supported in streaming mode");
2248 if (flags & GST_SEEK_FLAG_SEGMENT) {
2249 GST_DEBUG_OBJECT (demux, "Segment seek not supported in streaming mode");
2253 /* check for having parsed index already */
2254 if (!demux->common.index_parsed) {
2255 gboolean building_index;
2258 if (!demux->index_offset) {
2259 GST_DEBUG_OBJECT (demux, "no index (location); no seek in push mode");
2263 GST_OBJECT_LOCK (demux);
2264 /* handle the seek event in the chain function */
2265 demux->common.state = GST_MATROSKA_READ_STATE_SEEK;
2266 /* no more seek can be issued until state reset to _DATA */
2268 /* copy the event */
2269 if (demux->seek_event)
2270 gst_event_unref (demux->seek_event);
2271 demux->seek_event = gst_event_ref (event);
2273 /* set the building_index flag so that only one thread can setup the
2274 * structures for index seeking. */
2275 building_index = demux->building_index;
2276 if (!building_index) {
2277 demux->building_index = TRUE;
2278 offset = demux->index_offset;
2280 GST_OBJECT_UNLOCK (demux);
2282 if (!building_index) {
2283 /* seek to the first subindex or legacy index */
2284 GST_INFO_OBJECT (demux, "Seeking to Cues at %" G_GUINT64_FORMAT, offset);
2285 return perform_seek_to_offset (demux, rate, offset,
2286 gst_event_get_seqnum (event));
2289 /* well, we are handling it already */
2293 /* delegate to tweaked regular seek */
2294 return gst_matroska_demux_handle_seek_event (demux, pad, event);
2298 gst_matroska_demux_handle_src_event (GstPad * pad, GstObject * parent,
2301 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
2302 gboolean res = TRUE;
2304 switch (GST_EVENT_TYPE (event)) {
2305 case GST_EVENT_SEEK:
2306 /* no seeking until we are (safely) ready */
2307 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
2308 GST_DEBUG_OBJECT (demux, "not ready for seeking yet");
2311 if (!demux->streaming)
2312 res = gst_matroska_demux_handle_seek_event (demux, pad, event);
2314 res = gst_matroska_demux_handle_seek_push (demux, pad, event);
2315 gst_event_unref (event);
2320 GstMatroskaTrackContext *context = gst_pad_get_element_private (pad);
2321 if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
2322 GstMatroskaTrackVideoContext *videocontext =
2323 (GstMatroskaTrackVideoContext *) context;
2325 GstClockTimeDiff diff;
2326 GstClockTime timestamp;
2328 gst_event_parse_qos (event, NULL, &proportion, &diff, ×tamp);
2330 GST_OBJECT_LOCK (demux);
2331 videocontext->earliest_time = timestamp + diff;
2332 GST_OBJECT_UNLOCK (demux);
2335 gst_event_unref (event);
2339 case GST_EVENT_TOC_SELECT:
2342 GstTocEntry *entry = NULL;
2343 GstEvent *seek_event;
2346 if (!demux->common.toc) {
2347 GST_DEBUG_OBJECT (demux, "no TOC to select");
2350 gst_event_parse_toc_select (event, &uid);
2352 GST_OBJECT_LOCK (demux);
2353 entry = gst_toc_find_entry (demux->common.toc, uid);
2354 if (entry == NULL) {
2355 GST_OBJECT_UNLOCK (demux);
2356 GST_WARNING_OBJECT (demux, "no TOC entry with given UID: %s", uid);
2359 gst_toc_entry_get_start_stop_times (entry, &start_pos, NULL);
2360 GST_OBJECT_UNLOCK (demux);
2361 seek_event = gst_event_new_seek (1.0,
2363 GST_SEEK_FLAG_FLUSH,
2364 GST_SEEK_TYPE_SET, start_pos, GST_SEEK_TYPE_SET, -1);
2365 res = gst_matroska_demux_handle_seek_event (demux, pad, seek_event);
2366 gst_event_unref (seek_event);
2370 GST_WARNING_OBJECT (demux, "received empty TOC select event");
2374 gst_event_unref (event);
2378 /* events we don't need to handle */
2379 case GST_EVENT_NAVIGATION:
2380 gst_event_unref (event);
2384 case GST_EVENT_LATENCY:
2386 res = gst_pad_push_event (demux->common.sinkpad, event);
2393 static GstFlowReturn
2394 gst_matroska_demux_seek_to_previous_keyframe (GstMatroskaDemux * demux)
2396 GstFlowReturn ret = GST_FLOW_EOS;
2397 gboolean done = TRUE;
2400 g_return_val_if_fail (demux->seek_index, GST_FLOW_EOS);
2401 g_return_val_if_fail (demux->seek_entry < demux->seek_index->len,
2404 GST_DEBUG_OBJECT (demux, "locating previous keyframe");
2406 if (!demux->seek_entry) {
2407 GST_DEBUG_OBJECT (demux, "no earlier index entry");
2411 for (i = 0; i < demux->common.src->len; i++) {
2412 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
2414 GST_DEBUG_OBJECT (demux, "segment start %" GST_TIME_FORMAT
2415 ", stream %d at %" GST_TIME_FORMAT,
2416 GST_TIME_ARGS (demux->common.segment.start), stream->index,
2417 GST_TIME_ARGS (stream->from_time));
2418 if (GST_CLOCK_TIME_IS_VALID (stream->from_time)) {
2419 if (stream->from_time > demux->common.segment.start) {
2420 GST_DEBUG_OBJECT (demux, "stream %d not finished yet", stream->index);
2424 /* nothing pushed for this stream;
2425 * likely seek entry did not start at keyframe, so all was skipped.
2426 * So we need an earlier entry */
2432 GstMatroskaIndex *entry;
2434 entry = &g_array_index (demux->seek_index, GstMatroskaIndex,
2435 --demux->seek_entry);
2436 if (!gst_matroska_demux_move_to_entry (demux, entry, FALSE, TRUE))
2446 static GstFlowReturn
2447 gst_matroska_demux_parse_tracks (GstMatroskaDemux * demux, GstEbmlRead * ebml)
2449 GstFlowReturn ret = GST_FLOW_OK;
2452 DEBUG_ELEMENT_START (demux, ebml, "Tracks");
2454 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2455 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
2459 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
2460 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
2464 /* one track within the "all-tracks" header */
2465 case GST_MATROSKA_ID_TRACKENTRY:
2466 ret = gst_matroska_demux_add_stream (demux, ebml);
2470 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
2475 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
2477 demux->tracks_parsed = TRUE;
2483 * Read signed/unsigned "EBML" numbers.
2484 * Return: number of bytes processed.
2488 gst_matroska_ebmlnum_uint (guint8 * data, guint size, guint64 * num)
2490 gint len_mask = 0x80, read = 1, n = 1, num_ffs = 0;
2498 while (read <= 8 && !(total & len_mask)) {
2505 if ((total &= (len_mask - 1)) == len_mask - 1)
2510 if (data[n] == 0xff)
2512 total = (total << 8) | data[n];
2516 if (read == num_ffs && total != 0)
2525 gst_matroska_ebmlnum_sint (guint8 * data, guint size, gint64 * num)
2530 /* read as unsigned number first */
2531 if ((res = gst_matroska_ebmlnum_uint (data, size, &unum)) < 0)
2535 if (unum == G_MAXUINT64)
2538 *num = unum - ((1 << ((7 * res) - 1)) - 1);
2544 * Mostly used for subtitles. We add void filler data for each
2545 * lagging stream to make sure we don't deadlock.
2549 gst_matroska_demux_sync_streams (GstMatroskaDemux * demux)
2553 GST_OBJECT_LOCK (demux);
2555 GST_LOG_OBJECT (demux, "Sync to %" GST_TIME_FORMAT,
2556 GST_TIME_ARGS (demux->common.segment.position));
2558 g_assert (demux->common.num_streams == demux->common.src->len);
2559 for (stream_nr = 0; stream_nr < demux->common.src->len; stream_nr++) {
2560 GstMatroskaTrackContext *context;
2562 context = g_ptr_array_index (demux->common.src, stream_nr);
2564 GST_LOG_OBJECT (demux,
2565 "Checking for resync on stream %d (%" GST_TIME_FORMAT ")", stream_nr,
2566 GST_TIME_ARGS (context->pos));
2568 if (G_LIKELY (context->type != GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
2569 GST_LOG_OBJECT (demux, "Skipping sync on non-subtitle stream");
2573 /* does it lag? 0.5 seconds is a random threshold...
2574 * lag need only be considered if we have advanced into requested segment */
2575 if (GST_CLOCK_TIME_IS_VALID (context->pos) &&
2576 GST_CLOCK_TIME_IS_VALID (demux->common.segment.position) &&
2577 demux->common.segment.position > demux->common.segment.start &&
2578 context->pos + (GST_SECOND / 2) < demux->common.segment.position) {
2581 guint64 start = context->pos;
2582 guint64 stop = demux->common.segment.position - (GST_SECOND / 2);
2584 GST_DEBUG_OBJECT (demux,
2585 "Synchronizing stream %d with other by advancing time from %"
2586 GST_TIME_FORMAT " to %" GST_TIME_FORMAT, stream_nr,
2587 GST_TIME_ARGS (start), GST_TIME_ARGS (stop));
2589 context->pos = stop;
2591 event = gst_event_new_gap (start, stop - start);
2592 GST_OBJECT_UNLOCK (demux);
2593 gst_pad_push_event (context->pad, event);
2594 GST_OBJECT_LOCK (demux);
2598 GST_OBJECT_UNLOCK (demux);
2601 static GstFlowReturn
2602 gst_matroska_demux_push_stream_headers (GstMatroskaDemux * demux,
2603 GstMatroskaTrackContext * stream)
2605 GstFlowReturn ret = GST_FLOW_OK;
2608 num = gst_buffer_list_length (stream->stream_headers);
2609 for (i = 0; i < num; ++i) {
2612 buf = gst_buffer_list_get (stream->stream_headers, i);
2613 buf = gst_buffer_copy (buf);
2615 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
2617 if (stream->set_discont) {
2618 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
2619 stream->set_discont = FALSE;
2621 GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DISCONT);
2624 /* push out all headers in one go and use last flow return */
2625 ret = gst_pad_push (stream->pad, buf);
2628 /* don't need these any longer */
2629 gst_buffer_list_unref (stream->stream_headers);
2630 stream->stream_headers = NULL;
2633 ret = gst_flow_combiner_update_flow (demux->flowcombiner, ret);
2639 gst_matroska_demux_push_dvd_clut_change_event (GstMatroskaDemux * demux,
2640 GstMatroskaTrackContext * stream)
2644 g_assert (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB));
2646 if (!stream->codec_priv)
2649 /* ideally, VobSub private data should be parsed and stored more convenient
2650 * elsewhere, but for now, only interested in a small part */
2652 /* make sure we have terminating 0 */
2653 buf = g_strndup (stream->codec_priv, stream->codec_priv_size);
2655 /* just locate and parse palette part */
2656 start = strstr (buf, "palette:");
2661 guint8 r, g, b, y, u, v;
2664 while (g_ascii_isspace (*start))
2666 for (i = 0; i < 16; i++) {
2667 if (sscanf (start, "%06x", &col) != 1)
2670 while ((*start == ',') || g_ascii_isspace (*start))
2672 /* sigh, need to convert this from vobsub pseudo-RGB to YUV */
2673 r = (col >> 16) & 0xff;
2674 g = (col >> 8) & 0xff;
2676 y = CLAMP ((0.1494 * r + 0.6061 * g + 0.2445 * b) * 219 / 255 + 16, 0,
2678 u = CLAMP (0.6066 * r - 0.4322 * g - 0.1744 * b + 128, 0, 255);
2679 v = CLAMP (-0.08435 * r - 0.3422 * g + 0.4266 * b + 128, 0, 255);
2680 clut[i] = (y << 16) | (u << 8) | v;
2683 /* got them all without problems; build and send event */
2687 s = gst_structure_new ("application/x-gst-dvd", "event", G_TYPE_STRING,
2688 "dvd-spu-clut-change", "clut00", G_TYPE_INT, clut[0], "clut01",
2689 G_TYPE_INT, clut[1], "clut02", G_TYPE_INT, clut[2], "clut03",
2690 G_TYPE_INT, clut[3], "clut04", G_TYPE_INT, clut[4], "clut05",
2691 G_TYPE_INT, clut[5], "clut06", G_TYPE_INT, clut[6], "clut07",
2692 G_TYPE_INT, clut[7], "clut08", G_TYPE_INT, clut[8], "clut09",
2693 G_TYPE_INT, clut[9], "clut10", G_TYPE_INT, clut[10], "clut11",
2694 G_TYPE_INT, clut[11], "clut12", G_TYPE_INT, clut[12], "clut13",
2695 G_TYPE_INT, clut[13], "clut14", G_TYPE_INT, clut[14], "clut15",
2696 G_TYPE_INT, clut[15], NULL);
2698 gst_pad_push_event (stream->pad,
2699 gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM_STICKY, s));
2706 gst_matroska_demux_push_codec_data_all (GstMatroskaDemux * demux)
2710 GST_OBJECT_LOCK (demux);
2712 g_assert (demux->common.num_streams == demux->common.src->len);
2713 for (stream_nr = 0; stream_nr < demux->common.src->len; stream_nr++) {
2714 GstMatroskaTrackContext *stream;
2716 stream = g_ptr_array_index (demux->common.src, stream_nr);
2718 if (stream->send_stream_headers) {
2719 if (stream->stream_headers != NULL) {
2720 gst_matroska_demux_push_stream_headers (demux, stream);
2722 /* FIXME: perhaps we can just disable and skip this stream then */
2723 GST_ELEMENT_ERROR (demux, STREAM, DECODE, (NULL),
2724 ("Failed to extract stream headers from codec private data"));
2726 stream->send_stream_headers = FALSE;
2729 if (stream->send_dvd_event) {
2730 gst_matroska_demux_push_dvd_clut_change_event (demux, stream);
2731 /* FIXME: should we send this event again after (flushing) seek ? */
2732 stream->send_dvd_event = FALSE;
2736 GST_OBJECT_UNLOCK (demux);
2739 static GstFlowReturn
2740 gst_matroska_demux_add_mpeg_seq_header (GstElement * element,
2741 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2744 guint seq_header_len;
2745 guint32 header, tmp;
2747 if (stream->codec_state) {
2748 seq_header = stream->codec_state;
2749 seq_header_len = stream->codec_state_size;
2750 } else if (stream->codec_priv) {
2751 seq_header = stream->codec_priv;
2752 seq_header_len = stream->codec_priv_size;
2757 /* Sequence header only needed for keyframes */
2758 if (GST_BUFFER_FLAG_IS_SET (*buf, GST_BUFFER_FLAG_DELTA_UNIT))
2761 if (gst_buffer_get_size (*buf) < 4)
2764 gst_buffer_extract (*buf, 0, &tmp, sizeof (guint32));
2765 header = GUINT32_FROM_BE (tmp);
2767 /* Sequence start code, if not found prepend */
2768 if (header != 0x000001b3) {
2771 GST_DEBUG_OBJECT (element, "Prepending MPEG sequence header");
2773 newbuf = gst_buffer_new_wrapped (g_memdup (seq_header, seq_header_len),
2776 gst_buffer_copy_into (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
2777 GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_MEMORY, 0,
2778 gst_buffer_get_size (*buf));
2780 gst_buffer_unref (*buf);
2787 static GstFlowReturn
2788 gst_matroska_demux_add_wvpk_header (GstElement * element,
2789 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2791 GstMatroskaTrackAudioContext *audiocontext =
2792 (GstMatroskaTrackAudioContext *) stream;
2793 GstBuffer *newbuf = NULL;
2794 GstMapInfo map, outmap;
2795 guint8 *buf_data, *data;
2803 wvh.version = GST_READ_UINT16_LE (stream->codec_priv);
2806 wvh.total_samples = -1;
2807 wvh.block_index = audiocontext->wvpk_block_index;
2809 if (audiocontext->channels <= 2) {
2810 guint32 block_samples, tmp;
2811 gsize size = gst_buffer_get_size (*buf);
2813 gst_buffer_extract (*buf, 0, &tmp, sizeof (guint32));
2814 block_samples = GUINT32_FROM_LE (tmp);
2815 /* we need to reconstruct the header of the wavpack block */
2817 /* -20 because ck_size is the size of the wavpack block -8
2818 * and lace_size is the size of the wavpack block + 12
2819 * (the three guint32 of the header that already are in the buffer) */
2820 wvh.ck_size = size + sizeof (Wavpack4Header) - 20;
2822 /* block_samples, flags and crc are already in the buffer */
2823 newbuf = gst_buffer_new_allocate (NULL, sizeof (Wavpack4Header) - 12, NULL);
2825 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2831 GST_WRITE_UINT32_LE (data + 4, wvh.ck_size);
2832 GST_WRITE_UINT16_LE (data + 8, wvh.version);
2833 GST_WRITE_UINT8 (data + 10, wvh.track_no);
2834 GST_WRITE_UINT8 (data + 11, wvh.index_no);
2835 GST_WRITE_UINT32_LE (data + 12, wvh.total_samples);
2836 GST_WRITE_UINT32_LE (data + 16, wvh.block_index);
2838 /* Append data from buf: */
2839 gst_buffer_copy_into (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
2840 GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_MEMORY, 0, size);
2842 gst_buffer_unref (*buf);
2844 audiocontext->wvpk_block_index += block_samples;
2846 guint8 *outdata = NULL;
2848 gsize buf_size, size, out_size = 0;
2849 guint32 block_samples, flags, crc, blocksize;
2851 gst_buffer_map (*buf, &map, GST_MAP_READ);
2852 buf_data = map.data;
2853 buf_size = map.size;
2856 GST_ERROR_OBJECT (element, "Too small wavpack buffer");
2857 gst_buffer_unmap (*buf, &map);
2858 return GST_FLOW_ERROR;
2864 block_samples = GST_READ_UINT32_LE (data);
2869 flags = GST_READ_UINT32_LE (data);
2872 crc = GST_READ_UINT32_LE (data);
2875 blocksize = GST_READ_UINT32_LE (data);
2879 if (blocksize == 0 || size < blocksize)
2882 g_assert ((newbuf == NULL) == (outdata == NULL));
2884 if (newbuf == NULL) {
2885 out_size = sizeof (Wavpack4Header) + blocksize;
2886 newbuf = gst_buffer_new_allocate (NULL, out_size, NULL);
2888 gst_buffer_copy_into (newbuf, *buf,
2889 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS, 0, -1);
2892 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2893 outdata = outmap.data;
2895 gst_buffer_unmap (newbuf, &outmap);
2896 out_size += sizeof (Wavpack4Header) + blocksize;
2897 gst_buffer_set_size (newbuf, out_size);
2898 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2899 outdata = outmap.data;
2902 outdata[outpos] = 'w';
2903 outdata[outpos + 1] = 'v';
2904 outdata[outpos + 2] = 'p';
2905 outdata[outpos + 3] = 'k';
2908 GST_WRITE_UINT32_LE (outdata + outpos,
2909 blocksize + sizeof (Wavpack4Header) - 8);
2910 GST_WRITE_UINT16_LE (outdata + outpos + 4, wvh.version);
2911 GST_WRITE_UINT8 (outdata + outpos + 6, wvh.track_no);
2912 GST_WRITE_UINT8 (outdata + outpos + 7, wvh.index_no);
2913 GST_WRITE_UINT32_LE (outdata + outpos + 8, wvh.total_samples);
2914 GST_WRITE_UINT32_LE (outdata + outpos + 12, wvh.block_index);
2915 GST_WRITE_UINT32_LE (outdata + outpos + 16, block_samples);
2916 GST_WRITE_UINT32_LE (outdata + outpos + 20, flags);
2917 GST_WRITE_UINT32_LE (outdata + outpos + 24, crc);
2920 memmove (outdata + outpos, data, blocksize);
2921 outpos += blocksize;
2925 gst_buffer_unmap (*buf, &map);
2926 gst_buffer_unref (*buf);
2929 gst_buffer_unmap (newbuf, &outmap);
2932 audiocontext->wvpk_block_index += block_samples;
2938 /* @text must be null-terminated */
2940 gst_matroska_demux_subtitle_chunk_has_tag (GstElement * element,
2945 g_return_val_if_fail (text != NULL, FALSE);
2947 /* yes, this might all lead to false positives ... */
2948 tag = (gchar *) text;
2949 while ((tag = strchr (tag, '<'))) {
2951 if (*tag != '\0' && *(tag + 1) == '>') {
2952 /* some common convenience ones */
2953 /* maybe any character will do here ? */
2966 if (strstr (text, "<span"))
2972 static GstFlowReturn
2973 gst_matroska_demux_check_subtitle_buffer (GstElement * element,
2974 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2976 GstMatroskaTrackSubtitleContext *sub_stream;
2977 const gchar *encoding;
2982 gboolean needs_unmap = TRUE;
2984 sub_stream = (GstMatroskaTrackSubtitleContext *) stream;
2986 if (!gst_buffer_get_size (*buf) || !gst_buffer_map (*buf, &map, GST_MAP_READ))
2989 /* Need \0-terminator at the end */
2990 if (map.data[map.size - 1] != '\0') {
2991 newbuf = gst_buffer_new_and_alloc (map.size + 1);
2993 /* Copy old buffer and add a 0 at the end */
2994 gst_buffer_fill (newbuf, 0, map.data, map.size);
2995 gst_buffer_memset (newbuf, map.size, 0, 1);
2996 gst_buffer_set_size (newbuf, map.size);
2997 gst_buffer_unmap (*buf, &map);
2999 gst_buffer_copy_into (newbuf, *buf,
3000 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS |
3001 GST_BUFFER_COPY_META, 0, -1);
3002 gst_buffer_unref (*buf);
3004 gst_buffer_map (*buf, &map, GST_MAP_READ);
3007 if (!sub_stream->invalid_utf8) {
3008 if (g_utf8_validate ((gchar *) map.data, map.size, NULL)) {
3011 GST_WARNING_OBJECT (element, "subtitle stream %" G_GUINT64_FORMAT
3012 " is not valid UTF-8, this is broken according to the matroska"
3013 " specification", stream->num);
3014 sub_stream->invalid_utf8 = TRUE;
3017 /* file with broken non-UTF8 subtitle, do the best we can do to fix it */
3018 encoding = g_getenv ("GST_SUBTITLE_ENCODING");
3019 if (encoding == NULL || *encoding == '\0') {
3020 /* if local encoding is UTF-8 and no encoding specified
3021 * via the environment variable, assume ISO-8859-15 */
3022 if (g_get_charset (&encoding)) {
3023 encoding = "ISO-8859-15";
3028 g_convert_with_fallback ((gchar *) map.data, map.size, "UTF-8", encoding,
3029 (char *) "*", NULL, NULL, &err);
3032 GST_LOG_OBJECT (element, "could not convert string from '%s' to UTF-8: %s",
3033 encoding, err->message);
3037 /* invalid input encoding, fall back to ISO-8859-15 (always succeeds) */
3038 encoding = "ISO-8859-15";
3040 g_convert_with_fallback ((gchar *) map.data, map.size, "UTF-8",
3041 encoding, (char *) "*", NULL, NULL, NULL);
3044 GST_LOG_OBJECT (element, "converted subtitle text from %s to UTF-8 %s",
3045 encoding, (err) ? "(using ISO-8859-15 as fallback)" : "");
3048 utf8 = g_strdup ("invalid subtitle");
3050 newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
3051 gst_buffer_unmap (*buf, &map);
3052 gst_buffer_copy_into (newbuf, *buf,
3053 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_META,
3055 gst_buffer_unref (*buf);
3058 gst_buffer_map (*buf, &map, GST_MAP_READ);
3062 if (sub_stream->check_markup) {
3063 /* caps claim markup text, so we need to escape text,
3064 * except if text is already markup and then needs no further escaping */
3065 sub_stream->seen_markup_tag = sub_stream->seen_markup_tag ||
3066 gst_matroska_demux_subtitle_chunk_has_tag (element, (gchar *) map.data);
3068 if (!sub_stream->seen_markup_tag) {
3069 utf8 = g_markup_escape_text ((gchar *) map.data, map.size);
3071 newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
3072 gst_buffer_unmap (*buf, &map);
3073 gst_buffer_copy_into (newbuf, *buf,
3074 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS |
3075 GST_BUFFER_COPY_META, 0, -1);
3076 gst_buffer_unref (*buf);
3079 needs_unmap = FALSE;
3084 gst_buffer_unmap (*buf, &map);
3089 static GstFlowReturn
3090 gst_matroska_demux_check_aac (GstElement * element,
3091 GstMatroskaTrackContext * stream, GstBuffer ** buf)
3096 gst_buffer_extract (*buf, 0, data, 2);
3097 size = gst_buffer_get_size (*buf);
3099 if (size > 2 && data[0] == 0xff && (data[1] >> 4 == 0x0f)) {
3102 /* tss, ADTS data, remove codec_data
3103 * still assume it is at least parsed */
3104 stream->caps = gst_caps_make_writable (stream->caps);
3105 s = gst_caps_get_structure (stream->caps, 0);
3107 gst_structure_remove_field (s, "codec_data");
3108 gst_pad_set_caps (stream->pad, stream->caps);
3109 GST_DEBUG_OBJECT (element, "ADTS AAC audio data; removing codec-data, "
3110 "new caps: %" GST_PTR_FORMAT, stream->caps);
3113 /* disable subsequent checking */
3114 stream->postprocess_frame = NULL;
3120 gst_matroska_demux_align_buffer (GstMatroskaDemux * demux,
3121 GstBuffer * buffer, gsize alignment)
3125 gst_buffer_map (buffer, &map, GST_MAP_READ);
3127 if (map.size < sizeof (guintptr)) {
3128 gst_buffer_unmap (buffer, &map);
3132 if (((guintptr) map.data) & (alignment - 1)) {
3133 GstBuffer *new_buffer;
3134 GstAllocationParams params = { 0, alignment - 1, 0, 0, };
3136 new_buffer = gst_buffer_new_allocate (NULL,
3137 gst_buffer_get_size (buffer), ¶ms);
3139 /* Copy data "by hand", so ensure alignment is kept: */
3140 gst_buffer_fill (new_buffer, 0, map.data, map.size);
3142 gst_buffer_copy_into (new_buffer, buffer, GST_BUFFER_COPY_METADATA, 0, -1);
3143 GST_DEBUG_OBJECT (demux,
3144 "We want output aligned on %" G_GSIZE_FORMAT ", reallocated",
3147 gst_buffer_unmap (buffer, &map);
3148 gst_buffer_unref (buffer);
3153 gst_buffer_unmap (buffer, &map);
3157 static GstFlowReturn
3158 gst_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux,
3159 GstEbmlRead * ebml, guint64 cluster_time, guint64 cluster_offset,
3160 gboolean is_simpleblock)
3162 GstMatroskaTrackContext *stream = NULL;
3163 GstFlowReturn ret = GST_FLOW_OK;
3164 gboolean readblock = FALSE;
3166 guint64 block_duration = -1;
3167 GstBuffer *buf = NULL;
3169 gint stream_num = -1, n, laces = 0;
3171 gint *lace_size = NULL;
3174 gint64 referenceblock = 0;
3176 GstClockTime buffer_timestamp;
3178 offset = gst_ebml_read_get_offset (ebml);
3180 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3181 if (!is_simpleblock) {
3182 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK) {
3186 id = GST_MATROSKA_ID_SIMPLEBLOCK;
3190 /* one block inside the group. Note, block parsing is one
3191 * of the harder things, so this code is a bit complicated.
3192 * See http://www.matroska.org/ for documentation. */
3193 case GST_MATROSKA_ID_SIMPLEBLOCK:
3194 case GST_MATROSKA_ID_BLOCK:
3200 gst_buffer_unmap (buf, &map);
3201 gst_buffer_unref (buf);
3204 if ((ret = gst_ebml_read_buffer (ebml, &id, &buf)) != GST_FLOW_OK)
3207 gst_buffer_map (buf, &map, GST_MAP_READ);
3211 /* first byte(s): blocknum */
3212 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
3217 /* fetch stream from num */
3218 stream_num = gst_matroska_read_common_stream_from_num (&demux->common,
3220 if (G_UNLIKELY (size < 3)) {
3221 GST_WARNING_OBJECT (demux, "Invalid size %u", size);
3222 /* non-fatal, try next block(group) */
3225 } else if (G_UNLIKELY (stream_num < 0 ||
3226 stream_num >= demux->common.num_streams)) {
3227 /* let's not give up on a stray invalid track number */
3228 GST_WARNING_OBJECT (demux,
3229 "Invalid stream %d for track number %" G_GUINT64_FORMAT
3230 "; ignoring block", stream_num, num);
3234 stream = g_ptr_array_index (demux->common.src, stream_num);
3236 /* time (relative to cluster time) */
3237 time = ((gint16) GST_READ_UINT16_BE (data));
3240 flags = GST_READ_UINT8 (data);
3244 GST_LOG_OBJECT (demux, "time %" G_GUINT64_FORMAT ", flags %d", time,
3247 switch ((flags & 0x06) >> 1) {
3248 case 0x0: /* no lacing */
3250 lace_size = g_new (gint, 1);
3251 lace_size[0] = size;
3254 case 0x1: /* xiph lacing */
3255 case 0x2: /* fixed-size lacing */
3256 case 0x3: /* EBML lacing */
3258 goto invalid_lacing;
3259 laces = GST_READ_UINT8 (data) + 1;
3262 lace_size = g_new0 (gint, laces);
3264 switch ((flags & 0x06) >> 1) {
3265 case 0x1: /* xiph lacing */ {
3266 guint temp, total = 0;
3268 for (n = 0; ret == GST_FLOW_OK && n < laces - 1; n++) {
3271 goto invalid_lacing;
3272 temp = GST_READ_UINT8 (data);
3273 lace_size[n] += temp;
3279 total += lace_size[n];
3281 lace_size[n] = size - total;
3285 case 0x2: /* fixed-size lacing */
3286 for (n = 0; n < laces; n++)
3287 lace_size[n] = size / laces;
3290 case 0x3: /* EBML lacing */ {
3293 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
3297 total = lace_size[0] = num;
3298 for (n = 1; ret == GST_FLOW_OK && n < laces - 1; n++) {
3302 if ((r = gst_matroska_ebmlnum_sint (data, size, &snum)) < 0)
3306 lace_size[n] = lace_size[n - 1] + snum;
3307 total += lace_size[n];
3310 lace_size[n] = size - total;
3317 if (ret != GST_FLOW_OK)
3324 case GST_MATROSKA_ID_BLOCKDURATION:{
3325 ret = gst_ebml_read_uint (ebml, &id, &block_duration);
3326 GST_DEBUG_OBJECT (demux, "BlockDuration: %" G_GUINT64_FORMAT,
3331 case GST_MATROSKA_ID_REFERENCEBLOCK:{
3332 ret = gst_ebml_read_sint (ebml, &id, &referenceblock);
3333 GST_DEBUG_OBJECT (demux, "ReferenceBlock: %" G_GINT64_FORMAT,
3338 case GST_MATROSKA_ID_CODECSTATE:{
3340 guint64 data_len = 0;
3343 gst_ebml_read_binary (ebml, &id, &data,
3344 &data_len)) != GST_FLOW_OK)
3347 if (G_UNLIKELY (stream == NULL)) {
3348 GST_WARNING_OBJECT (demux,
3349 "Unexpected CodecState subelement - ignoring");
3353 g_free (stream->codec_state);
3354 stream->codec_state = data;
3355 stream->codec_state_size = data_len;
3357 /* Decode if necessary */
3358 if (stream->encodings && stream->encodings->len > 0
3359 && stream->codec_state && stream->codec_state_size > 0) {
3360 if (!gst_matroska_decode_data (stream->encodings,
3361 &stream->codec_state, &stream->codec_state_size,
3362 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
3363 GST_WARNING_OBJECT (demux, "Decoding codec state failed");
3367 GST_DEBUG_OBJECT (demux, "CodecState of %" G_GSIZE_FORMAT " bytes",
3368 stream->codec_state_size);
3373 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3377 case GST_MATROSKA_ID_BLOCKVIRTUAL:
3378 case GST_MATROSKA_ID_BLOCKADDITIONS:
3379 case GST_MATROSKA_ID_REFERENCEPRIORITY:
3380 case GST_MATROSKA_ID_REFERENCEVIRTUAL:
3381 case GST_MATROSKA_ID_SLICES:
3382 GST_DEBUG_OBJECT (demux,
3383 "Skipping BlockGroup subelement 0x%x - ignoring", id);
3384 ret = gst_ebml_read_skip (ebml);
3392 /* reading a number or so could have failed */
3393 if (ret != GST_FLOW_OK)
3396 if (ret == GST_FLOW_OK && readblock) {
3397 gboolean invisible_frame = FALSE;
3398 gboolean delta_unit = FALSE;
3399 guint64 duration = 0;
3400 gint64 lace_time = 0;
3402 stream = g_ptr_array_index (demux->common.src, stream_num);
3404 if (cluster_time != GST_CLOCK_TIME_NONE) {
3405 /* FIXME: What to do with negative timestamps? Give timestamp 0 or -1?
3406 * Drop unless the lace contains timestamp 0? */
3407 if (time < 0 && (-time) > cluster_time) {
3410 if (stream->timecodescale == 1.0)
3411 lace_time = (cluster_time + time) * demux->common.time_scale;
3414 gst_util_guint64_to_gdouble ((cluster_time + time) *
3415 demux->common.time_scale) * stream->timecodescale;
3418 lace_time = GST_CLOCK_TIME_NONE;
3421 /* need to refresh segment info ASAP */
3422 if (GST_CLOCK_TIME_IS_VALID (lace_time) && demux->need_segment) {
3423 GstSegment *segment = &demux->common.segment;
3425 GstEvent *segment_event;
3427 if (!GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
3428 demux->stream_start_time = lace_time;
3429 GST_DEBUG_OBJECT (demux,
3430 "Setting stream start time to %" GST_TIME_FORMAT,
3431 GST_TIME_ARGS (lace_time));
3433 clace_time = MAX (lace_time, demux->stream_start_time);
3434 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.position) &&
3435 demux->common.segment.position != 0) {
3436 GST_DEBUG_OBJECT (demux,
3437 "using stored seek position %" GST_TIME_FORMAT,
3438 GST_TIME_ARGS (demux->common.segment.position));
3439 clace_time = demux->common.segment.position + demux->stream_start_time;
3440 segment->position = GST_CLOCK_TIME_NONE;
3442 segment->start = clace_time;
3443 segment->stop = GST_CLOCK_TIME_NONE;
3444 segment->time = segment->start - demux->stream_start_time;
3445 segment->position = segment->start - demux->stream_start_time;
3446 GST_DEBUG_OBJECT (demux,
3447 "generated segment starting at %" GST_TIME_FORMAT ": %"
3448 GST_SEGMENT_FORMAT, GST_TIME_ARGS (lace_time), segment);
3449 /* now convey our segment notion downstream */
3450 segment_event = gst_event_new_segment (segment);
3451 if (demux->segment_seqnum)
3452 gst_event_set_seqnum (segment_event, demux->segment_seqnum);
3453 gst_matroska_demux_send_event (demux, segment_event);
3454 demux->need_segment = FALSE;
3455 demux->segment_seqnum = 0;
3458 /* send pending codec data headers for all streams,
3459 * before we perform sync across all streams */
3460 gst_matroska_demux_push_codec_data_all (demux);
3462 if (block_duration != -1) {
3463 if (stream->timecodescale == 1.0)
3464 duration = gst_util_uint64_scale (block_duration,
3465 demux->common.time_scale, 1);
3468 gst_util_gdouble_to_guint64 (gst_util_guint64_to_gdouble
3469 (gst_util_uint64_scale (block_duration, demux->common.time_scale,
3470 1)) * stream->timecodescale);
3471 } else if (stream->default_duration) {
3472 duration = stream->default_duration * laces;
3474 /* else duration is diff between timecode of this and next block */
3476 /* For SimpleBlock, look at the keyframe bit in flags. Otherwise,
3477 a ReferenceBlock implies that this is not a keyframe. In either
3478 case, it only makes sense for video streams. */
3479 if (stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
3480 if ((is_simpleblock && !(flags & 0x80)) || referenceblock) {
3482 invisible_frame = ((flags & 0x08)) &&
3483 (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8) ||
3484 !strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP9));
3488 for (n = 0; n < laces; n++) {
3491 if (G_UNLIKELY (lace_size[n] > size)) {
3492 GST_WARNING_OBJECT (demux, "Invalid lace size");
3496 /* QoS for video track with an index. the assumption is that
3497 index entries point to keyframes, but if that is not true we
3498 will instad skip until the next keyframe. */
3499 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
3500 stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
3501 stream->index_table && demux->common.segment.rate > 0.0) {
3502 GstMatroskaTrackVideoContext *videocontext =
3503 (GstMatroskaTrackVideoContext *) stream;
3504 GstClockTime earliest_time;
3505 GstClockTime earliest_stream_time;
3507 GST_OBJECT_LOCK (demux);
3508 earliest_time = videocontext->earliest_time;
3509 GST_OBJECT_UNLOCK (demux);
3510 earliest_stream_time = gst_segment_to_position (&demux->common.segment,
3511 GST_FORMAT_TIME, earliest_time);
3513 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
3514 GST_CLOCK_TIME_IS_VALID (earliest_stream_time) &&
3515 lace_time <= earliest_stream_time) {
3516 /* find index entry (keyframe) <= earliest_stream_time */
3517 GstMatroskaIndex *entry =
3518 gst_util_array_binary_search (stream->index_table->data,
3519 stream->index_table->len, sizeof (GstMatroskaIndex),
3520 (GCompareDataFunc) gst_matroska_index_seek_find,
3521 GST_SEARCH_MODE_BEFORE, &earliest_stream_time, NULL);
3523 /* if that entry (keyframe) is after the current the current
3524 buffer, we can skip pushing (and thus decoding) all
3525 buffers until that keyframe. */
3526 if (entry && GST_CLOCK_TIME_IS_VALID (entry->time) &&
3527 entry->time > lace_time) {
3528 GST_LOG_OBJECT (demux, "Skipping lace before late keyframe");
3529 stream->set_discont = TRUE;
3535 sub = gst_buffer_copy_region (buf, GST_BUFFER_COPY_ALL,
3536 gst_buffer_get_size (buf) - size, lace_size[n]);
3537 GST_DEBUG_OBJECT (demux, "created subbuffer %p", sub);
3540 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
3542 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
3544 if (invisible_frame)
3545 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DECODE_ONLY);
3547 if (stream->encodings != NULL && stream->encodings->len > 0)
3548 sub = gst_matroska_decode_buffer (stream, sub);
3551 GST_WARNING_OBJECT (demux, "Decoding buffer failed");
3555 buffer_timestamp = gst_matroska_track_get_buffer_timestamp (stream, sub);
3557 if (!stream->dts_only) {
3558 GST_BUFFER_PTS (sub) = lace_time;
3560 GST_BUFFER_DTS (sub) = lace_time;
3561 if (stream->intra_only)
3562 GST_BUFFER_PTS (sub) = lace_time;
3565 if (GST_CLOCK_TIME_IS_VALID (lace_time)) {
3566 GstClockTime last_stop_end;
3568 /* Check if this stream is after segment stop */
3569 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop) &&
3570 lace_time >= demux->common.segment.stop) {
3571 GST_DEBUG_OBJECT (demux,
3572 "Stream %d after segment stop %" GST_TIME_FORMAT, stream->index,
3573 GST_TIME_ARGS (demux->common.segment.stop));
3574 gst_buffer_unref (sub);
3577 if (offset >= stream->to_offset
3578 || (GST_CLOCK_TIME_IS_VALID (demux->to_time)
3579 && lace_time > demux->to_time)) {
3580 GST_DEBUG_OBJECT (demux, "Stream %d after playback section",
3582 gst_buffer_unref (sub);
3586 /* handle gaps, e.g. non-zero start-time, or an cue index entry
3587 * that landed us with timestamps not quite intended */
3588 GST_OBJECT_LOCK (demux);
3589 if (demux->max_gap_time &&
3590 GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) &&
3591 demux->common.segment.rate > 0.0) {
3592 GstClockTimeDiff diff;
3594 /* only send segments with increasing start times,
3595 * otherwise if these go back and forth downstream (sinks) increase
3596 * accumulated time and running_time */
3597 diff = GST_CLOCK_DIFF (demux->last_stop_end, lace_time);
3598 if (diff > 0 && diff > demux->max_gap_time
3599 && lace_time > demux->common.segment.start
3600 && (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop)
3601 || lace_time < demux->common.segment.stop)) {
3603 GST_DEBUG_OBJECT (demux,
3604 "Gap of %" G_GINT64_FORMAT " ns detected in"
3605 "stream %d (%" GST_TIME_FORMAT " -> %" GST_TIME_FORMAT "). "
3606 "Sending updated SEGMENT events", diff,
3607 stream->index, GST_TIME_ARGS (stream->pos),
3608 GST_TIME_ARGS (lace_time));
3610 event = gst_event_new_gap (demux->last_stop_end, diff);
3611 GST_OBJECT_UNLOCK (demux);
3612 gst_pad_push_event (stream->pad, event);
3613 GST_OBJECT_LOCK (demux);
3617 if (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.position)
3618 || demux->common.segment.position < lace_time) {
3619 demux->common.segment.position = lace_time;
3621 GST_OBJECT_UNLOCK (demux);
3623 last_stop_end = lace_time;
3625 GST_BUFFER_DURATION (sub) = duration / laces;
3626 last_stop_end += GST_BUFFER_DURATION (sub);
3629 if (!GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) ||
3630 demux->last_stop_end < last_stop_end)
3631 demux->last_stop_end = last_stop_end;
3633 GST_OBJECT_LOCK (demux);
3634 if (demux->common.segment.duration == -1 ||
3635 demux->stream_start_time + demux->common.segment.duration <
3637 demux->common.segment.duration =
3638 last_stop_end - demux->stream_start_time;
3639 GST_OBJECT_UNLOCK (demux);
3640 if (!demux->invalid_duration) {
3641 gst_element_post_message (GST_ELEMENT_CAST (demux),
3642 gst_message_new_duration_changed (GST_OBJECT_CAST (demux)));
3643 demux->invalid_duration = TRUE;
3646 GST_OBJECT_UNLOCK (demux);
3650 stream->pos = lace_time;
3652 gst_matroska_demux_sync_streams (demux);
3654 if (stream->set_discont) {
3655 GST_DEBUG_OBJECT (demux, "marking DISCONT");
3656 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DISCONT);
3657 stream->set_discont = FALSE;
3659 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DISCONT);
3662 /* reverse playback book-keeping */
3663 if (!GST_CLOCK_TIME_IS_VALID (stream->from_time))
3664 stream->from_time = lace_time;
3665 if (stream->from_offset == -1)
3666 stream->from_offset = offset;
3668 GST_DEBUG_OBJECT (demux,
3669 "Pushing lace %d, data of size %" G_GSIZE_FORMAT
3670 " for stream %d, time=%" GST_TIME_FORMAT " and duration=%"
3671 GST_TIME_FORMAT, n, gst_buffer_get_size (sub), stream_num,
3672 GST_TIME_ARGS (buffer_timestamp),
3673 GST_TIME_ARGS (GST_BUFFER_DURATION (sub)));
3676 if (demux->common.element_index) {
3677 if (stream->index_writer_id == -1)
3678 gst_index_get_writer_id (demux->common.element_index,
3679 GST_OBJECT (stream->pad), &stream->index_writer_id);
3681 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
3682 G_GUINT64_FORMAT " for writer id %d",
3683 GST_TIME_ARGS (buffer_timestamp), cluster_offset,
3684 stream->index_writer_id);
3685 gst_index_add_association (demux->common.element_index,
3686 stream->index_writer_id, GST_BUFFER_FLAG_IS_SET (sub,
3687 GST_BUFFER_FLAG_DELTA_UNIT) ? 0 : GST_ASSOCIATION_FLAG_KEY_UNIT,
3688 GST_FORMAT_TIME, buffer_timestamp, GST_FORMAT_BYTES, cluster_offset,
3693 /* Postprocess the buffers depending on the codec used */
3694 if (stream->postprocess_frame) {
3695 GST_LOG_OBJECT (demux, "running post process");
3696 ret = stream->postprocess_frame (GST_ELEMENT (demux), stream, &sub);
3699 /* At this point, we have a sub-buffer pointing at data within a larger
3700 buffer. This data might not be aligned with anything. If the data is
3701 raw samples though, we want it aligned to the raw type (eg, 4 bytes
3702 for 32 bit samples, etc), or bad things will happen downstream as
3703 elements typically assume minimal alignment.
3704 Therefore, create an aligned copy if necessary. */
3705 g_assert (stream->alignment <= G_MEM_ALIGN);
3706 sub = gst_matroska_demux_align_buffer (demux, sub, stream->alignment);
3708 if (GST_BUFFER_PTS_IS_VALID (sub)) {
3709 stream->pos = GST_BUFFER_PTS (sub);
3710 if (GST_BUFFER_DURATION_IS_VALID (sub))
3711 stream->pos += GST_BUFFER_DURATION (sub);
3712 } else if (GST_BUFFER_DTS_IS_VALID (sub)) {
3713 stream->pos = GST_BUFFER_DTS (sub);
3714 if (GST_BUFFER_DURATION_IS_VALID (sub))
3715 stream->pos += GST_BUFFER_DURATION (sub);
3718 ret = gst_pad_push (stream->pad, sub);
3720 if (demux->common.segment.rate < 0) {
3721 if (lace_time > demux->common.segment.stop && ret == GST_FLOW_EOS) {
3722 /* In reverse playback we can get a GST_FLOW_EOS when
3723 * we are at the end of the segment, so we just need to jump
3724 * back to the previous section. */
3725 GST_DEBUG_OBJECT (demux, "downstream has reached end of segment");
3730 ret = gst_flow_combiner_update_pad_flow (demux->flowcombiner,
3734 size -= lace_size[n];
3735 if (lace_time != GST_CLOCK_TIME_NONE && duration)
3736 lace_time += duration / laces;
3738 lace_time = GST_CLOCK_TIME_NONE;
3744 gst_buffer_unmap (buf, &map);
3745 gst_buffer_unref (buf);
3757 ret = gst_flow_combiner_update_pad_flow (demux->flowcombiner, stream->pad,
3763 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Invalid lacing size"));
3764 /* non-fatal, try next block(group) */
3770 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Data error"));
3771 /* non-fatal, try next block(group) */
3777 /* return FALSE if block(group) should be skipped (due to a seek) */
3778 static inline gboolean
3779 gst_matroska_demux_seek_block (GstMatroskaDemux * demux)
3781 if (G_UNLIKELY (demux->seek_block)) {
3782 if (!(--demux->seek_block)) {
3785 GST_LOG_OBJECT (demux, "should skip block due to seek");
3793 static GstFlowReturn
3794 gst_matroska_demux_parse_contents_seekentry (GstMatroskaDemux * demux,
3798 guint64 seek_pos = (guint64) - 1;
3799 guint32 seek_id = 0;
3802 DEBUG_ELEMENT_START (demux, ebml, "Seek");
3804 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3805 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
3809 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3810 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3814 case GST_MATROSKA_ID_SEEKID:
3818 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
3821 GST_DEBUG_OBJECT (demux, "SeekID: %" G_GUINT64_FORMAT, t);
3826 case GST_MATROSKA_ID_SEEKPOSITION:
3830 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
3833 if (t > G_MAXINT64) {
3834 GST_WARNING_OBJECT (demux,
3835 "Too large SeekPosition %" G_GUINT64_FORMAT, t);
3839 GST_DEBUG_OBJECT (demux, "SeekPosition: %" G_GUINT64_FORMAT, t);
3845 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3851 if (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)
3854 if (!seek_id || seek_pos == (guint64) - 1) {
3855 GST_WARNING_OBJECT (demux, "Incomplete seekhead entry (0x%x/%"
3856 G_GUINT64_FORMAT ")", seek_id, seek_pos);
3861 case GST_MATROSKA_ID_SEEKHEAD:
3864 case GST_MATROSKA_ID_CUES:
3865 case GST_MATROSKA_ID_TAGS:
3866 case GST_MATROSKA_ID_TRACKS:
3867 case GST_MATROSKA_ID_SEGMENTINFO:
3868 case GST_MATROSKA_ID_ATTACHMENTS:
3869 case GST_MATROSKA_ID_CHAPTERS:
3871 guint64 before_pos, length;
3875 length = gst_matroska_read_common_get_length (&demux->common);
3876 before_pos = demux->common.offset;
3878 if (length == (guint64) - 1) {
3879 GST_DEBUG_OBJECT (demux, "no upstream length, skipping SeakHead entry");
3883 /* check for validity */
3884 if (seek_pos + demux->common.ebml_segment_start + 12 >= length) {
3885 GST_WARNING_OBJECT (demux,
3886 "SeekHead reference lies outside file!" " (%"
3887 G_GUINT64_FORMAT "+%" G_GUINT64_FORMAT "+12 >= %"
3888 G_GUINT64_FORMAT ")", seek_pos, demux->common.ebml_segment_start,
3893 /* only pick up index location when streaming */
3894 if (demux->streaming) {
3895 if (seek_id == GST_MATROSKA_ID_CUES) {
3896 demux->index_offset = seek_pos + demux->common.ebml_segment_start;
3897 GST_DEBUG_OBJECT (demux, "Cues located at offset %" G_GUINT64_FORMAT,
3898 demux->index_offset);
3904 demux->common.offset = seek_pos + demux->common.ebml_segment_start;
3907 if ((ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
3908 GST_ELEMENT_CAST (demux), &id, &length, &needed)) !=
3912 if (id != seek_id) {
3913 GST_WARNING_OBJECT (demux,
3914 "We looked for ID=0x%x but got ID=0x%x (pos=%" G_GUINT64_FORMAT ")",
3915 seek_id, id, seek_pos + demux->common.ebml_segment_start);
3918 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
3923 demux->common.offset = before_pos;
3927 case GST_MATROSKA_ID_CLUSTER:
3929 guint64 pos = seek_pos + demux->common.ebml_segment_start;
3931 GST_LOG_OBJECT (demux, "Cluster position");
3932 if (G_UNLIKELY (!demux->clusters))
3933 demux->clusters = g_array_sized_new (TRUE, TRUE, sizeof (guint64), 100);
3934 g_array_append_val (demux->clusters, pos);
3939 GST_DEBUG_OBJECT (demux, "Ignoring Seek entry for ID=0x%x", seek_id);
3942 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
3947 static GstFlowReturn
3948 gst_matroska_demux_parse_contents (GstMatroskaDemux * demux, GstEbmlRead * ebml)
3950 GstFlowReturn ret = GST_FLOW_OK;
3953 DEBUG_ELEMENT_START (demux, ebml, "SeekHead");
3955 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3956 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
3960 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3961 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3965 case GST_MATROSKA_ID_SEEKENTRY:
3967 ret = gst_matroska_demux_parse_contents_seekentry (demux, ebml);
3968 /* Ignore EOS and errors here */
3969 if (ret != GST_FLOW_OK) {
3970 GST_DEBUG_OBJECT (demux, "Ignoring %s", gst_flow_get_name (ret));
3977 ret = gst_matroska_read_common_parse_skip (&demux->common,
3978 ebml, "SeekHead", id);
3983 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
3985 /* Sort clusters by position for easier searching */
3986 if (demux->clusters)
3987 g_array_sort (demux->clusters, (GCompareFunc) gst_matroska_cluster_compare);
3992 #define GST_FLOW_OVERFLOW GST_FLOW_CUSTOM_ERROR
3994 #define MAX_BLOCK_SIZE (15 * 1024 * 1024)
3996 static inline GstFlowReturn
3997 gst_matroska_demux_check_read_size (GstMatroskaDemux * demux, guint64 bytes)
3999 if (G_UNLIKELY (bytes > MAX_BLOCK_SIZE)) {
4000 /* only a few blocks are expected/allowed to be large,
4001 * and will be recursed into, whereas others will be read and must fit */
4002 if (demux->streaming) {
4003 /* fatal in streaming case, as we can't step over easily */
4004 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4005 ("reading large block of size %" G_GUINT64_FORMAT " not supported; "
4006 "file might be corrupt.", bytes));
4007 return GST_FLOW_ERROR;
4009 /* indicate higher level to quietly give up */
4010 GST_DEBUG_OBJECT (demux,
4011 "too large block of size %" G_GUINT64_FORMAT, bytes);
4012 return GST_FLOW_ERROR;
4019 /* returns TRUE if we truely are in error state, and should give up */
4020 static inline GstFlowReturn
4021 gst_matroska_demux_check_parse_error (GstMatroskaDemux * demux)
4023 if (!demux->streaming && demux->next_cluster_offset > 0) {
4024 /* just repositioning to where next cluster should be and try from there */
4025 GST_WARNING_OBJECT (demux, "parse error, trying next cluster expected at %"
4026 G_GUINT64_FORMAT, demux->next_cluster_offset);
4027 demux->common.offset = demux->next_cluster_offset;
4028 demux->next_cluster_offset = 0;
4034 /* sigh, one last attempt above and beyond call of duty ...;
4035 * search for cluster mark following current pos */
4036 pos = demux->common.offset;
4037 GST_WARNING_OBJECT (demux, "parse error, looking for next cluster");
4038 if ((ret = gst_matroska_demux_search_cluster (demux, &pos)) != GST_FLOW_OK) {
4039 /* did not work, give up */
4042 GST_DEBUG_OBJECT (demux, "... found at %" G_GUINT64_FORMAT, pos);
4043 /* try that position */
4044 demux->common.offset = pos;
4050 static inline GstFlowReturn
4051 gst_matroska_demux_flush (GstMatroskaDemux * demux, guint flush)
4053 GST_LOG_OBJECT (demux, "skipping %d bytes", flush);
4054 demux->common.offset += flush;
4055 if (demux->streaming) {
4058 /* hard to skip large blocks when streaming */
4059 ret = gst_matroska_demux_check_read_size (demux, flush);
4060 if (ret != GST_FLOW_OK)
4062 if (flush <= gst_adapter_available (demux->common.adapter))
4063 gst_adapter_flush (demux->common.adapter, flush);
4065 return GST_FLOW_EOS;
4070 /* initializes @ebml with @bytes from input stream at current offset.
4071 * Returns EOS if insufficient available,
4072 * ERROR if too much was attempted to read. */
4073 static inline GstFlowReturn
4074 gst_matroska_demux_take (GstMatroskaDemux * demux, guint64 bytes,
4077 GstBuffer *buffer = NULL;
4078 GstFlowReturn ret = GST_FLOW_OK;
4080 GST_LOG_OBJECT (demux, "taking %" G_GUINT64_FORMAT " bytes for parsing",
4082 ret = gst_matroska_demux_check_read_size (demux, bytes);
4083 if (G_UNLIKELY (ret != GST_FLOW_OK)) {
4084 if (!demux->streaming) {
4085 /* in pull mode, we can skip */
4086 if ((ret = gst_matroska_demux_flush (demux, bytes)) == GST_FLOW_OK)
4087 ret = GST_FLOW_OVERFLOW;
4089 /* otherwise fatal */
4090 ret = GST_FLOW_ERROR;
4094 if (demux->streaming) {
4095 if (gst_adapter_available (demux->common.adapter) >= bytes)
4096 buffer = gst_adapter_take_buffer (demux->common.adapter, bytes);
4100 ret = gst_matroska_read_common_peek_bytes (&demux->common,
4101 demux->common.offset, bytes, &buffer, NULL);
4102 if (G_LIKELY (buffer)) {
4103 gst_ebml_read_init (ebml, GST_ELEMENT_CAST (demux), buffer,
4104 demux->common.offset);
4105 demux->common.offset += bytes;
4112 gst_matroska_demux_check_seekability (GstMatroskaDemux * demux)
4115 gboolean seekable = FALSE;
4116 gint64 start = -1, stop = -1;
4118 query = gst_query_new_seeking (GST_FORMAT_BYTES);
4119 if (!gst_pad_peer_query (demux->common.sinkpad, query)) {
4120 GST_DEBUG_OBJECT (demux, "seeking query failed");
4124 gst_query_parse_seeking (query, NULL, &seekable, &start, &stop);
4126 /* try harder to query upstream size if we didn't get it the first time */
4127 if (seekable && stop == -1) {
4128 GST_DEBUG_OBJECT (demux, "doing duration query to fix up unset stop");
4129 gst_pad_peer_query_duration (demux->common.sinkpad, GST_FORMAT_BYTES,
4133 /* if upstream doesn't know the size, it's likely that it's not seekable in
4134 * practice even if it technically may be seekable */
4135 if (seekable && (start != 0 || stop <= start)) {
4136 GST_DEBUG_OBJECT (demux, "seekable but unknown start/stop -> disable");
4141 GST_INFO_OBJECT (demux, "seekable: %d (%" G_GUINT64_FORMAT " - %"
4142 G_GUINT64_FORMAT ")", seekable, start, stop);
4143 demux->seekable = seekable;
4145 gst_query_unref (query);
4148 static GstFlowReturn
4149 gst_matroska_demux_find_tracks (GstMatroskaDemux * demux)
4155 GstFlowReturn ret = GST_FLOW_OK;
4157 GST_WARNING_OBJECT (demux,
4158 "Found Cluster element before Tracks, searching Tracks");
4161 before_pos = demux->common.offset;
4163 /* Search Tracks element */
4165 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4166 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4167 if (ret != GST_FLOW_OK)
4170 if (id != GST_MATROSKA_ID_TRACKS) {
4171 /* we may be skipping large cluster here, so forego size check etc */
4172 /* ... but we can't skip undefined size; force error */
4173 if (length == G_MAXUINT64) {
4174 ret = gst_matroska_demux_check_read_size (demux, length);
4177 demux->common.offset += needed;
4178 demux->common.offset += length;
4183 /* will lead to track parsing ... */
4184 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4189 demux->common.offset = before_pos;
4194 #define GST_READ_CHECK(stmt) \
4196 if (G_UNLIKELY ((ret = (stmt)) != GST_FLOW_OK)) { \
4197 if (ret == GST_FLOW_OVERFLOW) { \
4198 ret = GST_FLOW_OK; \
4204 static GstFlowReturn
4205 gst_matroska_demux_parse_id (GstMatroskaDemux * demux, guint32 id,
4206 guint64 length, guint needed)
4208 GstEbmlRead ebml = { 0, };
4209 GstFlowReturn ret = GST_FLOW_OK;
4212 GST_LOG_OBJECT (demux, "Parsing Element id 0x%x, "
4213 "size %" G_GUINT64_FORMAT ", prefix %d", id, length, needed);
4215 /* if we plan to read and parse this element, we need prefix (id + length)
4216 * and the contents */
4217 /* mind about overflow wrap-around when dealing with undefined size */
4219 if (G_LIKELY (length != G_MAXUINT64))
4222 switch (demux->common.state) {
4223 case GST_MATROSKA_READ_STATE_START:
4225 case GST_EBML_ID_HEADER:
4226 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4227 ret = gst_matroska_read_common_parse_header (&demux->common, &ebml);
4228 if (ret != GST_FLOW_OK)
4230 demux->common.state = GST_MATROSKA_READ_STATE_SEGMENT;
4231 gst_matroska_demux_check_seekability (demux);
4234 goto invalid_header;
4238 case GST_MATROSKA_READ_STATE_SEGMENT:
4240 case GST_MATROSKA_ID_SEGMENT:
4241 /* eat segment prefix */
4242 GST_READ_CHECK (gst_matroska_demux_flush (demux, needed));
4243 GST_DEBUG_OBJECT (demux,
4244 "Found Segment start at offset %" G_GUINT64_FORMAT " with size %"
4245 G_GUINT64_FORMAT, demux->common.offset, length);
4246 /* seeks are from the beginning of the segment,
4247 * after the segment ID/length */
4248 demux->common.ebml_segment_start = demux->common.offset;
4250 length = G_MAXUINT64;
4251 demux->common.ebml_segment_length = length;
4252 demux->common.state = GST_MATROSKA_READ_STATE_HEADER;
4255 GST_WARNING_OBJECT (demux,
4256 "Expected a Segment ID (0x%x), but received 0x%x!",
4257 GST_MATROSKA_ID_SEGMENT, id);
4258 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4262 case GST_MATROSKA_READ_STATE_SCANNING:
4263 if (id != GST_MATROSKA_ID_CLUSTER &&
4264 id != GST_MATROSKA_ID_CLUSTERTIMECODE)
4267 case GST_MATROSKA_READ_STATE_HEADER:
4268 case GST_MATROSKA_READ_STATE_DATA:
4269 case GST_MATROSKA_READ_STATE_SEEK:
4271 case GST_MATROSKA_ID_SEGMENTINFO:
4272 if (!demux->common.segmentinfo_parsed) {
4273 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4274 ret = gst_matroska_read_common_parse_info (&demux->common,
4275 GST_ELEMENT_CAST (demux), &ebml);
4276 if (ret == GST_FLOW_OK)
4277 gst_matroska_demux_send_tags (demux);
4279 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4282 case GST_MATROSKA_ID_TRACKS:
4283 if (!demux->tracks_parsed) {
4284 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4285 ret = gst_matroska_demux_parse_tracks (demux, &ebml);
4287 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4290 case GST_MATROSKA_ID_CLUSTER:
4291 if (G_UNLIKELY (!demux->tracks_parsed)) {
4292 if (demux->streaming) {
4293 GST_DEBUG_OBJECT (demux, "Cluster before Track");
4294 goto not_streamable;
4296 ret = gst_matroska_demux_find_tracks (demux);
4297 if (!demux->tracks_parsed)
4301 if (G_UNLIKELY (demux->common.state
4302 == GST_MATROSKA_READ_STATE_HEADER)) {
4303 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
4304 demux->first_cluster_offset = demux->common.offset;
4305 GST_DEBUG_OBJECT (demux, "signaling no more pads");
4306 gst_element_no_more_pads (GST_ELEMENT (demux));
4307 /* send initial segment - we wait till we know the first
4308 incoming timestamp, so we can properly set the start of
4310 demux->need_segment = TRUE;
4312 demux->cluster_time = GST_CLOCK_TIME_NONE;
4313 demux->cluster_offset = demux->common.offset;
4314 if (G_UNLIKELY (!demux->seek_first && demux->seek_block)) {
4315 GST_DEBUG_OBJECT (demux, "seek target block %" G_GUINT64_FORMAT
4316 " not found in Cluster, trying next Cluster's first block instead",
4318 demux->seek_block = 0;
4320 demux->seek_first = FALSE;
4321 /* record next cluster for recovery */
4322 if (read != G_MAXUINT64)
4323 demux->next_cluster_offset = demux->cluster_offset + read;
4324 /* eat cluster prefix */
4325 gst_matroska_demux_flush (demux, needed);
4327 case GST_MATROSKA_ID_CLUSTERTIMECODE:
4331 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4332 if ((ret = gst_ebml_read_uint (&ebml, &id, &num)) != GST_FLOW_OK)
4334 GST_DEBUG_OBJECT (demux, "ClusterTimeCode: %" G_GUINT64_FORMAT, num);
4335 demux->cluster_time = num;
4337 if (demux->common.element_index) {
4338 if (demux->common.element_index_writer_id == -1)
4339 gst_index_get_writer_id (demux->common.element_index,
4340 GST_OBJECT (demux), &demux->common.element_index_writer_id);
4341 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
4342 G_GUINT64_FORMAT " for writer id %d",
4343 GST_TIME_ARGS (demux->cluster_time), demux->cluster_offset,
4344 demux->common.element_index_writer_id);
4345 gst_index_add_association (demux->common.element_index,
4346 demux->common.element_index_writer_id,
4347 GST_ASSOCIATION_FLAG_KEY_UNIT,
4348 GST_FORMAT_TIME, demux->cluster_time,
4349 GST_FORMAT_BYTES, demux->cluster_offset, NULL);
4354 case GST_MATROSKA_ID_BLOCKGROUP:
4355 if (!gst_matroska_demux_seek_block (demux))
4357 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4358 DEBUG_ELEMENT_START (demux, &ebml, "BlockGroup");
4359 if ((ret = gst_ebml_read_master (&ebml, &id)) == GST_FLOW_OK) {
4360 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4361 &ebml, demux->cluster_time, demux->cluster_offset, FALSE);
4363 DEBUG_ELEMENT_STOP (demux, &ebml, "BlockGroup", ret);
4365 case GST_MATROSKA_ID_SIMPLEBLOCK:
4366 if (!gst_matroska_demux_seek_block (demux))
4368 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4369 DEBUG_ELEMENT_START (demux, &ebml, "SimpleBlock");
4370 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4371 &ebml, demux->cluster_time, demux->cluster_offset, TRUE);
4372 DEBUG_ELEMENT_STOP (demux, &ebml, "SimpleBlock", ret);
4374 case GST_MATROSKA_ID_ATTACHMENTS:
4375 if (!demux->common.attachments_parsed) {
4376 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4377 ret = gst_matroska_read_common_parse_attachments (&demux->common,
4378 GST_ELEMENT_CAST (demux), &ebml);
4379 if (ret == GST_FLOW_OK)
4380 gst_matroska_demux_send_tags (demux);
4382 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4385 case GST_MATROSKA_ID_TAGS:
4386 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4387 ret = gst_matroska_read_common_parse_metadata (&demux->common,
4388 GST_ELEMENT_CAST (demux), &ebml);
4389 if (ret == GST_FLOW_OK)
4390 gst_matroska_demux_send_tags (demux);
4392 case GST_MATROSKA_ID_CHAPTERS:
4393 if (!demux->common.chapters_parsed) {
4394 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4396 gst_matroska_read_common_parse_chapters (&demux->common, &ebml);
4398 if (demux->common.toc) {
4399 gst_matroska_demux_send_event (demux,
4400 gst_event_new_toc (demux->common.toc, FALSE));
4403 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4405 case GST_MATROSKA_ID_SEEKHEAD:
4406 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4407 ret = gst_matroska_demux_parse_contents (demux, &ebml);
4409 case GST_MATROSKA_ID_CUES:
4410 if (demux->common.index_parsed) {
4411 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4414 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4415 ret = gst_matroska_read_common_parse_index (&demux->common, &ebml);
4416 /* only push based; delayed index building */
4417 if (ret == GST_FLOW_OK
4418 && demux->common.state == GST_MATROSKA_READ_STATE_SEEK) {
4421 GST_OBJECT_LOCK (demux);
4422 event = demux->seek_event;
4423 demux->seek_event = NULL;
4424 GST_OBJECT_UNLOCK (demux);
4427 /* unlikely to fail, since we managed to seek to this point */
4428 if (!gst_matroska_demux_handle_seek_event (demux, NULL, event)) {
4429 gst_event_unref (event);
4432 gst_event_unref (event);
4433 /* resume data handling, main thread clear to seek again */
4434 GST_OBJECT_LOCK (demux);
4435 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
4436 GST_OBJECT_UNLOCK (demux);
4439 case GST_MATROSKA_ID_POSITION:
4440 case GST_MATROSKA_ID_PREVSIZE:
4441 case GST_MATROSKA_ID_ENCRYPTEDBLOCK:
4442 case GST_MATROSKA_ID_SILENTTRACKS:
4443 GST_DEBUG_OBJECT (demux,
4444 "Skipping Cluster subelement 0x%x - ignoring", id);
4448 GST_DEBUG_OBJECT (demux, "skipping Element 0x%x", id);
4449 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4455 if (ret == GST_FLOW_PARSE)
4459 gst_ebml_read_clear (&ebml);
4465 /* simply exit, maybe not enough data yet */
4466 /* no ebml to clear if read error */
4471 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4472 ("Failed to parse Element 0x%x", id));
4473 ret = GST_FLOW_ERROR;
4478 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4479 ("File layout does not permit streaming"));
4480 ret = GST_FLOW_ERROR;
4485 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4486 ("No Tracks element found"));
4487 ret = GST_FLOW_ERROR;
4492 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Invalid header"));
4493 ret = GST_FLOW_ERROR;
4498 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Failed to seek"));
4499 ret = GST_FLOW_ERROR;
4505 gst_matroska_demux_loop (GstPad * pad)
4507 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (pad));
4513 /* If we have to close a segment, send a new segment to do this now */
4514 if (G_LIKELY (demux->common.state == GST_MATROSKA_READ_STATE_DATA)) {
4515 if (G_UNLIKELY (demux->new_segment)) {
4516 gst_matroska_demux_send_event (demux, demux->new_segment);
4517 demux->new_segment = NULL;
4521 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4522 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4523 if (ret == GST_FLOW_EOS) {
4525 } else if (ret == GST_FLOW_FLUSHING) {
4527 } else if (ret != GST_FLOW_OK) {
4528 ret = gst_matroska_demux_check_parse_error (demux);
4530 /* Only handle EOS as no error if we're outside the segment already */
4531 if (ret == GST_FLOW_EOS && (demux->common.ebml_segment_length != G_MAXUINT64
4532 && demux->common.offset >=
4533 demux->common.ebml_segment_start +
4534 demux->common.ebml_segment_length))
4536 else if (ret != GST_FLOW_OK)
4542 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
4543 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
4546 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4547 if (ret == GST_FLOW_EOS)
4549 if (ret != GST_FLOW_OK)
4552 /* check if we're at the end of a configured segment */
4553 if (G_LIKELY (demux->common.src->len)) {
4556 g_assert (demux->common.num_streams == demux->common.src->len);
4557 for (i = 0; i < demux->common.src->len; i++) {
4558 GstMatroskaTrackContext *context = g_ptr_array_index (demux->common.src,
4560 GST_DEBUG_OBJECT (context->pad, "pos %" GST_TIME_FORMAT,
4561 GST_TIME_ARGS (context->pos));
4562 if (context->eos == FALSE)
4566 GST_INFO_OBJECT (demux, "All streams are EOS");
4572 if (G_UNLIKELY (demux->cached_length == G_MAXUINT64 ||
4573 demux->common.offset >= demux->cached_length)) {
4574 demux->cached_length = gst_matroska_read_common_get_length (&demux->common);
4575 if (demux->common.offset == demux->cached_length) {
4576 GST_LOG_OBJECT (demux, "Reached end of stream");
4587 if (demux->common.segment.rate < 0.0) {
4588 ret = gst_matroska_demux_seek_to_previous_keyframe (demux);
4589 if (ret == GST_FLOW_OK)
4596 const gchar *reason = gst_flow_get_name (ret);
4597 gboolean push_eos = FALSE;
4599 GST_LOG_OBJECT (demux, "pausing task, reason %s", reason);
4600 gst_pad_pause_task (demux->common.sinkpad);
4602 if (ret == GST_FLOW_EOS) {
4603 /* perform EOS logic */
4605 /* If we were in the headers, make sure we send no-more-pads.
4606 This will ensure decodebin does not get stuck thinking
4607 the chain is not complete yet, and waiting indefinitely. */
4608 if (G_UNLIKELY (demux->common.state == GST_MATROSKA_READ_STATE_HEADER)) {
4609 if (demux->common.src->len == 0) {
4610 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
4611 ("No pads created"));
4613 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL),
4614 ("Failed to finish reading headers"));
4616 gst_element_no_more_pads (GST_ELEMENT (demux));
4619 if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
4622 /* for segment playback we need to post when (in stream time)
4623 * we stopped, this is either stop (when set) or the duration. */
4624 if ((stop = demux->common.segment.stop) == -1)
4625 stop = demux->last_stop_end;
4627 GST_LOG_OBJECT (demux, "Sending segment done, at end of segment");
4628 gst_element_post_message (GST_ELEMENT (demux),
4629 gst_message_new_segment_done (GST_OBJECT (demux), GST_FORMAT_TIME,
4631 gst_matroska_demux_send_event (demux,
4632 gst_event_new_segment_done (GST_FORMAT_TIME, stop));
4636 } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS) {
4637 /* for fatal errors we post an error message */
4638 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
4639 ("stream stopped, reason %s", reason));
4643 /* send EOS, and prevent hanging if no streams yet */
4644 GST_LOG_OBJECT (demux, "Sending EOS, at end of stream");
4645 if (!gst_matroska_demux_send_event (demux, gst_event_new_eos ()) &&
4646 (ret == GST_FLOW_EOS)) {
4647 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4648 (NULL), ("got eos but no streams (yet)"));
4656 * Create and push a flushing seek event upstream
4659 perform_seek_to_offset (GstMatroskaDemux * demux, gdouble rate, guint64 offset,
4665 GST_DEBUG_OBJECT (demux, "Seeking to %" G_GUINT64_FORMAT, offset);
4668 gst_event_new_seek (rate, GST_FORMAT_BYTES,
4669 GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, GST_SEEK_TYPE_SET, offset,
4670 GST_SEEK_TYPE_NONE, -1);
4671 gst_event_set_seqnum (event, seqnum);
4673 res = gst_pad_push_event (demux->common.sinkpad, event);
4675 /* segment event will update offset */
4679 static GstFlowReturn
4680 gst_matroska_demux_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
4682 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4684 GstFlowReturn ret = GST_FLOW_OK;
4689 if (G_UNLIKELY (GST_BUFFER_IS_DISCONT (buffer))) {
4690 GST_DEBUG_OBJECT (demux, "got DISCONT");
4691 gst_adapter_clear (demux->common.adapter);
4692 GST_OBJECT_LOCK (demux);
4693 gst_matroska_read_common_reset_streams (&demux->common,
4694 GST_CLOCK_TIME_NONE, FALSE);
4695 GST_OBJECT_UNLOCK (demux);
4698 gst_adapter_push (demux->common.adapter, buffer);
4702 available = gst_adapter_available (demux->common.adapter);
4704 ret = gst_matroska_read_common_peek_id_length_push (&demux->common,
4705 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4706 if (G_UNLIKELY (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)) {
4707 if (demux->common.ebml_segment_length != G_MAXUINT64
4708 && demux->common.offset >=
4709 demux->common.ebml_segment_start + demux->common.ebml_segment_length)
4714 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
4715 "size %" G_GUINT64_FORMAT ", needed %d, available %d",
4716 demux->common.offset, id, length, needed, available);
4718 if (needed > available)
4721 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4722 if (ret == GST_FLOW_EOS) {
4723 /* need more data */
4725 } else if (ret != GST_FLOW_OK) {
4732 gst_matroska_demux_handle_sink_event (GstPad * pad, GstObject * parent,
4735 gboolean res = TRUE;
4736 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4738 GST_DEBUG_OBJECT (demux,
4739 "have event type %s: %p on sink pad", GST_EVENT_TYPE_NAME (event), event);
4741 switch (GST_EVENT_TYPE (event)) {
4742 case GST_EVENT_SEGMENT:
4744 const GstSegment *segment;
4746 /* some debug output */
4747 gst_event_parse_segment (event, &segment);
4748 /* FIXME: do we need to update segment base here (like accum in 0.10)? */
4749 GST_DEBUG_OBJECT (demux,
4750 "received format %d segment %" GST_SEGMENT_FORMAT, segment->format,
4753 if (demux->common.state < GST_MATROSKA_READ_STATE_DATA) {
4754 GST_DEBUG_OBJECT (demux, "still starting");
4758 /* we only expect a BYTE segment, e.g. following a seek */
4759 if (segment->format != GST_FORMAT_BYTES) {
4760 GST_DEBUG_OBJECT (demux, "unsupported segment format, ignoring");
4764 GST_DEBUG_OBJECT (demux, "clearing segment state");
4765 GST_OBJECT_LOCK (demux);
4766 /* clear current segment leftover */
4767 gst_adapter_clear (demux->common.adapter);
4768 /* and some streaming setup */
4769 demux->common.offset = segment->start;
4770 /* accumulate base based on current position */
4771 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.position))
4772 demux->common.segment.base +=
4773 (MAX (demux->common.segment.position, demux->stream_start_time)
4774 - demux->stream_start_time) / fabs (demux->common.segment.rate);
4775 /* do not know where we are;
4776 * need to come across a cluster and generate segment */
4777 demux->common.segment.position = GST_CLOCK_TIME_NONE;
4778 demux->cluster_time = GST_CLOCK_TIME_NONE;
4779 demux->cluster_offset = 0;
4780 demux->need_segment = TRUE;
4781 demux->segment_seqnum = gst_event_get_seqnum (event);
4782 /* but keep some of the upstream segment */
4783 demux->common.segment.rate = segment->rate;
4784 /* also check if need to keep some of the requested seek position */
4785 if (demux->seek_offset == segment->start) {
4786 GST_DEBUG_OBJECT (demux, "position matches requested seek");
4787 demux->common.segment.position = demux->requested_seek_time;
4789 GST_DEBUG_OBJECT (demux, "unexpected segment position");
4791 demux->requested_seek_time = GST_CLOCK_TIME_NONE;
4792 demux->seek_offset = -1;
4793 GST_OBJECT_UNLOCK (demux);
4795 /* chain will send initial segment after pads have been added,
4796 * or otherwise come up with one */
4797 GST_DEBUG_OBJECT (demux, "eating event");
4798 gst_event_unref (event);
4804 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
4805 gst_event_unref (event);
4806 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4807 (NULL), ("got eos and didn't receive a complete header object"));
4808 } else if (demux->common.num_streams == 0) {
4809 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4810 (NULL), ("got eos but no streams (yet)"));
4812 gst_matroska_demux_send_event (demux, event);
4816 case GST_EVENT_FLUSH_STOP:
4820 gst_adapter_clear (demux->common.adapter);
4821 GST_OBJECT_LOCK (demux);
4822 gst_matroska_read_common_reset_streams (&demux->common,
4823 GST_CLOCK_TIME_NONE, TRUE);
4824 gst_flow_combiner_reset (demux->flowcombiner);
4825 dur = demux->common.segment.duration;
4826 gst_segment_init (&demux->common.segment, GST_FORMAT_TIME);
4827 demux->common.segment.duration = dur;
4828 demux->cluster_time = GST_CLOCK_TIME_NONE;
4829 demux->cluster_offset = 0;
4830 GST_OBJECT_UNLOCK (demux);
4834 res = gst_pad_event_default (pad, parent, event);
4842 gst_matroska_demux_sink_activate (GstPad * sinkpad, GstObject * parent)
4844 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4846 gboolean pull_mode = FALSE;
4848 query = gst_query_new_scheduling ();
4850 if (gst_pad_peer_query (sinkpad, query))
4851 pull_mode = gst_query_has_scheduling_mode_with_flags (query,
4852 GST_PAD_MODE_PULL, GST_SCHEDULING_FLAG_SEEKABLE);
4854 gst_query_unref (query);
4857 GST_DEBUG ("going to pull mode");
4858 demux->streaming = FALSE;
4859 return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PULL, TRUE);
4861 GST_DEBUG ("going to push (streaming) mode");
4862 demux->streaming = TRUE;
4863 return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PUSH, TRUE);
4868 gst_matroska_demux_sink_activate_mode (GstPad * sinkpad, GstObject * parent,
4869 GstPadMode mode, gboolean active)
4872 case GST_PAD_MODE_PULL:
4874 /* if we have a scheduler we can start the task */
4875 gst_pad_start_task (sinkpad, (GstTaskFunction) gst_matroska_demux_loop,
4878 gst_pad_stop_task (sinkpad);
4881 case GST_PAD_MODE_PUSH:
4889 gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext *
4890 videocontext, const gchar * codec_id, guint8 * data, guint size,
4891 gchar ** codec_name, guint32 * riff_fourcc)
4893 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) videocontext;
4894 GstCaps *caps = NULL;
4896 g_assert (videocontext != NULL);
4897 g_assert (codec_name != NULL);
4902 /* TODO: check if we have all codec types from matroska-ids.h
4903 * check if we have to do more special things with codec_private
4906 * GST_MATROSKA_CODEC_ID_VIDEO_QUICKTIME
4907 * GST_MATROSKA_CODEC_ID_VIDEO_SNOW
4910 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VFW_FOURCC)) {
4911 gst_riff_strf_vids *vids = NULL;
4914 GstBuffer *buf = NULL;
4916 vids = (gst_riff_strf_vids *) data;
4918 /* assure size is big enough */
4920 GST_WARNING ("Too small BITMAPINFOHEADER (%d bytes)", size);
4923 if (size < sizeof (gst_riff_strf_vids)) {
4924 vids = g_new (gst_riff_strf_vids, 1);
4925 memcpy (vids, data, size);
4928 context->dts_only = TRUE; /* VFW files only store DTS */
4930 /* little-endian -> byte-order */
4931 vids->size = GUINT32_FROM_LE (vids->size);
4932 vids->width = GUINT32_FROM_LE (vids->width);
4933 vids->height = GUINT32_FROM_LE (vids->height);
4934 vids->planes = GUINT16_FROM_LE (vids->planes);
4935 vids->bit_cnt = GUINT16_FROM_LE (vids->bit_cnt);
4936 vids->compression = GUINT32_FROM_LE (vids->compression);
4937 vids->image_size = GUINT32_FROM_LE (vids->image_size);
4938 vids->xpels_meter = GUINT32_FROM_LE (vids->xpels_meter);
4939 vids->ypels_meter = GUINT32_FROM_LE (vids->ypels_meter);
4940 vids->num_colors = GUINT32_FROM_LE (vids->num_colors);
4941 vids->imp_colors = GUINT32_FROM_LE (vids->imp_colors);
4943 if (size > sizeof (gst_riff_strf_vids)) { /* some extra_data */
4944 gsize offset = sizeof (gst_riff_strf_vids);
4947 gst_buffer_new_wrapped (g_memdup ((guint8 *) vids + offset,
4948 size - offset), size - offset);
4952 *riff_fourcc = vids->compression;
4954 caps = gst_riff_create_video_caps (vids->compression, NULL, vids,
4955 buf, NULL, codec_name);
4958 GST_WARNING ("Unhandled RIFF fourcc %" GST_FOURCC_FORMAT,
4959 GST_FOURCC_ARGS (vids->compression));
4961 static GstStaticCaps intra_caps = GST_STATIC_CAPS ("image/jpeg; "
4962 "video/x-raw; image/png; video/x-dv; video/x-huffyuv; video/x-ffv; "
4963 "video/x-compressed-yuv");
4964 context->intra_only =
4965 gst_caps_can_intersect (gst_static_caps_get (&intra_caps), caps);
4969 gst_buffer_unref (buf);
4971 if (vids != (gst_riff_strf_vids *) data)
4974 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_UNCOMPRESSED)) {
4976 GstVideoFormat format;
4978 gst_video_info_init (&info);
4979 switch (videocontext->fourcc) {
4980 case GST_MAKE_FOURCC ('I', '4', '2', '0'):
4981 format = GST_VIDEO_FORMAT_I420;
4983 case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
4984 format = GST_VIDEO_FORMAT_YUY2;
4986 case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
4987 format = GST_VIDEO_FORMAT_YV12;
4989 case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
4990 format = GST_VIDEO_FORMAT_UYVY;
4992 case GST_MAKE_FOURCC ('A', 'Y', 'U', 'V'):
4993 format = GST_VIDEO_FORMAT_AYUV;
4995 case GST_MAKE_FOURCC ('Y', '8', '0', '0'):
4996 case GST_MAKE_FOURCC ('Y', '8', ' ', ' '):
4997 format = GST_VIDEO_FORMAT_GRAY8;
4999 case GST_MAKE_FOURCC ('R', 'G', 'B', 24):
5000 format = GST_VIDEO_FORMAT_RGB;
5002 case GST_MAKE_FOURCC ('B', 'G', 'R', 24):
5003 format = GST_VIDEO_FORMAT_BGR;
5006 GST_DEBUG ("Unknown fourcc %" GST_FOURCC_FORMAT,
5007 GST_FOURCC_ARGS (videocontext->fourcc));
5011 context->intra_only = TRUE;
5013 gst_video_info_set_format (&info, format, videocontext->pixel_width,
5014 videocontext->pixel_height);
5015 caps = gst_video_info_to_caps (&info);
5016 *codec_name = gst_pb_utils_get_codec_description (caps);
5017 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_SP)) {
5018 caps = gst_caps_new_simple ("video/x-divx",
5019 "divxversion", G_TYPE_INT, 4, NULL);
5020 *codec_name = g_strdup ("MPEG-4 simple profile");
5021 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP) ||
5022 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AP)) {
5023 caps = gst_caps_new_simple ("video/mpeg",
5024 "mpegversion", G_TYPE_INT, 4,
5025 "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
5029 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
5030 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5031 gst_buffer_unref (priv);
5033 gst_codec_utils_mpeg4video_caps_set_level_and_profile (caps, data, size);
5035 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP))
5036 *codec_name = g_strdup ("MPEG-4 advanced simple profile");
5038 *codec_name = g_strdup ("MPEG-4 advanced profile");
5039 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MSMPEG4V3)) {
5041 caps = gst_caps_new_full (gst_structure_new ("video/x-divx",
5042 "divxversion", G_TYPE_INT, 3, NULL),
5043 gst_structure_new ("video/x-msmpeg",
5044 "msmpegversion", G_TYPE_INT, 43, NULL), NULL);
5046 caps = gst_caps_new_simple ("video/x-msmpeg",
5047 "msmpegversion", G_TYPE_INT, 43, NULL);
5048 *codec_name = g_strdup ("Microsoft MPEG-4 v.3");
5049 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1) ||
5050 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG2)) {
5053 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1))
5058 caps = gst_caps_new_simple ("video/mpeg",
5059 "systemstream", G_TYPE_BOOLEAN, FALSE,
5060 "mpegversion", G_TYPE_INT, mpegversion, NULL);
5061 *codec_name = g_strdup_printf ("MPEG-%d video", mpegversion);
5062 context->postprocess_frame = gst_matroska_demux_add_mpeg_seq_header;
5063 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MJPEG)) {
5064 caps = gst_caps_new_empty_simple ("image/jpeg");
5065 *codec_name = g_strdup ("Motion-JPEG");
5066 context->intra_only = TRUE;
5067 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AVC)) {
5068 caps = gst_caps_new_empty_simple ("video/x-h264");
5072 /* First byte is the version, second is the profile indication, and third
5073 * is the 5 contraint_set_flags and 3 reserved bits. Fourth byte is the
5074 * level indication. */
5075 gst_codec_utils_h264_caps_set_level_and_profile (caps, data + 1,
5078 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
5079 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5080 gst_buffer_unref (priv);
5082 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "avc",
5083 "alignment", G_TYPE_STRING, "au", NULL);
5085 GST_WARNING ("No codec data found, assuming output is byte-stream");
5086 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
5089 *codec_name = g_strdup ("H264");
5090 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEGH_HEVC)) {
5091 caps = gst_caps_new_empty_simple ("video/x-h265");
5095 gst_codec_utils_h265_caps_set_level_tier_and_profile (caps, data + 1,
5098 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
5099 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5100 gst_buffer_unref (priv);
5102 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "hvc1",
5103 "alignment", G_TYPE_STRING, "au", NULL);
5105 GST_WARNING ("No codec data found, assuming output is byte-stream");
5106 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
5109 *codec_name = g_strdup ("HEVC");
5110 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1)) ||
5111 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2)) ||
5112 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3)) ||
5113 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))) {
5114 gint rmversion = -1;
5116 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1))
5118 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2))
5120 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3))
5122 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))
5125 caps = gst_caps_new_simple ("video/x-pn-realvideo",
5126 "rmversion", G_TYPE_INT, rmversion, NULL);
5127 GST_DEBUG ("data:%p, size:0x%x", data, size);
5128 /* We need to extract the extradata ! */
5129 if (data && (size >= 0x22)) {
5134 subformat = GST_READ_UINT32_BE (data + 0x1a);
5135 rformat = GST_READ_UINT32_BE (data + 0x1e);
5138 gst_buffer_new_wrapped (g_memdup (data + 0x1a, size - 0x1a),
5140 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, "format",
5141 G_TYPE_INT, rformat, "subformat", G_TYPE_INT, subformat, NULL);
5142 gst_buffer_unref (priv);
5145 *codec_name = g_strdup_printf ("RealVideo %d.0", rmversion);
5146 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_THEORA)) {
5147 caps = gst_caps_new_empty_simple ("video/x-theora");
5148 context->stream_headers =
5149 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
5150 context->codec_priv_size);
5151 /* FIXME: mark stream as broken and skip if there are no stream headers */
5152 context->send_stream_headers = TRUE;
5153 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_DIRAC)) {
5154 caps = gst_caps_new_empty_simple ("video/x-dirac");
5155 *codec_name = g_strdup_printf ("Dirac");
5156 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8)) {
5157 caps = gst_caps_new_empty_simple ("video/x-vp8");
5158 *codec_name = g_strdup_printf ("On2 VP8");
5159 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP9)) {
5160 caps = gst_caps_new_empty_simple ("video/x-vp9");
5161 *codec_name = g_strdup_printf ("On2 VP9");
5163 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
5169 GstStructure *structure;
5171 for (i = 0; i < gst_caps_get_size (caps); i++) {
5172 structure = gst_caps_get_structure (caps, i);
5174 /* FIXME: use the real unit here! */
5175 GST_DEBUG ("video size %dx%d, target display size %dx%d (any unit)",
5176 videocontext->pixel_width,
5177 videocontext->pixel_height,
5178 videocontext->display_width, videocontext->display_height);
5180 /* pixel width and height are the w and h of the video in pixels */
5181 if (videocontext->pixel_width > 0 && videocontext->pixel_height > 0) {
5182 gint w = videocontext->pixel_width;
5183 gint h = videocontext->pixel_height;
5185 gst_structure_set (structure,
5186 "width", G_TYPE_INT, w, "height", G_TYPE_INT, h, NULL);
5189 if (videocontext->display_width > 0 || videocontext->display_height > 0) {
5192 if (videocontext->display_width <= 0)
5193 videocontext->display_width = videocontext->pixel_width;
5194 if (videocontext->display_height <= 0)
5195 videocontext->display_height = videocontext->pixel_height;
5197 /* calculate the pixel aspect ratio using the display and pixel w/h */
5198 n = videocontext->display_width * videocontext->pixel_height;
5199 d = videocontext->display_height * videocontext->pixel_width;
5200 GST_DEBUG ("setting PAR to %d/%d", n, d);
5201 gst_structure_set (structure, "pixel-aspect-ratio",
5203 videocontext->display_width * videocontext->pixel_height,
5204 videocontext->display_height * videocontext->pixel_width, NULL);
5207 if (videocontext->default_fps > 0.0) {
5210 gst_util_double_to_fraction (videocontext->default_fps, &fps_n, &fps_d);
5212 GST_DEBUG ("using default fps %d/%d", fps_n, fps_d);
5214 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION, fps_n,
5216 } else if (context->default_duration > 0) {
5219 gst_video_guess_framerate (context->default_duration, &fps_n, &fps_d);
5221 GST_INFO ("using default duration %" G_GUINT64_FORMAT
5222 " framerate %d/%d", context->default_duration, fps_n, fps_d);
5224 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
5225 fps_n, fps_d, NULL);
5227 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
5231 if (videocontext->parent.flags & GST_MATROSKA_VIDEOTRACK_INTERLACED)
5232 gst_structure_set (structure, "interlace-mode", G_TYPE_STRING,
5235 if (videocontext->multiview_mode != GST_VIDEO_MULTIVIEW_MODE_NONE) {
5236 if (gst_video_multiview_guess_half_aspect (videocontext->multiview_mode,
5237 videocontext->pixel_width, videocontext->pixel_height,
5238 videocontext->display_width * videocontext->pixel_height,
5239 videocontext->display_height * videocontext->pixel_width)) {
5240 videocontext->multiview_flags |= GST_VIDEO_MULTIVIEW_FLAGS_HALF_ASPECT;
5242 gst_caps_set_simple (caps,
5243 "multiview-mode", G_TYPE_STRING,
5244 gst_video_multiview_mode_to_caps_string
5245 (videocontext->multiview_mode), "multiview-flags",
5246 GST_TYPE_VIDEO_MULTIVIEW_FLAGSET, videocontext->multiview_flags,
5247 GST_FLAG_SET_MASK_EXACT, NULL);
5250 caps = gst_caps_simplify (caps);
5257 * Some AAC specific code... *sigh*
5258 * FIXME: maybe we should use '15' and code the sample rate explicitly
5259 * if the sample rate doesn't match the predefined rates exactly? (tpm)
5263 aac_rate_idx (gint rate)
5267 else if (75132 <= rate)
5269 else if (55426 <= rate)
5271 else if (46009 <= rate)
5273 else if (37566 <= rate)
5275 else if (27713 <= rate)
5277 else if (23004 <= rate)
5279 else if (18783 <= rate)
5281 else if (13856 <= rate)
5283 else if (11502 <= rate)
5285 else if (9391 <= rate)
5292 aac_profile_idx (const gchar * codec_id)
5296 if (strlen (codec_id) <= 12)
5298 else if (!strncmp (&codec_id[12], "MAIN", 4))
5300 else if (!strncmp (&codec_id[12], "LC", 2))
5302 else if (!strncmp (&codec_id[12], "SSR", 3))
5311 round_up_pow2 (guint n)
5322 #define AAC_SYNC_EXTENSION_TYPE 0x02b7
5325 gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext *
5326 audiocontext, const gchar * codec_id, guint8 * data, guint size,
5327 gchar ** codec_name, guint16 * riff_audio_fmt)
5329 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) audiocontext;
5330 GstCaps *caps = NULL;
5332 g_assert (audiocontext != NULL);
5333 g_assert (codec_name != NULL);
5336 *riff_audio_fmt = 0;
5338 /* TODO: check if we have all codec types from matroska-ids.h
5339 * check if we have to do more special things with codec_private
5340 * check if we need bitdepth in different places too
5341 * implement channel position magic
5343 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID9
5344 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID10
5345 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDMC
5346 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDM2
5349 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1) ||
5350 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2) ||
5351 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L3)) {
5354 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1))
5356 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2))
5361 caps = gst_caps_new_simple ("audio/mpeg",
5362 "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, layer, NULL);
5363 *codec_name = g_strdup_printf ("MPEG-1 layer %d", layer);
5364 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE) ||
5365 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_LE)) {
5368 GstAudioFormat format;
5370 sign = (audiocontext->bitdepth != 8);
5371 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE))
5372 endianness = G_BIG_ENDIAN;
5374 endianness = G_LITTLE_ENDIAN;
5376 format = gst_audio_format_build_integer (sign, endianness,
5377 audiocontext->bitdepth, audiocontext->bitdepth);
5379 /* FIXME: Channel mask and reordering */
5380 caps = gst_caps_new_simple ("audio/x-raw",
5381 "format", G_TYPE_STRING, gst_audio_format_to_string (format),
5382 "layout", G_TYPE_STRING, "interleaved", NULL);
5384 *codec_name = g_strdup_printf ("Raw %d-bit PCM audio",
5385 audiocontext->bitdepth);
5386 context->alignment = GST_ROUND_UP_8 (audiocontext->bitdepth) / 8;
5387 context->alignment = round_up_pow2 (context->alignment);
5388 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_FLOAT)) {
5389 const gchar *format;
5390 if (audiocontext->bitdepth == 32)
5394 /* FIXME: Channel mask and reordering */
5395 caps = gst_caps_new_simple ("audio/x-raw",
5396 "format", G_TYPE_STRING, format,
5397 "layout", G_TYPE_STRING, "interleaved", NULL);
5398 *codec_name = g_strdup_printf ("Raw %d-bit floating-point audio",
5399 audiocontext->bitdepth);
5400 context->alignment = audiocontext->bitdepth / 8;
5401 context->alignment = round_up_pow2 (context->alignment);
5402 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AC3,
5403 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AC3))) {
5404 caps = gst_caps_new_simple ("audio/x-ac3",
5405 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5406 *codec_name = g_strdup ("AC-3 audio");
5407 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_EAC3,
5408 strlen (GST_MATROSKA_CODEC_ID_AUDIO_EAC3))) {
5409 caps = gst_caps_new_simple ("audio/x-eac3",
5410 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5411 *codec_name = g_strdup ("E-AC-3 audio");
5412 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TRUEHD,
5413 strlen (GST_MATROSKA_CODEC_ID_AUDIO_TRUEHD))) {
5414 caps = gst_caps_new_empty_simple ("audio/x-true-hd");
5415 *codec_name = g_strdup ("Dolby TrueHD");
5416 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_DTS)) {
5417 caps = gst_caps_new_empty_simple ("audio/x-dts");
5418 *codec_name = g_strdup ("DTS audio");
5419 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_VORBIS)) {
5420 caps = gst_caps_new_empty_simple ("audio/x-vorbis");
5421 context->stream_headers =
5422 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
5423 context->codec_priv_size);
5424 /* FIXME: mark stream as broken and skip if there are no stream headers */
5425 context->send_stream_headers = TRUE;
5426 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_FLAC)) {
5427 caps = gst_caps_new_empty_simple ("audio/x-flac");
5428 context->stream_headers =
5429 gst_matroska_parse_flac_stream_headers (context->codec_priv,
5430 context->codec_priv_size);
5431 /* FIXME: mark stream as broken and skip if there are no stream headers */
5432 context->send_stream_headers = TRUE;
5433 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_SPEEX)) {
5434 caps = gst_caps_new_empty_simple ("audio/x-speex");
5435 context->stream_headers =
5436 gst_matroska_parse_speex_stream_headers (context->codec_priv,
5437 context->codec_priv_size);
5438 /* FIXME: mark stream as broken and skip if there are no stream headers */
5439 context->send_stream_headers = TRUE;
5440 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_OPUS)) {
5441 caps = gst_caps_new_empty_simple ("audio/x-opus");
5442 *codec_name = g_strdup ("Opus");
5443 context->stream_headers =
5444 gst_matroska_parse_opus_stream_headers (context->codec_priv,
5445 context->codec_priv_size);
5446 if (context->stream_headers) {
5447 /* There was a valid header. Multistream headers are more than
5448 * 19 bytes, as they include an extra channel mapping table. */
5449 gboolean multistream = (context->codec_priv_size > 19);
5450 gst_caps_set_simple (caps, "multistream", G_TYPE_BOOLEAN, multistream,
5453 /* FIXME: mark stream as broken and skip if there are no stream headers */
5454 context->send_stream_headers = TRUE;
5455 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_ACM)) {
5456 gst_riff_strf_auds auds;
5458 if (data && size >= 18) {
5459 GstBuffer *codec_data = NULL;
5461 /* little-endian -> byte-order */
5462 auds.format = GST_READ_UINT16_LE (data);
5463 auds.channels = GST_READ_UINT16_LE (data + 2);
5464 auds.rate = GST_READ_UINT32_LE (data + 4);
5465 auds.av_bps = GST_READ_UINT32_LE (data + 8);
5466 auds.blockalign = GST_READ_UINT16_LE (data + 12);
5467 auds.bits_per_sample = GST_READ_UINT16_LE (data + 16);
5469 /* 18 is the waveformatex size */
5471 codec_data = gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY,
5472 data + 18, size - 18, 0, size - 18, NULL, NULL);
5476 *riff_audio_fmt = auds.format;
5478 /* FIXME: Handle reorder map */
5479 caps = gst_riff_create_audio_caps (auds.format, NULL, &auds, NULL,
5480 codec_data, codec_name, NULL);
5482 gst_buffer_unref (codec_data);
5485 GST_WARNING ("Unhandled RIFF audio format 0x%02x", auds.format);
5488 GST_WARNING ("Invalid codec data size (%d expected, got %d)", 18, size);
5490 } else if (g_str_has_prefix (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC)) {
5491 GstBuffer *priv = NULL;
5493 gint rate_idx, profile;
5494 guint8 *data = NULL;
5496 /* unspecified AAC profile with opaque private codec data */
5497 if (strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC) == 0) {
5498 if (context->codec_priv_size >= 2) {
5499 guint obj_type, freq_index, explicit_freq_bytes = 0;
5501 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
5503 freq_index = (GST_READ_UINT16_BE (context->codec_priv) & 0x780) >> 7;
5504 obj_type = (GST_READ_UINT16_BE (context->codec_priv) & 0xF800) >> 11;
5505 if (freq_index == 15)
5506 explicit_freq_bytes = 3;
5507 GST_DEBUG ("obj_type = %u, freq_index = %u", obj_type, freq_index);
5508 priv = gst_buffer_new_wrapped (g_memdup (context->codec_priv,
5509 context->codec_priv_size), context->codec_priv_size);
5510 /* assume SBR if samplerate <= 24kHz */
5511 if (obj_type == 5 || (freq_index >= 6 && freq_index != 15) ||
5512 (context->codec_priv_size == (5 + explicit_freq_bytes))) {
5513 audiocontext->samplerate *= 2;
5516 GST_WARNING ("Opaque A_AAC codec ID, but no codec private data");
5517 /* this is pretty broken;
5518 * maybe we need to make up some default private,
5519 * or maybe ADTS data got dumped in.
5520 * Let's set up some private data now, and check actual data later */
5521 /* just try this and see what happens ... */
5522 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
5523 context->postprocess_frame = gst_matroska_demux_check_aac;
5527 /* make up decoder-specific data if it is not supplied */
5531 priv = gst_buffer_new_allocate (NULL, 5, NULL);
5532 gst_buffer_map (priv, &map, GST_MAP_WRITE);
5534 rate_idx = aac_rate_idx (audiocontext->samplerate);
5535 profile = aac_profile_idx (codec_id);
5537 data[0] = ((profile + 1) << 3) | ((rate_idx & 0xE) >> 1);
5538 data[1] = ((rate_idx & 0x1) << 7) | (audiocontext->channels << 3);
5540 if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2,
5541 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2))) {
5543 gst_buffer_unmap (priv, &map);
5544 gst_buffer_set_size (priv, 2);
5545 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4,
5546 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4))) {
5549 if (g_strrstr (codec_id, "SBR")) {
5550 /* HE-AAC (aka SBR AAC) */
5551 audiocontext->samplerate *= 2;
5552 rate_idx = aac_rate_idx (audiocontext->samplerate);
5553 data[2] = AAC_SYNC_EXTENSION_TYPE >> 3;
5554 data[3] = ((AAC_SYNC_EXTENSION_TYPE & 0x07) << 5) | 5;
5555 data[4] = (1 << 7) | (rate_idx << 3);
5556 gst_buffer_unmap (priv, &map);
5558 gst_buffer_unmap (priv, &map);
5559 gst_buffer_set_size (priv, 2);
5562 gst_buffer_unmap (priv, &map);
5563 gst_buffer_unref (priv);
5565 GST_ERROR ("Unknown AAC profile and no codec private data");
5570 caps = gst_caps_new_simple ("audio/mpeg",
5571 "mpegversion", G_TYPE_INT, mpegversion,
5572 "framed", G_TYPE_BOOLEAN, TRUE,
5573 "stream-format", G_TYPE_STRING, "raw", NULL);
5574 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5575 if (context->codec_priv && context->codec_priv_size > 0)
5576 gst_codec_utils_aac_caps_set_level_and_profile (caps,
5577 context->codec_priv, context->codec_priv_size);
5578 *codec_name = g_strdup_printf ("MPEG-%d AAC audio", mpegversion);
5579 gst_buffer_unref (priv);
5581 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TTA)) {
5582 caps = gst_caps_new_simple ("audio/x-tta",
5583 "width", G_TYPE_INT, audiocontext->bitdepth, NULL);
5584 *codec_name = g_strdup ("TTA audio");
5585 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_WAVPACK4)) {
5586 caps = gst_caps_new_simple ("audio/x-wavpack",
5587 "width", G_TYPE_INT, audiocontext->bitdepth,
5588 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5589 *codec_name = g_strdup ("Wavpack audio");
5590 context->postprocess_frame = gst_matroska_demux_add_wvpk_header;
5591 audiocontext->wvpk_block_index = 0;
5592 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4)) ||
5593 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_28_8)) ||
5594 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))) {
5595 gint raversion = -1;
5597 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4))
5599 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))
5604 caps = gst_caps_new_simple ("audio/x-pn-realaudio",
5605 "raversion", G_TYPE_INT, raversion, NULL);
5606 /* Extract extra information from caps, mapping varies based on codec */
5607 if (data && (size >= 0x50)) {
5614 guint extra_data_size;
5616 GST_ERROR ("real audio raversion:%d", raversion);
5617 if (raversion == 8) {
5619 flavor = GST_READ_UINT16_BE (data + 22);
5620 packet_size = GST_READ_UINT32_BE (data + 24);
5621 height = GST_READ_UINT16_BE (data + 40);
5622 leaf_size = GST_READ_UINT16_BE (data + 44);
5623 sample_width = GST_READ_UINT16_BE (data + 58);
5624 extra_data_size = GST_READ_UINT32_BE (data + 74);
5627 ("flavor:%d, packet_size:%d, height:%d, leaf_size:%d, sample_width:%d, extra_data_size:%d",
5628 flavor, packet_size, height, leaf_size, sample_width,
5630 gst_caps_set_simple (caps, "flavor", G_TYPE_INT, flavor, "packet_size",
5631 G_TYPE_INT, packet_size, "height", G_TYPE_INT, height, "leaf_size",
5632 G_TYPE_INT, leaf_size, "width", G_TYPE_INT, sample_width, NULL);
5634 if ((size - 78) >= extra_data_size) {
5635 priv = gst_buffer_new_wrapped (g_memdup (data + 78, extra_data_size),
5637 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5638 gst_buffer_unref (priv);
5643 *codec_name = g_strdup_printf ("RealAudio %d.0", raversion);
5644 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_SIPR)) {
5645 caps = gst_caps_new_empty_simple ("audio/x-sipro");
5646 *codec_name = g_strdup ("Sipro/ACELP.NET Voice Codec");
5647 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_RALF)) {
5648 caps = gst_caps_new_empty_simple ("audio/x-ralf-mpeg4-generic");
5649 *codec_name = g_strdup ("Real Audio Lossless");
5650 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_ATRC)) {
5651 caps = gst_caps_new_empty_simple ("audio/x-vnd.sony.atrac3");
5652 *codec_name = g_strdup ("Sony ATRAC3");
5654 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
5659 if (audiocontext->samplerate > 0 && audiocontext->channels > 0) {
5662 for (i = 0; i < gst_caps_get_size (caps); i++) {
5663 gst_structure_set (gst_caps_get_structure (caps, i),
5664 "channels", G_TYPE_INT, audiocontext->channels,
5665 "rate", G_TYPE_INT, audiocontext->samplerate, NULL);
5669 caps = gst_caps_simplify (caps);
5676 gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
5677 subtitlecontext, const gchar * codec_id, gpointer data, guint size)
5679 GstCaps *caps = NULL;
5680 GstMatroskaTrackContext *context =
5681 (GstMatroskaTrackContext *) subtitlecontext;
5683 /* for backwards compatibility */
5684 if (!g_ascii_strcasecmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASCII))
5685 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8;
5686 else if (!g_ascii_strcasecmp (codec_id, "S_SSA"))
5687 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_SSA;
5688 else if (!g_ascii_strcasecmp (codec_id, "S_ASS"))
5689 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_ASS;
5690 else if (!g_ascii_strcasecmp (codec_id, "S_USF"))
5691 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_USF;
5693 /* TODO: Add GST_MATROSKA_CODEC_ID_SUBTITLE_BMP support
5694 * Check if we have to do something with codec_private */
5695 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8)) {
5696 /* well, plain text simply does not have a lot of markup ... */
5697 caps = gst_caps_new_simple ("text/x-raw", "format", G_TYPE_STRING,
5698 "pango-markup", NULL);
5699 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5700 subtitlecontext->check_markup = TRUE;
5701 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_SSA)) {
5702 caps = gst_caps_new_empty_simple ("application/x-ssa");
5703 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5704 subtitlecontext->check_markup = FALSE;
5705 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASS)) {
5706 caps = gst_caps_new_empty_simple ("application/x-ass");
5707 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5708 subtitlecontext->check_markup = FALSE;
5709 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_USF)) {
5710 caps = gst_caps_new_empty_simple ("application/x-usf");
5711 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5712 subtitlecontext->check_markup = FALSE;
5713 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB)) {
5714 caps = gst_caps_new_empty_simple ("subpicture/x-dvd");
5715 ((GstMatroskaTrackContext *) subtitlecontext)->send_dvd_event = TRUE;
5716 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_HDMVPGS)) {
5717 caps = gst_caps_new_empty_simple ("subpicture/x-pgs");
5718 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_KATE)) {
5719 caps = gst_caps_new_empty_simple ("subtitle/x-kate");
5720 context->stream_headers =
5721 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
5722 context->codec_priv_size);
5723 /* FIXME: mark stream as broken and skip if there are no stream headers */
5724 context->send_stream_headers = TRUE;
5726 GST_DEBUG ("Unknown subtitle stream: codec_id='%s'", codec_id);
5727 caps = gst_caps_new_empty_simple ("application/x-subtitle-unknown");
5730 if (data != NULL && size > 0) {
5733 buf = gst_buffer_new_wrapped (g_memdup (data, size), size);
5734 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, buf, NULL);
5735 gst_buffer_unref (buf);
5743 gst_matroska_demux_set_index (GstElement * element, GstIndex * index)
5745 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5747 GST_OBJECT_LOCK (demux);
5748 if (demux->common.element_index)
5749 gst_object_unref (demux->common.element_index);
5750 demux->common.element_index = index ? gst_object_ref (index) : NULL;
5751 GST_OBJECT_UNLOCK (demux);
5752 GST_DEBUG_OBJECT (demux, "Set index %" GST_PTR_FORMAT,
5753 demux->common.element_index);
5757 gst_matroska_demux_get_index (GstElement * element)
5759 GstIndex *result = NULL;
5760 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5762 GST_OBJECT_LOCK (demux);
5763 if (demux->common.element_index)
5764 result = gst_object_ref (demux->common.element_index);
5765 GST_OBJECT_UNLOCK (demux);
5767 GST_DEBUG_OBJECT (demux, "Returning index %" GST_PTR_FORMAT, result);
5773 static GstStateChangeReturn
5774 gst_matroska_demux_change_state (GstElement * element,
5775 GstStateChange transition)
5777 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5778 GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
5780 /* handle upwards state changes here */
5781 switch (transition) {
5786 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
5788 /* handle downwards state changes */
5789 switch (transition) {
5790 case GST_STATE_CHANGE_PAUSED_TO_READY:
5791 gst_matroska_demux_reset (GST_ELEMENT (demux));
5801 gst_matroska_demux_set_property (GObject * object,
5802 guint prop_id, const GValue * value, GParamSpec * pspec)
5804 GstMatroskaDemux *demux;
5806 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
5807 demux = GST_MATROSKA_DEMUX (object);
5810 case PROP_MAX_GAP_TIME:
5811 GST_OBJECT_LOCK (demux);
5812 demux->max_gap_time = g_value_get_uint64 (value);
5813 GST_OBJECT_UNLOCK (demux);
5816 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
5822 gst_matroska_demux_get_property (GObject * object,
5823 guint prop_id, GValue * value, GParamSpec * pspec)
5825 GstMatroskaDemux *demux;
5827 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
5828 demux = GST_MATROSKA_DEMUX (object);
5831 case PROP_MAX_GAP_TIME:
5832 GST_OBJECT_LOCK (demux);
5833 g_value_set_uint64 (value, demux->max_gap_time);
5834 GST_OBJECT_UNLOCK (demux);
5837 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
5843 gst_matroska_demux_plugin_init (GstPlugin * plugin)
5847 /* parser helper separate debug */
5848 GST_DEBUG_CATEGORY_INIT (ebmlread_debug, "ebmlread",
5849 0, "EBML stream helper class");
5851 /* create an elementfactory for the matroska_demux element */
5852 if (!gst_element_register (plugin, "matroskademux",
5853 GST_RANK_PRIMARY, GST_TYPE_MATROSKA_DEMUX))