1 /* GStreamer Matroska muxer/demuxer
2 * (c) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
3 * (c) 2006 Tim-Philipp Müller <tim centricular net>
4 * (c) 2008 Sebastian Dröge <slomo@circular-chaos.org>
5 * (c) 2011 Debarshi Ray <rishi@gnu.org>
7 * matroska-demux.c: matroska file/stream demuxer
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Library General Public License for more details.
19 * You should have received a copy of the GNU Library General Public
20 * License along with this library; if not, write to the
21 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
22 * Boston, MA 02110-1301, USA.
25 /* TODO: check CRC32 if present
26 * TODO: there can be a segment after the first segment. Handle like
27 * chained oggs. Fixes #334082
28 * TODO: Test samples: http://www.matroska.org/samples/matrix/index.html
29 * http://samples.mplayerhq.hu/Matroska/
30 * TODO: check if demuxing is done correct for all codecs according to spec
31 * TODO: seeking with incomplete or without CUE
35 * SECTION:element-matroskademux
37 * matroskademux demuxes a Matroska file into the different contained streams.
40 * <title>Example launch line</title>
42 * gst-launch-1.0 -v filesrc location=/path/to/mkv ! matroskademux ! vorbisdec ! audioconvert ! audioresample ! autoaudiosink
43 * ]| This pipeline demuxes a Matroska file and outputs the contained Vorbis audio.
54 #include <glib/gprintf.h>
56 /* For AVI compatibility mode
57 and for fourcc stuff */
58 #include <gst/riff/riff-read.h>
59 #include <gst/riff/riff-ids.h>
60 #include <gst/riff/riff-media.h>
62 #include <gst/audio/audio.h>
63 #include <gst/tag/tag.h>
64 #include <gst/pbutils/pbutils.h>
65 #include <gst/video/video.h>
67 #include "matroska-demux.h"
68 #include "matroska-ids.h"
70 GST_DEBUG_CATEGORY_STATIC (matroskademux_debug);
71 #define GST_CAT_DEFAULT matroskademux_debug
73 #define DEBUG_ELEMENT_START(demux, ebml, element) \
74 GST_DEBUG_OBJECT (demux, "Parsing " element " element at offset %" \
75 G_GUINT64_FORMAT, gst_ebml_read_get_pos (ebml))
77 #define DEBUG_ELEMENT_STOP(demux, ebml, element, ret) \
78 GST_DEBUG_OBJECT (demux, "Parsing " element " element " \
79 " finished with '%s'", gst_flow_get_name (ret))
89 #define DEFAULT_MAX_GAP_TIME (2 * GST_SECOND)
91 static GstStaticPadTemplate sink_templ = GST_STATIC_PAD_TEMPLATE ("sink",
94 GST_STATIC_CAPS ("audio/x-matroska; video/x-matroska; "
95 "video/x-matroska-3d; audio/webm; video/webm")
98 /* TODO: fill in caps! */
100 static GstStaticPadTemplate audio_src_templ =
101 GST_STATIC_PAD_TEMPLATE ("audio_%u",
104 GST_STATIC_CAPS ("ANY")
107 static GstStaticPadTemplate video_src_templ =
108 GST_STATIC_PAD_TEMPLATE ("video_%u",
111 GST_STATIC_CAPS ("ANY")
114 static GstStaticPadTemplate subtitle_src_templ =
115 GST_STATIC_PAD_TEMPLATE ("subtitle_%u",
118 GST_STATIC_CAPS ("text/x-raw, format=pango-markup; application/x-ssa; "
119 "application/x-ass;application/x-usf; subpicture/x-dvd; "
120 "subpicture/x-pgs; subtitle/x-kate; " "application/x-subtitle-unknown")
123 static GstFlowReturn gst_matroska_demux_parse_id (GstMatroskaDemux * demux,
124 guint32 id, guint64 length, guint needed);
126 /* element functions */
127 static void gst_matroska_demux_loop (GstPad * pad);
129 static gboolean gst_matroska_demux_element_send_event (GstElement * element,
131 static gboolean gst_matroska_demux_element_query (GstElement * element,
135 static gboolean gst_matroska_demux_sink_activate (GstPad * sinkpad,
137 static gboolean gst_matroska_demux_sink_activate_mode (GstPad * sinkpad,
138 GstObject * parent, GstPadMode mode, gboolean active);
140 static gboolean gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
141 GstPad * pad, GstEvent * event);
142 static gboolean gst_matroska_demux_handle_src_event (GstPad * pad,
143 GstObject * parent, GstEvent * event);
144 static gboolean gst_matroska_demux_handle_src_query (GstPad * pad,
145 GstObject * parent, GstQuery * query);
147 static gboolean gst_matroska_demux_handle_sink_event (GstPad * pad,
148 GstObject * parent, GstEvent * event);
149 static GstFlowReturn gst_matroska_demux_chain (GstPad * pad,
150 GstObject * object, GstBuffer * buffer);
152 static GstStateChangeReturn
153 gst_matroska_demux_change_state (GstElement * element,
154 GstStateChange transition);
157 gst_matroska_demux_set_index (GstElement * element, GstIndex * index);
158 static GstIndex *gst_matroska_demux_get_index (GstElement * element);
162 static GstCaps *gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext
163 * videocontext, const gchar * codec_id, guint8 * data, guint size,
164 gchar ** codec_name, guint32 * riff_fourcc);
165 static GstCaps *gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext
166 * audiocontext, const gchar * codec_id, guint8 * data, guint size,
167 gchar ** codec_name, guint16 * riff_audio_fmt);
169 * gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
170 subtitlecontext, const gchar * codec_id, gpointer data, guint size);
173 static void gst_matroska_demux_reset (GstElement * element);
174 static gboolean perform_seek_to_offset (GstMatroskaDemux * demux,
175 gdouble rate, guint64 offset, guint32 seqnum);
177 /* gobject functions */
178 static void gst_matroska_demux_set_property (GObject * object,
179 guint prop_id, const GValue * value, GParamSpec * pspec);
180 static void gst_matroska_demux_get_property (GObject * object,
181 guint prop_id, GValue * value, GParamSpec * pspec);
183 GType gst_matroska_demux_get_type (void);
184 #define parent_class gst_matroska_demux_parent_class
185 G_DEFINE_TYPE (GstMatroskaDemux, gst_matroska_demux, GST_TYPE_ELEMENT);
188 gst_matroska_demux_finalize (GObject * object)
190 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (object);
192 gst_matroska_read_common_finalize (&demux->common);
193 gst_flow_combiner_free (demux->flowcombiner);
194 G_OBJECT_CLASS (parent_class)->finalize (object);
198 gst_matroska_demux_class_init (GstMatroskaDemuxClass * klass)
200 GObjectClass *gobject_class = (GObjectClass *) klass;
201 GstElementClass *gstelement_class = (GstElementClass *) klass;
203 GST_DEBUG_CATEGORY_INIT (matroskademux_debug, "matroskademux", 0,
206 gobject_class->finalize = gst_matroska_demux_finalize;
208 gobject_class->get_property = gst_matroska_demux_get_property;
209 gobject_class->set_property = gst_matroska_demux_set_property;
211 g_object_class_install_property (gobject_class, PROP_MAX_GAP_TIME,
212 g_param_spec_uint64 ("max-gap-time", "Maximum gap time",
213 "The demuxer sends out segment events for skipping "
214 "gaps longer than this (0 = disabled).", 0, G_MAXUINT64,
215 DEFAULT_MAX_GAP_TIME, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
217 gstelement_class->change_state =
218 GST_DEBUG_FUNCPTR (gst_matroska_demux_change_state);
219 gstelement_class->send_event =
220 GST_DEBUG_FUNCPTR (gst_matroska_demux_element_send_event);
221 gstelement_class->query =
222 GST_DEBUG_FUNCPTR (gst_matroska_demux_element_query);
224 gstelement_class->set_index =
225 GST_DEBUG_FUNCPTR (gst_matroska_demux_set_index);
226 gstelement_class->get_index =
227 GST_DEBUG_FUNCPTR (gst_matroska_demux_get_index);
230 gst_element_class_add_pad_template (gstelement_class,
231 gst_static_pad_template_get (&video_src_templ));
232 gst_element_class_add_pad_template (gstelement_class,
233 gst_static_pad_template_get (&audio_src_templ));
234 gst_element_class_add_pad_template (gstelement_class,
235 gst_static_pad_template_get (&subtitle_src_templ));
236 gst_element_class_add_pad_template (gstelement_class,
237 gst_static_pad_template_get (&sink_templ));
239 gst_element_class_set_static_metadata (gstelement_class, "Matroska demuxer",
241 "Demuxes Matroska/WebM streams into video/audio/subtitles",
242 "GStreamer maintainers <gstreamer-devel@lists.sourceforge.net>");
246 gst_matroska_demux_init (GstMatroskaDemux * demux)
248 demux->common.sinkpad = gst_pad_new_from_static_template (&sink_templ,
250 gst_pad_set_activate_function (demux->common.sinkpad,
251 GST_DEBUG_FUNCPTR (gst_matroska_demux_sink_activate));
252 gst_pad_set_activatemode_function (demux->common.sinkpad,
253 GST_DEBUG_FUNCPTR (gst_matroska_demux_sink_activate_mode));
254 gst_pad_set_chain_function (demux->common.sinkpad,
255 GST_DEBUG_FUNCPTR (gst_matroska_demux_chain));
256 gst_pad_set_event_function (demux->common.sinkpad,
257 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_sink_event));
258 gst_element_add_pad (GST_ELEMENT (demux), demux->common.sinkpad);
260 /* init defaults for common read context */
261 gst_matroska_read_common_init (&demux->common);
263 /* property defaults */
264 demux->max_gap_time = DEFAULT_MAX_GAP_TIME;
266 GST_OBJECT_FLAG_SET (demux, GST_ELEMENT_FLAG_INDEXABLE);
268 demux->flowcombiner = gst_flow_combiner_new ();
271 gst_matroska_demux_reset (GST_ELEMENT (demux));
275 gst_matroska_demux_reset (GstElement * element)
277 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
279 GST_DEBUG_OBJECT (demux, "Resetting state");
281 gst_matroska_read_common_reset (GST_ELEMENT (demux), &demux->common);
283 demux->num_a_streams = 0;
284 demux->num_t_streams = 0;
285 demux->num_v_streams = 0;
287 demux->have_group_id = FALSE;
288 demux->group_id = G_MAXUINT;
291 demux->tracks_parsed = FALSE;
293 if (demux->clusters) {
294 g_array_free (demux->clusters, TRUE);
295 demux->clusters = NULL;
298 g_list_foreach (demux->seek_parsed,
299 (GFunc) gst_matroska_read_common_free_parsed_el, NULL);
300 g_list_free (demux->seek_parsed);
301 demux->seek_parsed = NULL;
303 demux->last_stop_end = GST_CLOCK_TIME_NONE;
304 demux->seek_block = 0;
305 demux->stream_start_time = GST_CLOCK_TIME_NONE;
306 demux->to_time = GST_CLOCK_TIME_NONE;
307 demux->cluster_time = GST_CLOCK_TIME_NONE;
308 demux->cluster_offset = 0;
309 demux->next_cluster_offset = 0;
310 demux->index_offset = 0;
311 demux->seekable = FALSE;
312 demux->need_segment = FALSE;
313 demux->segment_seqnum = 0;
314 demux->requested_seek_time = GST_CLOCK_TIME_NONE;
315 demux->seek_offset = -1;
316 demux->building_index = FALSE;
317 if (demux->seek_event) {
318 gst_event_unref (demux->seek_event);
319 demux->seek_event = NULL;
322 demux->seek_index = NULL;
323 demux->seek_entry = 0;
325 if (demux->new_segment) {
326 gst_event_unref (demux->new_segment);
327 demux->new_segment = NULL;
330 demux->invalid_duration = FALSE;
332 demux->cached_length = G_MAXUINT64;
334 gst_flow_combiner_clear (demux->flowcombiner);
338 gst_matroska_decode_buffer (GstMatroskaTrackContext * context, GstBuffer * buf)
344 g_return_val_if_fail (GST_IS_BUFFER (buf), NULL);
346 GST_DEBUG ("decoding buffer %p", buf);
348 gst_buffer_map (buf, &map, GST_MAP_READ);
352 g_return_val_if_fail (size > 0, buf);
354 if (gst_matroska_decode_data (context->encodings, &data, &size,
355 GST_MATROSKA_TRACK_ENCODING_SCOPE_FRAME, FALSE)) {
356 gst_buffer_unmap (buf, &map);
357 gst_buffer_unref (buf);
358 return gst_buffer_new_wrapped (data, size);
360 GST_DEBUG ("decode data failed");
361 gst_buffer_unmap (buf, &map);
362 gst_buffer_unref (buf);
368 gst_matroska_demux_add_stream_headers_to_caps (GstMatroskaDemux * demux,
369 GstBufferList * list, GstCaps * caps)
372 GValue arr_val = G_VALUE_INIT;
373 GValue buf_val = G_VALUE_INIT;
376 g_assert (gst_caps_is_writable (caps));
378 g_value_init (&arr_val, GST_TYPE_ARRAY);
379 g_value_init (&buf_val, GST_TYPE_BUFFER);
381 num = gst_buffer_list_length (list);
382 for (i = 0; i < num; ++i) {
383 g_value_set_boxed (&buf_val, gst_buffer_list_get (list, i));
384 gst_value_array_append_value (&arr_val, &buf_val);
387 s = gst_caps_get_structure (caps, 0);
388 gst_structure_take_value (s, "streamheader", &arr_val);
389 g_value_unset (&buf_val);
393 gst_matroska_demux_add_stream (GstMatroskaDemux * demux, GstEbmlRead * ebml)
395 GstElementClass *klass = GST_ELEMENT_GET_CLASS (demux);
396 GstMatroskaTrackContext *context;
397 GstPadTemplate *templ = NULL;
398 GstStreamFlags stream_flags;
399 GstCaps *caps = NULL;
400 gchar *padname = NULL;
402 guint32 id, riff_fourcc = 0;
403 guint16 riff_audio_fmt = 0;
404 GstEvent *stream_start;
408 DEBUG_ELEMENT_START (demux, ebml, "TrackEntry");
410 /* start with the master */
411 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
412 DEBUG_ELEMENT_STOP (demux, ebml, "TrackEntry", ret);
416 /* allocate generic... if we know the type, we'll g_renew()
417 * with the precise type */
418 context = g_new0 (GstMatroskaTrackContext, 1);
419 g_ptr_array_add (demux->common.src, context);
420 context->index = demux->common.num_streams;
421 context->index_writer_id = -1;
422 context->type = 0; /* no type yet */
423 context->default_duration = 0;
425 context->set_discont = TRUE;
426 context->timecodescale = 1.0;
428 GST_MATROSKA_TRACK_ENABLED | GST_MATROSKA_TRACK_DEFAULT |
429 GST_MATROSKA_TRACK_LACING;
430 context->from_time = GST_CLOCK_TIME_NONE;
431 context->from_offset = -1;
432 context->to_offset = G_MAXINT64;
433 context->alignment = 1;
434 context->dts_only = FALSE;
435 context->intra_only = FALSE;
436 context->tags = gst_tag_list_new_empty ();
437 demux->common.num_streams++;
438 g_assert (demux->common.src->len == demux->common.num_streams);
440 GST_DEBUG_OBJECT (demux, "Stream number %d", context->index);
442 /* try reading the trackentry headers */
443 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
444 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
448 /* track number (unique stream ID) */
449 case GST_MATROSKA_ID_TRACKNUMBER:{
452 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
456 GST_ERROR_OBJECT (demux, "Invalid TrackNumber 0");
457 ret = GST_FLOW_ERROR;
459 } else if (!gst_matroska_read_common_tracknumber_unique (&demux->common,
461 GST_ERROR_OBJECT (demux, "TrackNumber %" G_GUINT64_FORMAT
462 " is not unique", num);
463 ret = GST_FLOW_ERROR;
467 GST_DEBUG_OBJECT (demux, "TrackNumber: %" G_GUINT64_FORMAT, num);
471 /* track UID (unique identifier) */
472 case GST_MATROSKA_ID_TRACKUID:{
475 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
479 GST_ERROR_OBJECT (demux, "Invalid TrackUID 0");
480 ret = GST_FLOW_ERROR;
484 GST_DEBUG_OBJECT (demux, "TrackUID: %" G_GUINT64_FORMAT, num);
489 /* track type (video, audio, combined, subtitle, etc.) */
490 case GST_MATROSKA_ID_TRACKTYPE:{
493 if ((ret = gst_ebml_read_uint (ebml, &id, &track_type)) != GST_FLOW_OK) {
497 if (context->type != 0 && context->type != track_type) {
498 GST_WARNING_OBJECT (demux,
499 "More than one tracktype defined in a TrackEntry - skipping");
501 } else if (track_type < 1 || track_type > 254) {
502 GST_WARNING_OBJECT (demux, "Invalid TrackType %" G_GUINT64_FORMAT,
507 GST_DEBUG_OBJECT (demux, "TrackType: %" G_GUINT64_FORMAT, track_type);
509 /* ok, so we're actually going to reallocate this thing */
510 switch (track_type) {
511 case GST_MATROSKA_TRACK_TYPE_VIDEO:
512 gst_matroska_track_init_video_context (&context);
514 case GST_MATROSKA_TRACK_TYPE_AUDIO:
515 gst_matroska_track_init_audio_context (&context);
517 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
518 gst_matroska_track_init_subtitle_context (&context);
520 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
521 case GST_MATROSKA_TRACK_TYPE_LOGO:
522 case GST_MATROSKA_TRACK_TYPE_BUTTONS:
523 case GST_MATROSKA_TRACK_TYPE_CONTROL:
525 GST_WARNING_OBJECT (demux,
526 "Unknown or unsupported TrackType %" G_GUINT64_FORMAT,
531 g_ptr_array_index (demux->common.src, demux->common.num_streams - 1)
536 /* tracktype specific stuff for video */
537 case GST_MATROSKA_ID_TRACKVIDEO:{
538 GstMatroskaTrackVideoContext *videocontext;
540 DEBUG_ELEMENT_START (demux, ebml, "TrackVideo");
542 if (!gst_matroska_track_init_video_context (&context)) {
543 GST_WARNING_OBJECT (demux,
544 "TrackVideo element in non-video track - ignoring track");
545 ret = GST_FLOW_ERROR;
547 } else if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
550 videocontext = (GstMatroskaTrackVideoContext *) context;
551 g_ptr_array_index (demux->common.src, demux->common.num_streams - 1)
554 while (ret == GST_FLOW_OK &&
555 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
556 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
560 /* Should be one level up but some broken muxers write it here. */
561 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
564 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
568 GST_WARNING_OBJECT (demux, "Invalid TrackDefaultDuration 0");
572 GST_DEBUG_OBJECT (demux,
573 "TrackDefaultDuration: %" G_GUINT64_FORMAT, num);
574 context->default_duration = num;
578 /* video framerate */
579 /* NOTE: This one is here only for backward compatibility.
580 * Use _TRACKDEFAULDURATION one level up. */
581 case GST_MATROSKA_ID_VIDEOFRAMERATE:{
584 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
588 GST_WARNING_OBJECT (demux, "Invalid TrackVideoFPS %lf", num);
592 GST_DEBUG_OBJECT (demux, "TrackVideoFrameRate: %lf", num);
593 if (context->default_duration == 0)
594 context->default_duration =
595 gst_gdouble_to_guint64 ((gdouble) GST_SECOND * (1.0 / num));
596 videocontext->default_fps = num;
600 /* width of the size to display the video at */
601 case GST_MATROSKA_ID_VIDEODISPLAYWIDTH:{
604 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
608 GST_WARNING_OBJECT (demux, "Invalid TrackVideoDisplayWidth 0");
612 GST_DEBUG_OBJECT (demux,
613 "TrackVideoDisplayWidth: %" G_GUINT64_FORMAT, num);
614 videocontext->display_width = num;
618 /* height of the size to display the video at */
619 case GST_MATROSKA_ID_VIDEODISPLAYHEIGHT:{
622 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
626 GST_WARNING_OBJECT (demux, "Invalid TrackVideoDisplayHeight 0");
630 GST_DEBUG_OBJECT (demux,
631 "TrackVideoDisplayHeight: %" G_GUINT64_FORMAT, num);
632 videocontext->display_height = num;
636 /* width of the video in the file */
637 case GST_MATROSKA_ID_VIDEOPIXELWIDTH:{
640 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
644 GST_WARNING_OBJECT (demux, "Invalid TrackVideoPixelWidth 0");
648 GST_DEBUG_OBJECT (demux,
649 "TrackVideoPixelWidth: %" G_GUINT64_FORMAT, num);
650 videocontext->pixel_width = num;
654 /* height of the video in the file */
655 case GST_MATROSKA_ID_VIDEOPIXELHEIGHT:{
658 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
662 GST_WARNING_OBJECT (demux, "Invalid TrackVideoPixelHeight 0");
666 GST_DEBUG_OBJECT (demux,
667 "TrackVideoPixelHeight: %" G_GUINT64_FORMAT, num);
668 videocontext->pixel_height = num;
672 /* whether the video is interlaced */
673 case GST_MATROSKA_ID_VIDEOFLAGINTERLACED:{
676 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
680 context->flags |= GST_MATROSKA_VIDEOTRACK_INTERLACED;
682 context->flags &= ~GST_MATROSKA_VIDEOTRACK_INTERLACED;
683 GST_DEBUG_OBJECT (demux, "TrackVideoInterlaced: %d",
684 (context->flags & GST_MATROSKA_VIDEOTRACK_INTERLACED) ? 1 :
689 /* aspect ratio behaviour */
690 case GST_MATROSKA_ID_VIDEOASPECTRATIOTYPE:{
693 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
696 if (num != GST_MATROSKA_ASPECT_RATIO_MODE_FREE &&
697 num != GST_MATROSKA_ASPECT_RATIO_MODE_KEEP &&
698 num != GST_MATROSKA_ASPECT_RATIO_MODE_FIXED) {
699 GST_WARNING_OBJECT (demux,
700 "Unknown TrackVideoAspectRatioType 0x%x", (guint) num);
703 GST_DEBUG_OBJECT (demux,
704 "TrackVideoAspectRatioType: %" G_GUINT64_FORMAT, num);
705 videocontext->asr_mode = num;
709 /* colourspace (only matters for raw video) fourcc */
710 case GST_MATROSKA_ID_VIDEOCOLOURSPACE:{
715 gst_ebml_read_binary (ebml, &id, &data,
716 &datalen)) != GST_FLOW_OK)
721 GST_WARNING_OBJECT (demux,
722 "Invalid TrackVideoColourSpace length %" G_GUINT64_FORMAT,
727 memcpy (&videocontext->fourcc, data, 4);
728 GST_DEBUG_OBJECT (demux,
729 "TrackVideoColourSpace: %" GST_FOURCC_FORMAT,
730 GST_FOURCC_ARGS (videocontext->fourcc));
734 case GST_MATROSKA_ID_VIDEOSTEREOMODE:
738 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
741 GST_DEBUG_OBJECT (demux, "StereoMode: %" G_GUINT64_FORMAT, num);
744 case GST_MATROSKA_STEREO_MODE_SBS_RL:
745 videocontext->multiview_flags =
746 GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST;
748 case GST_MATROSKA_STEREO_MODE_SBS_LR:
749 videocontext->multiview_mode =
750 GST_VIDEO_MULTIVIEW_MODE_SIDE_BY_SIDE;
752 case GST_MATROSKA_STEREO_MODE_TB_RL:
753 videocontext->multiview_flags =
754 GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST;
756 case GST_MATROSKA_STEREO_MODE_TB_LR:
757 videocontext->multiview_mode =
758 GST_VIDEO_MULTIVIEW_MODE_TOP_BOTTOM;
760 case GST_MATROSKA_STEREO_MODE_CHECKER_RL:
761 videocontext->multiview_flags =
762 GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST;
764 case GST_MATROSKA_STEREO_MODE_CHECKER_LR:
765 videocontext->multiview_mode =
766 GST_VIDEO_MULTIVIEW_MODE_CHECKERBOARD;
768 case GST_MATROSKA_STEREO_MODE_FBF_RL:
769 videocontext->multiview_flags =
770 GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST;
772 case GST_MATROSKA_STEREO_MODE_FBF_LR:
773 videocontext->multiview_mode =
774 GST_VIDEO_MULTIVIEW_MODE_FRAME_BY_FRAME;
775 /* FIXME: In frame-by-frame mode, left/right frame buffers are
776 * laced within one block, and we'll need to apply FIRST_IN_BUNDLE
777 * accordingly. See http://www.matroska.org/technical/specs/index.html#StereoMode */
778 GST_FIXME_OBJECT (demux,
779 "Frame-by-frame stereoscopic mode not fully implemented");
786 GST_WARNING_OBJECT (demux,
787 "Unknown TrackVideo subelement 0x%x - ignoring", id);
789 case GST_MATROSKA_ID_VIDEODISPLAYUNIT:
790 case GST_MATROSKA_ID_VIDEOPIXELCROPBOTTOM:
791 case GST_MATROSKA_ID_VIDEOPIXELCROPTOP:
792 case GST_MATROSKA_ID_VIDEOPIXELCROPLEFT:
793 case GST_MATROSKA_ID_VIDEOPIXELCROPRIGHT:
794 case GST_MATROSKA_ID_VIDEOGAMMAVALUE:
795 ret = gst_ebml_read_skip (ebml);
800 DEBUG_ELEMENT_STOP (demux, ebml, "TrackVideo", ret);
804 /* tracktype specific stuff for audio */
805 case GST_MATROSKA_ID_TRACKAUDIO:{
806 GstMatroskaTrackAudioContext *audiocontext;
808 DEBUG_ELEMENT_START (demux, ebml, "TrackAudio");
810 if (!gst_matroska_track_init_audio_context (&context)) {
811 GST_WARNING_OBJECT (demux,
812 "TrackAudio element in non-audio track - ignoring track");
813 ret = GST_FLOW_ERROR;
817 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
820 audiocontext = (GstMatroskaTrackAudioContext *) context;
821 g_ptr_array_index (demux->common.src, demux->common.num_streams - 1)
824 while (ret == GST_FLOW_OK &&
825 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
826 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
831 case GST_MATROSKA_ID_AUDIOSAMPLINGFREQ:{
834 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
839 GST_WARNING_OBJECT (demux,
840 "Invalid TrackAudioSamplingFrequency %lf", num);
844 GST_DEBUG_OBJECT (demux, "TrackAudioSamplingFrequency: %lf", num);
845 audiocontext->samplerate = num;
850 case GST_MATROSKA_ID_AUDIOBITDEPTH:{
853 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
857 GST_WARNING_OBJECT (demux, "Invalid TrackAudioBitDepth 0");
861 GST_DEBUG_OBJECT (demux, "TrackAudioBitDepth: %" G_GUINT64_FORMAT,
863 audiocontext->bitdepth = num;
868 case GST_MATROSKA_ID_AUDIOCHANNELS:{
871 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
875 GST_WARNING_OBJECT (demux, "Invalid TrackAudioChannels 0");
879 GST_DEBUG_OBJECT (demux, "TrackAudioChannels: %" G_GUINT64_FORMAT,
881 audiocontext->channels = num;
886 GST_WARNING_OBJECT (demux,
887 "Unknown TrackAudio subelement 0x%x - ignoring", id);
889 case GST_MATROSKA_ID_AUDIOCHANNELPOSITIONS:
890 case GST_MATROSKA_ID_AUDIOOUTPUTSAMPLINGFREQ:
891 ret = gst_ebml_read_skip (ebml);
896 DEBUG_ELEMENT_STOP (demux, ebml, "TrackAudio", ret);
901 /* codec identifier */
902 case GST_MATROSKA_ID_CODECID:{
905 if ((ret = gst_ebml_read_ascii (ebml, &id, &text)) != GST_FLOW_OK)
908 GST_DEBUG_OBJECT (demux, "CodecID: %s", GST_STR_NULL (text));
909 context->codec_id = text;
913 /* codec private data */
914 case GST_MATROSKA_ID_CODECPRIVATE:{
919 gst_ebml_read_binary (ebml, &id, &data, &size)) != GST_FLOW_OK)
922 context->codec_priv = data;
923 context->codec_priv_size = size;
925 GST_DEBUG_OBJECT (demux, "CodecPrivate of size %" G_GUINT64_FORMAT,
930 /* name of the codec */
931 case GST_MATROSKA_ID_CODECNAME:{
934 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
937 GST_DEBUG_OBJECT (demux, "CodecName: %s", GST_STR_NULL (text));
938 context->codec_name = text;
942 /* name of this track */
943 case GST_MATROSKA_ID_TRACKNAME:{
946 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
949 context->name = text;
950 GST_DEBUG_OBJECT (demux, "TrackName: %s", GST_STR_NULL (text));
954 /* language (matters for audio/subtitles, mostly) */
955 case GST_MATROSKA_ID_TRACKLANGUAGE:{
958 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
962 context->language = text;
965 if (strlen (context->language) >= 4 && context->language[3] == '-')
966 context->language[3] = '\0';
968 GST_DEBUG_OBJECT (demux, "TrackLanguage: %s",
969 GST_STR_NULL (context->language));
973 /* whether this is actually used */
974 case GST_MATROSKA_ID_TRACKFLAGENABLED:{
977 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
981 context->flags |= GST_MATROSKA_TRACK_ENABLED;
983 context->flags &= ~GST_MATROSKA_TRACK_ENABLED;
985 GST_DEBUG_OBJECT (demux, "TrackEnabled: %d",
986 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
990 /* whether it's the default for this track type */
991 case GST_MATROSKA_ID_TRACKFLAGDEFAULT:{
994 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
998 context->flags |= GST_MATROSKA_TRACK_DEFAULT;
1000 context->flags &= ~GST_MATROSKA_TRACK_DEFAULT;
1002 GST_DEBUG_OBJECT (demux, "TrackDefault: %d",
1003 (context->flags & GST_MATROSKA_TRACK_DEFAULT) ? 1 : 0);
1007 /* whether the track must be used during playback */
1008 case GST_MATROSKA_ID_TRACKFLAGFORCED:{
1011 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1015 context->flags |= GST_MATROSKA_TRACK_FORCED;
1017 context->flags &= ~GST_MATROSKA_TRACK_FORCED;
1019 GST_DEBUG_OBJECT (demux, "TrackForced: %d",
1020 (context->flags & GST_MATROSKA_TRACK_FORCED) ? 1 : 0);
1024 /* lacing (like MPEG, where blocks don't end/start on frame
1026 case GST_MATROSKA_ID_TRACKFLAGLACING:{
1029 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1033 context->flags |= GST_MATROSKA_TRACK_LACING;
1035 context->flags &= ~GST_MATROSKA_TRACK_LACING;
1037 GST_DEBUG_OBJECT (demux, "TrackLacing: %d",
1038 (context->flags & GST_MATROSKA_TRACK_LACING) ? 1 : 0);
1042 /* default length (in time) of one data block in this track */
1043 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
1046 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1051 GST_WARNING_OBJECT (demux, "Invalid TrackDefaultDuration 0");
1055 GST_DEBUG_OBJECT (demux, "TrackDefaultDuration: %" G_GUINT64_FORMAT,
1057 context->default_duration = num;
1061 case GST_MATROSKA_ID_CONTENTENCODINGS:{
1062 ret = gst_matroska_read_common_read_track_encodings (&demux->common,
1067 case GST_MATROSKA_ID_TRACKTIMECODESCALE:{
1070 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
1074 GST_WARNING_OBJECT (demux, "Invalid TrackTimeCodeScale %lf", num);
1078 GST_DEBUG_OBJECT (demux, "TrackTimeCodeScale: %lf", num);
1079 context->timecodescale = num;
1084 GST_WARNING ("Unknown TrackEntry subelement 0x%x - ignoring", id);
1087 /* we ignore these because they're nothing useful (i.e. crap)
1088 * or simply not implemented yet. */
1089 case GST_MATROSKA_ID_TRACKMINCACHE:
1090 case GST_MATROSKA_ID_TRACKMAXCACHE:
1091 case GST_MATROSKA_ID_MAXBLOCKADDITIONID:
1092 case GST_MATROSKA_ID_TRACKATTACHMENTLINK:
1093 case GST_MATROSKA_ID_TRACKOVERLAY:
1094 case GST_MATROSKA_ID_TRACKTRANSLATE:
1095 case GST_MATROSKA_ID_TRACKOFFSET:
1096 case GST_MATROSKA_ID_CODECSETTINGS:
1097 case GST_MATROSKA_ID_CODECINFOURL:
1098 case GST_MATROSKA_ID_CODECDOWNLOADURL:
1099 case GST_MATROSKA_ID_CODECDECODEALL:
1100 ret = gst_ebml_read_skip (ebml);
1105 DEBUG_ELEMENT_STOP (demux, ebml, "TrackEntry", ret);
1107 /* Decode codec private data if necessary */
1108 if (context->encodings && context->encodings->len > 0 && context->codec_priv
1109 && context->codec_priv_size > 0) {
1110 if (!gst_matroska_decode_data (context->encodings,
1111 &context->codec_priv, &context->codec_priv_size,
1112 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
1113 GST_WARNING_OBJECT (demux, "Decoding codec private data failed");
1114 ret = GST_FLOW_ERROR;
1118 if (context->type == 0 || context->codec_id == NULL || (ret != GST_FLOW_OK
1119 && ret != GST_FLOW_EOS)) {
1120 if (ret == GST_FLOW_OK || ret == GST_FLOW_EOS)
1121 GST_WARNING_OBJECT (ebml, "Unknown stream/codec in track entry header");
1123 demux->common.num_streams--;
1124 g_ptr_array_remove_index (demux->common.src, demux->common.num_streams);
1125 g_assert (demux->common.src->len == demux->common.num_streams);
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_unmap (*buf, &map);
2998 gst_buffer_copy_into (newbuf, *buf,
2999 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS |
3000 GST_BUFFER_COPY_META, 0, -1);
3001 gst_buffer_unref (*buf);
3003 gst_buffer_map (*buf, &map, GST_MAP_READ);
3006 if (!sub_stream->invalid_utf8) {
3007 if (g_utf8_validate ((gchar *) map.data, map.size - 1, NULL)) {
3010 GST_WARNING_OBJECT (element, "subtitle stream %" G_GUINT64_FORMAT
3011 " is not valid UTF-8, this is broken according to the matroska"
3012 " specification", stream->num);
3013 sub_stream->invalid_utf8 = TRUE;
3016 /* file with broken non-UTF8 subtitle, do the best we can do to fix it */
3017 encoding = g_getenv ("GST_SUBTITLE_ENCODING");
3018 if (encoding == NULL || *encoding == '\0') {
3019 /* if local encoding is UTF-8 and no encoding specified
3020 * via the environment variable, assume ISO-8859-15 */
3021 if (g_get_charset (&encoding)) {
3022 encoding = "ISO-8859-15";
3027 g_convert_with_fallback ((gchar *) map.data, map.size, "UTF-8", encoding,
3028 (char *) "*", NULL, NULL, &err);
3031 GST_LOG_OBJECT (element, "could not convert string from '%s' to UTF-8: %s",
3032 encoding, err->message);
3036 /* invalid input encoding, fall back to ISO-8859-15 (always succeeds) */
3037 encoding = "ISO-8859-15";
3039 g_convert_with_fallback ((gchar *) map.data, map.size, "UTF-8",
3040 encoding, (char *) "*", NULL, NULL, NULL);
3043 GST_LOG_OBJECT (element, "converted subtitle text from %s to UTF-8 %s",
3044 encoding, (err) ? "(using ISO-8859-15 as fallback)" : "");
3047 utf8 = g_strdup ("invalid subtitle");
3049 newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
3050 gst_buffer_unmap (*buf, &map);
3051 gst_buffer_copy_into (newbuf, *buf,
3052 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_META,
3054 gst_buffer_unref (*buf);
3057 gst_buffer_map (*buf, &map, GST_MAP_READ);
3061 if (sub_stream->check_markup) {
3062 /* caps claim markup text, so we need to escape text,
3063 * except if text is already markup and then needs no further escaping */
3064 sub_stream->seen_markup_tag = sub_stream->seen_markup_tag ||
3065 gst_matroska_demux_subtitle_chunk_has_tag (element, (gchar *) map.data);
3067 if (!sub_stream->seen_markup_tag) {
3068 utf8 = g_markup_escape_text ((gchar *) map.data, map.size);
3070 newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
3071 gst_buffer_unmap (*buf, &map);
3072 gst_buffer_copy_into (newbuf, *buf,
3073 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS |
3074 GST_BUFFER_COPY_META, 0, -1);
3075 gst_buffer_unref (*buf);
3078 needs_unmap = FALSE;
3083 gst_buffer_unmap (*buf, &map);
3088 static GstFlowReturn
3089 gst_matroska_demux_check_aac (GstElement * element,
3090 GstMatroskaTrackContext * stream, GstBuffer ** buf)
3095 gst_buffer_extract (*buf, 0, data, 2);
3096 size = gst_buffer_get_size (*buf);
3098 if (size > 2 && data[0] == 0xff && (data[1] >> 4 == 0x0f)) {
3101 /* tss, ADTS data, remove codec_data
3102 * still assume it is at least parsed */
3103 stream->caps = gst_caps_make_writable (stream->caps);
3104 s = gst_caps_get_structure (stream->caps, 0);
3106 gst_structure_remove_field (s, "codec_data");
3107 gst_pad_set_caps (stream->pad, stream->caps);
3108 GST_DEBUG_OBJECT (element, "ADTS AAC audio data; removing codec-data, "
3109 "new caps: %" GST_PTR_FORMAT, stream->caps);
3112 /* disable subsequent checking */
3113 stream->postprocess_frame = NULL;
3119 gst_matroska_demux_align_buffer (GstMatroskaDemux * demux,
3120 GstBuffer * buffer, gsize alignment)
3124 gst_buffer_map (buffer, &map, GST_MAP_READ);
3126 if (map.size < sizeof (guintptr)) {
3127 gst_buffer_unmap (buffer, &map);
3131 if (((guintptr) map.data) & (alignment - 1)) {
3132 GstBuffer *new_buffer;
3133 GstAllocationParams params = { 0, alignment - 1, 0, 0, };
3135 new_buffer = gst_buffer_new_allocate (NULL,
3136 gst_buffer_get_size (buffer), ¶ms);
3138 /* Copy data "by hand", so ensure alignment is kept: */
3139 gst_buffer_fill (new_buffer, 0, map.data, map.size);
3141 gst_buffer_copy_into (new_buffer, buffer, GST_BUFFER_COPY_METADATA, 0, -1);
3142 GST_DEBUG_OBJECT (demux,
3143 "We want output aligned on %" G_GSIZE_FORMAT ", reallocated",
3146 gst_buffer_unmap (buffer, &map);
3147 gst_buffer_unref (buffer);
3152 gst_buffer_unmap (buffer, &map);
3156 static GstFlowReturn
3157 gst_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux,
3158 GstEbmlRead * ebml, guint64 cluster_time, guint64 cluster_offset,
3159 gboolean is_simpleblock)
3161 GstMatroskaTrackContext *stream = NULL;
3162 GstFlowReturn ret = GST_FLOW_OK;
3163 gboolean readblock = FALSE;
3165 guint64 block_duration = -1;
3166 GstBuffer *buf = NULL;
3168 gint stream_num = -1, n, laces = 0;
3170 gint *lace_size = NULL;
3173 gint64 referenceblock = 0;
3175 GstClockTime buffer_timestamp;
3177 offset = gst_ebml_read_get_offset (ebml);
3179 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3180 if (!is_simpleblock) {
3181 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK) {
3185 id = GST_MATROSKA_ID_SIMPLEBLOCK;
3189 /* one block inside the group. Note, block parsing is one
3190 * of the harder things, so this code is a bit complicated.
3191 * See http://www.matroska.org/ for documentation. */
3192 case GST_MATROSKA_ID_SIMPLEBLOCK:
3193 case GST_MATROSKA_ID_BLOCK:
3199 gst_buffer_unmap (buf, &map);
3200 gst_buffer_unref (buf);
3203 if ((ret = gst_ebml_read_buffer (ebml, &id, &buf)) != GST_FLOW_OK)
3206 gst_buffer_map (buf, &map, GST_MAP_READ);
3210 /* first byte(s): blocknum */
3211 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
3216 /* fetch stream from num */
3217 stream_num = gst_matroska_read_common_stream_from_num (&demux->common,
3219 if (G_UNLIKELY (size < 3)) {
3220 GST_WARNING_OBJECT (demux, "Invalid size %u", size);
3221 /* non-fatal, try next block(group) */
3224 } else if (G_UNLIKELY (stream_num < 0 ||
3225 stream_num >= demux->common.num_streams)) {
3226 /* let's not give up on a stray invalid track number */
3227 GST_WARNING_OBJECT (demux,
3228 "Invalid stream %d for track number %" G_GUINT64_FORMAT
3229 "; ignoring block", stream_num, num);
3233 stream = g_ptr_array_index (demux->common.src, stream_num);
3235 /* time (relative to cluster time) */
3236 time = ((gint16) GST_READ_UINT16_BE (data));
3239 flags = GST_READ_UINT8 (data);
3243 GST_LOG_OBJECT (demux, "time %" G_GUINT64_FORMAT ", flags %d", time,
3246 switch ((flags & 0x06) >> 1) {
3247 case 0x0: /* no lacing */
3249 lace_size = g_new (gint, 1);
3250 lace_size[0] = size;
3253 case 0x1: /* xiph lacing */
3254 case 0x2: /* fixed-size lacing */
3255 case 0x3: /* EBML lacing */
3257 goto invalid_lacing;
3258 laces = GST_READ_UINT8 (data) + 1;
3261 lace_size = g_new0 (gint, laces);
3263 switch ((flags & 0x06) >> 1) {
3264 case 0x1: /* xiph lacing */ {
3265 guint temp, total = 0;
3267 for (n = 0; ret == GST_FLOW_OK && n < laces - 1; n++) {
3270 goto invalid_lacing;
3271 temp = GST_READ_UINT8 (data);
3272 lace_size[n] += temp;
3278 total += lace_size[n];
3280 lace_size[n] = size - total;
3284 case 0x2: /* fixed-size lacing */
3285 for (n = 0; n < laces; n++)
3286 lace_size[n] = size / laces;
3289 case 0x3: /* EBML lacing */ {
3292 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
3296 total = lace_size[0] = num;
3297 for (n = 1; ret == GST_FLOW_OK && n < laces - 1; n++) {
3301 if ((r = gst_matroska_ebmlnum_sint (data, size, &snum)) < 0)
3305 lace_size[n] = lace_size[n - 1] + snum;
3306 total += lace_size[n];
3309 lace_size[n] = size - total;
3316 if (ret != GST_FLOW_OK)
3323 case GST_MATROSKA_ID_BLOCKDURATION:{
3324 ret = gst_ebml_read_uint (ebml, &id, &block_duration);
3325 GST_DEBUG_OBJECT (demux, "BlockDuration: %" G_GUINT64_FORMAT,
3330 case GST_MATROSKA_ID_REFERENCEBLOCK:{
3331 ret = gst_ebml_read_sint (ebml, &id, &referenceblock);
3332 GST_DEBUG_OBJECT (demux, "ReferenceBlock: %" G_GINT64_FORMAT,
3337 case GST_MATROSKA_ID_CODECSTATE:{
3339 guint64 data_len = 0;
3342 gst_ebml_read_binary (ebml, &id, &data,
3343 &data_len)) != GST_FLOW_OK)
3346 if (G_UNLIKELY (stream == NULL)) {
3347 GST_WARNING_OBJECT (demux,
3348 "Unexpected CodecState subelement - ignoring");
3352 g_free (stream->codec_state);
3353 stream->codec_state = data;
3354 stream->codec_state_size = data_len;
3356 /* Decode if necessary */
3357 if (stream->encodings && stream->encodings->len > 0
3358 && stream->codec_state && stream->codec_state_size > 0) {
3359 if (!gst_matroska_decode_data (stream->encodings,
3360 &stream->codec_state, &stream->codec_state_size,
3361 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
3362 GST_WARNING_OBJECT (demux, "Decoding codec state failed");
3366 GST_DEBUG_OBJECT (demux, "CodecState of %" G_GSIZE_FORMAT " bytes",
3367 stream->codec_state_size);
3372 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3376 case GST_MATROSKA_ID_BLOCKVIRTUAL:
3377 case GST_MATROSKA_ID_BLOCKADDITIONS:
3378 case GST_MATROSKA_ID_REFERENCEPRIORITY:
3379 case GST_MATROSKA_ID_REFERENCEVIRTUAL:
3380 case GST_MATROSKA_ID_SLICES:
3381 GST_DEBUG_OBJECT (demux,
3382 "Skipping BlockGroup subelement 0x%x - ignoring", id);
3383 ret = gst_ebml_read_skip (ebml);
3391 /* reading a number or so could have failed */
3392 if (ret != GST_FLOW_OK)
3395 if (ret == GST_FLOW_OK && readblock) {
3396 gboolean invisible_frame = FALSE;
3397 gboolean delta_unit = FALSE;
3398 guint64 duration = 0;
3399 gint64 lace_time = 0;
3401 stream = g_ptr_array_index (demux->common.src, stream_num);
3403 if (cluster_time != GST_CLOCK_TIME_NONE) {
3404 /* FIXME: What to do with negative timestamps? Give timestamp 0 or -1?
3405 * Drop unless the lace contains timestamp 0? */
3406 if (time < 0 && (-time) > cluster_time) {
3409 if (stream->timecodescale == 1.0)
3410 lace_time = (cluster_time + time) * demux->common.time_scale;
3413 gst_util_guint64_to_gdouble ((cluster_time + time) *
3414 demux->common.time_scale) * stream->timecodescale;
3417 lace_time = GST_CLOCK_TIME_NONE;
3420 /* need to refresh segment info ASAP */
3421 if (GST_CLOCK_TIME_IS_VALID (lace_time) && demux->need_segment) {
3422 GstSegment *segment = &demux->common.segment;
3424 GstEvent *segment_event;
3426 if (!GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
3427 demux->stream_start_time = lace_time;
3428 GST_DEBUG_OBJECT (demux,
3429 "Setting stream start time to %" GST_TIME_FORMAT,
3430 GST_TIME_ARGS (lace_time));
3432 clace_time = MAX (lace_time, demux->stream_start_time);
3433 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.position) &&
3434 demux->common.segment.position != 0) {
3435 GST_DEBUG_OBJECT (demux,
3436 "using stored seek position %" GST_TIME_FORMAT,
3437 GST_TIME_ARGS (demux->common.segment.position));
3438 clace_time = demux->common.segment.position + demux->stream_start_time;
3439 segment->position = GST_CLOCK_TIME_NONE;
3441 segment->start = clace_time;
3442 segment->stop = GST_CLOCK_TIME_NONE;
3443 segment->time = segment->start - demux->stream_start_time;
3444 segment->position = segment->start - demux->stream_start_time;
3445 GST_DEBUG_OBJECT (demux,
3446 "generated segment starting at %" GST_TIME_FORMAT ": %"
3447 GST_SEGMENT_FORMAT, GST_TIME_ARGS (lace_time), segment);
3448 /* now convey our segment notion downstream */
3449 segment_event = gst_event_new_segment (segment);
3450 if (demux->segment_seqnum)
3451 gst_event_set_seqnum (segment_event, demux->segment_seqnum);
3452 gst_matroska_demux_send_event (demux, segment_event);
3453 demux->need_segment = FALSE;
3454 demux->segment_seqnum = 0;
3457 /* send pending codec data headers for all streams,
3458 * before we perform sync across all streams */
3459 gst_matroska_demux_push_codec_data_all (demux);
3461 if (block_duration != -1) {
3462 if (stream->timecodescale == 1.0)
3463 duration = gst_util_uint64_scale (block_duration,
3464 demux->common.time_scale, 1);
3467 gst_util_gdouble_to_guint64 (gst_util_guint64_to_gdouble
3468 (gst_util_uint64_scale (block_duration, demux->common.time_scale,
3469 1)) * stream->timecodescale);
3470 } else if (stream->default_duration) {
3471 duration = stream->default_duration * laces;
3473 /* else duration is diff between timecode of this and next block */
3475 /* For SimpleBlock, look at the keyframe bit in flags. Otherwise,
3476 a ReferenceBlock implies that this is not a keyframe. In either
3477 case, it only makes sense for video streams. */
3478 if (stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
3479 if ((is_simpleblock && !(flags & 0x80)) || referenceblock) {
3481 invisible_frame = ((flags & 0x08)) &&
3482 (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8) ||
3483 !strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP9));
3487 for (n = 0; n < laces; n++) {
3490 if (G_UNLIKELY (lace_size[n] > size)) {
3491 GST_WARNING_OBJECT (demux, "Invalid lace size");
3495 /* QoS for video track with an index. the assumption is that
3496 index entries point to keyframes, but if that is not true we
3497 will instad skip until the next keyframe. */
3498 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
3499 stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
3500 stream->index_table && demux->common.segment.rate > 0.0) {
3501 GstMatroskaTrackVideoContext *videocontext =
3502 (GstMatroskaTrackVideoContext *) stream;
3503 GstClockTime earliest_time;
3504 GstClockTime earliest_stream_time;
3506 GST_OBJECT_LOCK (demux);
3507 earliest_time = videocontext->earliest_time;
3508 GST_OBJECT_UNLOCK (demux);
3509 earliest_stream_time = gst_segment_to_position (&demux->common.segment,
3510 GST_FORMAT_TIME, earliest_time);
3512 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
3513 GST_CLOCK_TIME_IS_VALID (earliest_stream_time) &&
3514 lace_time <= earliest_stream_time) {
3515 /* find index entry (keyframe) <= earliest_stream_time */
3516 GstMatroskaIndex *entry =
3517 gst_util_array_binary_search (stream->index_table->data,
3518 stream->index_table->len, sizeof (GstMatroskaIndex),
3519 (GCompareDataFunc) gst_matroska_index_seek_find,
3520 GST_SEARCH_MODE_BEFORE, &earliest_stream_time, NULL);
3522 /* if that entry (keyframe) is after the current the current
3523 buffer, we can skip pushing (and thus decoding) all
3524 buffers until that keyframe. */
3525 if (entry && GST_CLOCK_TIME_IS_VALID (entry->time) &&
3526 entry->time > lace_time) {
3527 GST_LOG_OBJECT (demux, "Skipping lace before late keyframe");
3528 stream->set_discont = TRUE;
3534 sub = gst_buffer_copy_region (buf, GST_BUFFER_COPY_ALL,
3535 gst_buffer_get_size (buf) - size, lace_size[n]);
3536 GST_DEBUG_OBJECT (demux, "created subbuffer %p", sub);
3539 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
3541 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
3543 if (invisible_frame)
3544 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DECODE_ONLY);
3546 if (stream->encodings != NULL && stream->encodings->len > 0)
3547 sub = gst_matroska_decode_buffer (stream, sub);
3550 GST_WARNING_OBJECT (demux, "Decoding buffer failed");
3554 buffer_timestamp = gst_matroska_track_get_buffer_timestamp (stream, sub);
3556 if (!stream->dts_only) {
3557 GST_BUFFER_PTS (sub) = lace_time;
3559 GST_BUFFER_DTS (sub) = lace_time;
3560 if (stream->intra_only)
3561 GST_BUFFER_PTS (sub) = lace_time;
3564 if (GST_CLOCK_TIME_IS_VALID (lace_time)) {
3565 GstClockTime last_stop_end;
3567 /* Check if this stream is after segment stop */
3568 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop) &&
3569 lace_time >= demux->common.segment.stop) {
3570 GST_DEBUG_OBJECT (demux,
3571 "Stream %d after segment stop %" GST_TIME_FORMAT, stream->index,
3572 GST_TIME_ARGS (demux->common.segment.stop));
3573 gst_buffer_unref (sub);
3576 if (offset >= stream->to_offset
3577 || (GST_CLOCK_TIME_IS_VALID (demux->to_time)
3578 && lace_time > demux->to_time)) {
3579 GST_DEBUG_OBJECT (demux, "Stream %d after playback section",
3581 gst_buffer_unref (sub);
3585 /* handle gaps, e.g. non-zero start-time, or an cue index entry
3586 * that landed us with timestamps not quite intended */
3587 GST_OBJECT_LOCK (demux);
3588 if (demux->max_gap_time &&
3589 GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) &&
3590 demux->common.segment.rate > 0.0) {
3591 GstClockTimeDiff diff;
3593 /* only send segments with increasing start times,
3594 * otherwise if these go back and forth downstream (sinks) increase
3595 * accumulated time and running_time */
3596 diff = GST_CLOCK_DIFF (demux->last_stop_end, lace_time);
3597 if (diff > 0 && diff > demux->max_gap_time
3598 && lace_time > demux->common.segment.start
3599 && (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop)
3600 || lace_time < demux->common.segment.stop)) {
3602 GST_DEBUG_OBJECT (demux,
3603 "Gap of %" G_GINT64_FORMAT " ns detected in"
3604 "stream %d (%" GST_TIME_FORMAT " -> %" GST_TIME_FORMAT "). "
3605 "Sending updated SEGMENT events", diff,
3606 stream->index, GST_TIME_ARGS (stream->pos),
3607 GST_TIME_ARGS (lace_time));
3609 event = gst_event_new_gap (demux->last_stop_end, diff);
3610 GST_OBJECT_UNLOCK (demux);
3611 gst_pad_push_event (stream->pad, event);
3612 GST_OBJECT_LOCK (demux);
3616 if (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.position)
3617 || demux->common.segment.position < lace_time) {
3618 demux->common.segment.position = lace_time;
3620 GST_OBJECT_UNLOCK (demux);
3622 last_stop_end = lace_time;
3624 GST_BUFFER_DURATION (sub) = duration / laces;
3625 last_stop_end += GST_BUFFER_DURATION (sub);
3628 if (!GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) ||
3629 demux->last_stop_end < last_stop_end)
3630 demux->last_stop_end = last_stop_end;
3632 GST_OBJECT_LOCK (demux);
3633 if (demux->common.segment.duration == -1 ||
3634 demux->stream_start_time + demux->common.segment.duration <
3636 demux->common.segment.duration =
3637 last_stop_end - demux->stream_start_time;
3638 GST_OBJECT_UNLOCK (demux);
3639 if (!demux->invalid_duration) {
3640 gst_element_post_message (GST_ELEMENT_CAST (demux),
3641 gst_message_new_duration_changed (GST_OBJECT_CAST (demux)));
3642 demux->invalid_duration = TRUE;
3645 GST_OBJECT_UNLOCK (demux);
3649 stream->pos = lace_time;
3651 gst_matroska_demux_sync_streams (demux);
3653 if (stream->set_discont) {
3654 GST_DEBUG_OBJECT (demux, "marking DISCONT");
3655 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DISCONT);
3656 stream->set_discont = FALSE;
3658 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DISCONT);
3661 /* reverse playback book-keeping */
3662 if (!GST_CLOCK_TIME_IS_VALID (stream->from_time))
3663 stream->from_time = lace_time;
3664 if (stream->from_offset == -1)
3665 stream->from_offset = offset;
3667 GST_DEBUG_OBJECT (demux,
3668 "Pushing lace %d, data of size %" G_GSIZE_FORMAT
3669 " for stream %d, time=%" GST_TIME_FORMAT " and duration=%"
3670 GST_TIME_FORMAT, n, gst_buffer_get_size (sub), stream_num,
3671 GST_TIME_ARGS (buffer_timestamp),
3672 GST_TIME_ARGS (GST_BUFFER_DURATION (sub)));
3675 if (demux->common.element_index) {
3676 if (stream->index_writer_id == -1)
3677 gst_index_get_writer_id (demux->common.element_index,
3678 GST_OBJECT (stream->pad), &stream->index_writer_id);
3680 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
3681 G_GUINT64_FORMAT " for writer id %d",
3682 GST_TIME_ARGS (buffer_timestamp), cluster_offset,
3683 stream->index_writer_id);
3684 gst_index_add_association (demux->common.element_index,
3685 stream->index_writer_id, GST_BUFFER_FLAG_IS_SET (sub,
3686 GST_BUFFER_FLAG_DELTA_UNIT) ? 0 : GST_ASSOCIATION_FLAG_KEY_UNIT,
3687 GST_FORMAT_TIME, buffer_timestamp, GST_FORMAT_BYTES, cluster_offset,
3692 /* Postprocess the buffers depending on the codec used */
3693 if (stream->postprocess_frame) {
3694 GST_LOG_OBJECT (demux, "running post process");
3695 ret = stream->postprocess_frame (GST_ELEMENT (demux), stream, &sub);
3698 /* At this point, we have a sub-buffer pointing at data within a larger
3699 buffer. This data might not be aligned with anything. If the data is
3700 raw samples though, we want it aligned to the raw type (eg, 4 bytes
3701 for 32 bit samples, etc), or bad things will happen downstream as
3702 elements typically assume minimal alignment.
3703 Therefore, create an aligned copy if necessary. */
3704 g_assert (stream->alignment <= G_MEM_ALIGN);
3705 sub = gst_matroska_demux_align_buffer (demux, sub, stream->alignment);
3707 if (GST_BUFFER_PTS_IS_VALID (sub)) {
3708 stream->pos = GST_BUFFER_PTS (sub);
3709 if (GST_BUFFER_DURATION_IS_VALID (sub))
3710 stream->pos += GST_BUFFER_DURATION (sub);
3711 } else if (GST_BUFFER_DTS_IS_VALID (sub)) {
3712 stream->pos = GST_BUFFER_DTS (sub);
3713 if (GST_BUFFER_DURATION_IS_VALID (sub))
3714 stream->pos += GST_BUFFER_DURATION (sub);
3717 ret = gst_pad_push (stream->pad, sub);
3719 if (demux->common.segment.rate < 0) {
3720 if (lace_time > demux->common.segment.stop && ret == GST_FLOW_EOS) {
3721 /* In reverse playback we can get a GST_FLOW_EOS when
3722 * we are at the end of the segment, so we just need to jump
3723 * back to the previous section. */
3724 GST_DEBUG_OBJECT (demux, "downstream has reached end of segment");
3729 ret = gst_flow_combiner_update_pad_flow (demux->flowcombiner,
3733 size -= lace_size[n];
3734 if (lace_time != GST_CLOCK_TIME_NONE && duration)
3735 lace_time += duration / laces;
3737 lace_time = GST_CLOCK_TIME_NONE;
3743 gst_buffer_unmap (buf, &map);
3744 gst_buffer_unref (buf);
3756 ret = gst_flow_combiner_update_pad_flow (demux->flowcombiner, stream->pad,
3762 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Invalid lacing size"));
3763 /* non-fatal, try next block(group) */
3769 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Data error"));
3770 /* non-fatal, try next block(group) */
3776 /* return FALSE if block(group) should be skipped (due to a seek) */
3777 static inline gboolean
3778 gst_matroska_demux_seek_block (GstMatroskaDemux * demux)
3780 if (G_UNLIKELY (demux->seek_block)) {
3781 if (!(--demux->seek_block)) {
3784 GST_LOG_OBJECT (demux, "should skip block due to seek");
3792 static GstFlowReturn
3793 gst_matroska_demux_parse_contents_seekentry (GstMatroskaDemux * demux,
3797 guint64 seek_pos = (guint64) - 1;
3798 guint32 seek_id = 0;
3801 DEBUG_ELEMENT_START (demux, ebml, "Seek");
3803 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3804 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
3808 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3809 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3813 case GST_MATROSKA_ID_SEEKID:
3817 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
3820 GST_DEBUG_OBJECT (demux, "SeekID: %" G_GUINT64_FORMAT, t);
3825 case GST_MATROSKA_ID_SEEKPOSITION:
3829 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
3832 if (t > G_MAXINT64) {
3833 GST_WARNING_OBJECT (demux,
3834 "Too large SeekPosition %" G_GUINT64_FORMAT, t);
3838 GST_DEBUG_OBJECT (demux, "SeekPosition: %" G_GUINT64_FORMAT, t);
3844 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3850 if (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)
3853 if (!seek_id || seek_pos == (guint64) - 1) {
3854 GST_WARNING_OBJECT (demux, "Incomplete seekhead entry (0x%x/%"
3855 G_GUINT64_FORMAT ")", seek_id, seek_pos);
3860 case GST_MATROSKA_ID_SEEKHEAD:
3863 case GST_MATROSKA_ID_CUES:
3864 case GST_MATROSKA_ID_TAGS:
3865 case GST_MATROSKA_ID_TRACKS:
3866 case GST_MATROSKA_ID_SEGMENTINFO:
3867 case GST_MATROSKA_ID_ATTACHMENTS:
3868 case GST_MATROSKA_ID_CHAPTERS:
3870 guint64 before_pos, length;
3874 length = gst_matroska_read_common_get_length (&demux->common);
3875 before_pos = demux->common.offset;
3877 if (length == (guint64) - 1) {
3878 GST_DEBUG_OBJECT (demux, "no upstream length, skipping SeakHead entry");
3882 /* check for validity */
3883 if (seek_pos + demux->common.ebml_segment_start + 12 >= length) {
3884 GST_WARNING_OBJECT (demux,
3885 "SeekHead reference lies outside file!" " (%"
3886 G_GUINT64_FORMAT "+%" G_GUINT64_FORMAT "+12 >= %"
3887 G_GUINT64_FORMAT ")", seek_pos, demux->common.ebml_segment_start,
3892 /* only pick up index location when streaming */
3893 if (demux->streaming) {
3894 if (seek_id == GST_MATROSKA_ID_CUES) {
3895 demux->index_offset = seek_pos + demux->common.ebml_segment_start;
3896 GST_DEBUG_OBJECT (demux, "Cues located at offset %" G_GUINT64_FORMAT,
3897 demux->index_offset);
3903 demux->common.offset = seek_pos + demux->common.ebml_segment_start;
3906 if ((ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
3907 GST_ELEMENT_CAST (demux), &id, &length, &needed)) !=
3911 if (id != seek_id) {
3912 GST_WARNING_OBJECT (demux,
3913 "We looked for ID=0x%x but got ID=0x%x (pos=%" G_GUINT64_FORMAT ")",
3914 seek_id, id, seek_pos + demux->common.ebml_segment_start);
3917 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
3922 demux->common.offset = before_pos;
3926 case GST_MATROSKA_ID_CLUSTER:
3928 guint64 pos = seek_pos + demux->common.ebml_segment_start;
3930 GST_LOG_OBJECT (demux, "Cluster position");
3931 if (G_UNLIKELY (!demux->clusters))
3932 demux->clusters = g_array_sized_new (TRUE, TRUE, sizeof (guint64), 100);
3933 g_array_append_val (demux->clusters, pos);
3938 GST_DEBUG_OBJECT (demux, "Ignoring Seek entry for ID=0x%x", seek_id);
3941 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
3946 static GstFlowReturn
3947 gst_matroska_demux_parse_contents (GstMatroskaDemux * demux, GstEbmlRead * ebml)
3949 GstFlowReturn ret = GST_FLOW_OK;
3952 DEBUG_ELEMENT_START (demux, ebml, "SeekHead");
3954 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3955 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
3959 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3960 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3964 case GST_MATROSKA_ID_SEEKENTRY:
3966 ret = gst_matroska_demux_parse_contents_seekentry (demux, ebml);
3967 /* Ignore EOS and errors here */
3968 if (ret != GST_FLOW_OK) {
3969 GST_DEBUG_OBJECT (demux, "Ignoring %s", gst_flow_get_name (ret));
3976 ret = gst_matroska_read_common_parse_skip (&demux->common,
3977 ebml, "SeekHead", id);
3982 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
3984 /* Sort clusters by position for easier searching */
3985 if (demux->clusters)
3986 g_array_sort (demux->clusters, (GCompareFunc) gst_matroska_cluster_compare);
3991 #define GST_FLOW_OVERFLOW GST_FLOW_CUSTOM_ERROR
3993 #define MAX_BLOCK_SIZE (15 * 1024 * 1024)
3995 static inline GstFlowReturn
3996 gst_matroska_demux_check_read_size (GstMatroskaDemux * demux, guint64 bytes)
3998 if (G_UNLIKELY (bytes > MAX_BLOCK_SIZE)) {
3999 /* only a few blocks are expected/allowed to be large,
4000 * and will be recursed into, whereas others will be read and must fit */
4001 if (demux->streaming) {
4002 /* fatal in streaming case, as we can't step over easily */
4003 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4004 ("reading large block of size %" G_GUINT64_FORMAT " not supported; "
4005 "file might be corrupt.", bytes));
4006 return GST_FLOW_ERROR;
4008 /* indicate higher level to quietly give up */
4009 GST_DEBUG_OBJECT (demux,
4010 "too large block of size %" G_GUINT64_FORMAT, bytes);
4011 return GST_FLOW_ERROR;
4018 /* returns TRUE if we truely are in error state, and should give up */
4019 static inline GstFlowReturn
4020 gst_matroska_demux_check_parse_error (GstMatroskaDemux * demux)
4022 if (!demux->streaming && demux->next_cluster_offset > 0) {
4023 /* just repositioning to where next cluster should be and try from there */
4024 GST_WARNING_OBJECT (demux, "parse error, trying next cluster expected at %"
4025 G_GUINT64_FORMAT, demux->next_cluster_offset);
4026 demux->common.offset = demux->next_cluster_offset;
4027 demux->next_cluster_offset = 0;
4033 /* sigh, one last attempt above and beyond call of duty ...;
4034 * search for cluster mark following current pos */
4035 pos = demux->common.offset;
4036 GST_WARNING_OBJECT (demux, "parse error, looking for next cluster");
4037 if ((ret = gst_matroska_demux_search_cluster (demux, &pos)) != GST_FLOW_OK) {
4038 /* did not work, give up */
4041 GST_DEBUG_OBJECT (demux, "... found at %" G_GUINT64_FORMAT, pos);
4042 /* try that position */
4043 demux->common.offset = pos;
4049 static inline GstFlowReturn
4050 gst_matroska_demux_flush (GstMatroskaDemux * demux, guint flush)
4052 GST_LOG_OBJECT (demux, "skipping %d bytes", flush);
4053 demux->common.offset += flush;
4054 if (demux->streaming) {
4057 /* hard to skip large blocks when streaming */
4058 ret = gst_matroska_demux_check_read_size (demux, flush);
4059 if (ret != GST_FLOW_OK)
4061 if (flush <= gst_adapter_available (demux->common.adapter))
4062 gst_adapter_flush (demux->common.adapter, flush);
4064 return GST_FLOW_EOS;
4069 /* initializes @ebml with @bytes from input stream at current offset.
4070 * Returns EOS if insufficient available,
4071 * ERROR if too much was attempted to read. */
4072 static inline GstFlowReturn
4073 gst_matroska_demux_take (GstMatroskaDemux * demux, guint64 bytes,
4076 GstBuffer *buffer = NULL;
4077 GstFlowReturn ret = GST_FLOW_OK;
4079 GST_LOG_OBJECT (demux, "taking %" G_GUINT64_FORMAT " bytes for parsing",
4081 ret = gst_matroska_demux_check_read_size (demux, bytes);
4082 if (G_UNLIKELY (ret != GST_FLOW_OK)) {
4083 if (!demux->streaming) {
4084 /* in pull mode, we can skip */
4085 if ((ret = gst_matroska_demux_flush (demux, bytes)) == GST_FLOW_OK)
4086 ret = GST_FLOW_OVERFLOW;
4088 /* otherwise fatal */
4089 ret = GST_FLOW_ERROR;
4093 if (demux->streaming) {
4094 if (gst_adapter_available (demux->common.adapter) >= bytes)
4095 buffer = gst_adapter_take_buffer (demux->common.adapter, bytes);
4099 ret = gst_matroska_read_common_peek_bytes (&demux->common,
4100 demux->common.offset, bytes, &buffer, NULL);
4101 if (G_LIKELY (buffer)) {
4102 gst_ebml_read_init (ebml, GST_ELEMENT_CAST (demux), buffer,
4103 demux->common.offset);
4104 demux->common.offset += bytes;
4111 gst_matroska_demux_check_seekability (GstMatroskaDemux * demux)
4114 gboolean seekable = FALSE;
4115 gint64 start = -1, stop = -1;
4117 query = gst_query_new_seeking (GST_FORMAT_BYTES);
4118 if (!gst_pad_peer_query (demux->common.sinkpad, query)) {
4119 GST_DEBUG_OBJECT (demux, "seeking query failed");
4123 gst_query_parse_seeking (query, NULL, &seekable, &start, &stop);
4125 /* try harder to query upstream size if we didn't get it the first time */
4126 if (seekable && stop == -1) {
4127 GST_DEBUG_OBJECT (demux, "doing duration query to fix up unset stop");
4128 gst_pad_peer_query_duration (demux->common.sinkpad, GST_FORMAT_BYTES,
4132 /* if upstream doesn't know the size, it's likely that it's not seekable in
4133 * practice even if it technically may be seekable */
4134 if (seekable && (start != 0 || stop <= start)) {
4135 GST_DEBUG_OBJECT (demux, "seekable but unknown start/stop -> disable");
4140 GST_INFO_OBJECT (demux, "seekable: %d (%" G_GUINT64_FORMAT " - %"
4141 G_GUINT64_FORMAT ")", seekable, start, stop);
4142 demux->seekable = seekable;
4144 gst_query_unref (query);
4147 static GstFlowReturn
4148 gst_matroska_demux_find_tracks (GstMatroskaDemux * demux)
4154 GstFlowReturn ret = GST_FLOW_OK;
4156 GST_WARNING_OBJECT (demux,
4157 "Found Cluster element before Tracks, searching Tracks");
4160 before_pos = demux->common.offset;
4162 /* Search Tracks element */
4164 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4165 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4166 if (ret != GST_FLOW_OK)
4169 if (id != GST_MATROSKA_ID_TRACKS) {
4170 /* we may be skipping large cluster here, so forego size check etc */
4171 /* ... but we can't skip undefined size; force error */
4172 if (length == G_MAXUINT64) {
4173 ret = gst_matroska_demux_check_read_size (demux, length);
4176 demux->common.offset += needed;
4177 demux->common.offset += length;
4182 /* will lead to track parsing ... */
4183 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4188 demux->common.offset = before_pos;
4193 #define GST_READ_CHECK(stmt) \
4195 if (G_UNLIKELY ((ret = (stmt)) != GST_FLOW_OK)) { \
4196 if (ret == GST_FLOW_OVERFLOW) { \
4197 ret = GST_FLOW_OK; \
4203 static GstFlowReturn
4204 gst_matroska_demux_parse_id (GstMatroskaDemux * demux, guint32 id,
4205 guint64 length, guint needed)
4207 GstEbmlRead ebml = { 0, };
4208 GstFlowReturn ret = GST_FLOW_OK;
4211 GST_LOG_OBJECT (demux, "Parsing Element id 0x%x, "
4212 "size %" G_GUINT64_FORMAT ", prefix %d", id, length, needed);
4214 /* if we plan to read and parse this element, we need prefix (id + length)
4215 * and the contents */
4216 /* mind about overflow wrap-around when dealing with undefined size */
4218 if (G_LIKELY (length != G_MAXUINT64))
4221 switch (demux->common.state) {
4222 case GST_MATROSKA_READ_STATE_START:
4224 case GST_EBML_ID_HEADER:
4225 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4226 ret = gst_matroska_read_common_parse_header (&demux->common, &ebml);
4227 if (ret != GST_FLOW_OK)
4229 demux->common.state = GST_MATROSKA_READ_STATE_SEGMENT;
4230 gst_matroska_demux_check_seekability (demux);
4233 goto invalid_header;
4237 case GST_MATROSKA_READ_STATE_SEGMENT:
4239 case GST_MATROSKA_ID_SEGMENT:
4240 /* eat segment prefix */
4241 GST_READ_CHECK (gst_matroska_demux_flush (demux, needed));
4242 GST_DEBUG_OBJECT (demux,
4243 "Found Segment start at offset %" G_GUINT64_FORMAT " with size %"
4244 G_GUINT64_FORMAT, demux->common.offset, length);
4245 /* seeks are from the beginning of the segment,
4246 * after the segment ID/length */
4247 demux->common.ebml_segment_start = demux->common.offset;
4249 length = G_MAXUINT64;
4250 demux->common.ebml_segment_length = length;
4251 demux->common.state = GST_MATROSKA_READ_STATE_HEADER;
4254 GST_WARNING_OBJECT (demux,
4255 "Expected a Segment ID (0x%x), but received 0x%x!",
4256 GST_MATROSKA_ID_SEGMENT, id);
4257 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4261 case GST_MATROSKA_READ_STATE_SCANNING:
4262 if (id != GST_MATROSKA_ID_CLUSTER &&
4263 id != GST_MATROSKA_ID_CLUSTERTIMECODE)
4266 case GST_MATROSKA_READ_STATE_HEADER:
4267 case GST_MATROSKA_READ_STATE_DATA:
4268 case GST_MATROSKA_READ_STATE_SEEK:
4270 case GST_MATROSKA_ID_SEGMENTINFO:
4271 if (!demux->common.segmentinfo_parsed) {
4272 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4273 ret = gst_matroska_read_common_parse_info (&demux->common,
4274 GST_ELEMENT_CAST (demux), &ebml);
4275 if (ret == GST_FLOW_OK)
4276 gst_matroska_demux_send_tags (demux);
4278 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4281 case GST_MATROSKA_ID_TRACKS:
4282 if (!demux->tracks_parsed) {
4283 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4284 ret = gst_matroska_demux_parse_tracks (demux, &ebml);
4286 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4289 case GST_MATROSKA_ID_CLUSTER:
4290 if (G_UNLIKELY (!demux->tracks_parsed)) {
4291 if (demux->streaming) {
4292 GST_DEBUG_OBJECT (demux, "Cluster before Track");
4293 goto not_streamable;
4295 ret = gst_matroska_demux_find_tracks (demux);
4296 if (!demux->tracks_parsed)
4300 if (G_UNLIKELY (demux->common.state
4301 == GST_MATROSKA_READ_STATE_HEADER)) {
4302 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
4303 demux->first_cluster_offset = demux->common.offset;
4304 GST_DEBUG_OBJECT (demux, "signaling no more pads");
4305 gst_element_no_more_pads (GST_ELEMENT (demux));
4306 /* send initial segment - we wait till we know the first
4307 incoming timestamp, so we can properly set the start of
4309 demux->need_segment = TRUE;
4311 demux->cluster_time = GST_CLOCK_TIME_NONE;
4312 demux->cluster_offset = demux->common.offset;
4313 if (G_UNLIKELY (!demux->seek_first && demux->seek_block)) {
4314 GST_DEBUG_OBJECT (demux, "seek target block %" G_GUINT64_FORMAT
4315 " not found in Cluster, trying next Cluster's first block instead",
4317 demux->seek_block = 0;
4319 demux->seek_first = FALSE;
4320 /* record next cluster for recovery */
4321 if (read != G_MAXUINT64)
4322 demux->next_cluster_offset = demux->cluster_offset + read;
4323 /* eat cluster prefix */
4324 gst_matroska_demux_flush (demux, needed);
4326 case GST_MATROSKA_ID_CLUSTERTIMECODE:
4330 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4331 if ((ret = gst_ebml_read_uint (&ebml, &id, &num)) != GST_FLOW_OK)
4333 GST_DEBUG_OBJECT (demux, "ClusterTimeCode: %" G_GUINT64_FORMAT, num);
4334 demux->cluster_time = num;
4336 if (demux->common.element_index) {
4337 if (demux->common.element_index_writer_id == -1)
4338 gst_index_get_writer_id (demux->common.element_index,
4339 GST_OBJECT (demux), &demux->common.element_index_writer_id);
4340 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
4341 G_GUINT64_FORMAT " for writer id %d",
4342 GST_TIME_ARGS (demux->cluster_time), demux->cluster_offset,
4343 demux->common.element_index_writer_id);
4344 gst_index_add_association (demux->common.element_index,
4345 demux->common.element_index_writer_id,
4346 GST_ASSOCIATION_FLAG_KEY_UNIT,
4347 GST_FORMAT_TIME, demux->cluster_time,
4348 GST_FORMAT_BYTES, demux->cluster_offset, NULL);
4353 case GST_MATROSKA_ID_BLOCKGROUP:
4354 if (!gst_matroska_demux_seek_block (demux))
4356 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4357 DEBUG_ELEMENT_START (demux, &ebml, "BlockGroup");
4358 if ((ret = gst_ebml_read_master (&ebml, &id)) == GST_FLOW_OK) {
4359 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4360 &ebml, demux->cluster_time, demux->cluster_offset, FALSE);
4362 DEBUG_ELEMENT_STOP (demux, &ebml, "BlockGroup", ret);
4364 case GST_MATROSKA_ID_SIMPLEBLOCK:
4365 if (!gst_matroska_demux_seek_block (demux))
4367 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4368 DEBUG_ELEMENT_START (demux, &ebml, "SimpleBlock");
4369 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4370 &ebml, demux->cluster_time, demux->cluster_offset, TRUE);
4371 DEBUG_ELEMENT_STOP (demux, &ebml, "SimpleBlock", ret);
4373 case GST_MATROSKA_ID_ATTACHMENTS:
4374 if (!demux->common.attachments_parsed) {
4375 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4376 ret = gst_matroska_read_common_parse_attachments (&demux->common,
4377 GST_ELEMENT_CAST (demux), &ebml);
4378 if (ret == GST_FLOW_OK)
4379 gst_matroska_demux_send_tags (demux);
4381 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4384 case GST_MATROSKA_ID_TAGS:
4385 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4386 ret = gst_matroska_read_common_parse_metadata (&demux->common,
4387 GST_ELEMENT_CAST (demux), &ebml);
4388 if (ret == GST_FLOW_OK)
4389 gst_matroska_demux_send_tags (demux);
4391 case GST_MATROSKA_ID_CHAPTERS:
4392 if (!demux->common.chapters_parsed) {
4393 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4395 gst_matroska_read_common_parse_chapters (&demux->common, &ebml);
4397 if (demux->common.toc) {
4398 gst_matroska_demux_send_event (demux,
4399 gst_event_new_toc (demux->common.toc, FALSE));
4402 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4404 case GST_MATROSKA_ID_SEEKHEAD:
4405 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4406 ret = gst_matroska_demux_parse_contents (demux, &ebml);
4408 case GST_MATROSKA_ID_CUES:
4409 if (demux->common.index_parsed) {
4410 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4413 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4414 ret = gst_matroska_read_common_parse_index (&demux->common, &ebml);
4415 /* only push based; delayed index building */
4416 if (ret == GST_FLOW_OK
4417 && demux->common.state == GST_MATROSKA_READ_STATE_SEEK) {
4420 GST_OBJECT_LOCK (demux);
4421 event = demux->seek_event;
4422 demux->seek_event = NULL;
4423 GST_OBJECT_UNLOCK (demux);
4426 /* unlikely to fail, since we managed to seek to this point */
4427 if (!gst_matroska_demux_handle_seek_event (demux, NULL, event)) {
4428 gst_event_unref (event);
4431 gst_event_unref (event);
4432 /* resume data handling, main thread clear to seek again */
4433 GST_OBJECT_LOCK (demux);
4434 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
4435 GST_OBJECT_UNLOCK (demux);
4438 case GST_MATROSKA_ID_POSITION:
4439 case GST_MATROSKA_ID_PREVSIZE:
4440 case GST_MATROSKA_ID_ENCRYPTEDBLOCK:
4441 case GST_MATROSKA_ID_SILENTTRACKS:
4442 GST_DEBUG_OBJECT (demux,
4443 "Skipping Cluster subelement 0x%x - ignoring", id);
4447 GST_DEBUG_OBJECT (demux, "skipping Element 0x%x", id);
4448 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4454 if (ret == GST_FLOW_PARSE)
4458 gst_ebml_read_clear (&ebml);
4464 /* simply exit, maybe not enough data yet */
4465 /* no ebml to clear if read error */
4470 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4471 ("Failed to parse Element 0x%x", id));
4472 ret = GST_FLOW_ERROR;
4477 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4478 ("File layout does not permit streaming"));
4479 ret = GST_FLOW_ERROR;
4484 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4485 ("No Tracks element found"));
4486 ret = GST_FLOW_ERROR;
4491 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Invalid header"));
4492 ret = GST_FLOW_ERROR;
4497 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Failed to seek"));
4498 ret = GST_FLOW_ERROR;
4504 gst_matroska_demux_loop (GstPad * pad)
4506 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (pad));
4512 /* If we have to close a segment, send a new segment to do this now */
4513 if (G_LIKELY (demux->common.state == GST_MATROSKA_READ_STATE_DATA)) {
4514 if (G_UNLIKELY (demux->new_segment)) {
4515 gst_matroska_demux_send_event (demux, demux->new_segment);
4516 demux->new_segment = NULL;
4520 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4521 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4522 if (ret == GST_FLOW_EOS) {
4524 } else if (ret == GST_FLOW_FLUSHING) {
4526 } else if (ret != GST_FLOW_OK) {
4527 ret = gst_matroska_demux_check_parse_error (demux);
4529 /* Only handle EOS as no error if we're outside the segment already */
4530 if (ret == GST_FLOW_EOS && (demux->common.ebml_segment_length != G_MAXUINT64
4531 && demux->common.offset >=
4532 demux->common.ebml_segment_start +
4533 demux->common.ebml_segment_length))
4535 else if (ret != GST_FLOW_OK)
4541 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
4542 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
4545 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4546 if (ret == GST_FLOW_EOS)
4548 if (ret != GST_FLOW_OK)
4551 /* check if we're at the end of a configured segment */
4552 if (G_LIKELY (demux->common.src->len)) {
4555 g_assert (demux->common.num_streams == demux->common.src->len);
4556 for (i = 0; i < demux->common.src->len; i++) {
4557 GstMatroskaTrackContext *context = g_ptr_array_index (demux->common.src,
4559 GST_DEBUG_OBJECT (context->pad, "pos %" GST_TIME_FORMAT,
4560 GST_TIME_ARGS (context->pos));
4561 if (context->eos == FALSE)
4565 GST_INFO_OBJECT (demux, "All streams are EOS");
4571 if (G_UNLIKELY (demux->cached_length == G_MAXUINT64 ||
4572 demux->common.offset >= demux->cached_length)) {
4573 demux->cached_length = gst_matroska_read_common_get_length (&demux->common);
4574 if (demux->common.offset == demux->cached_length) {
4575 GST_LOG_OBJECT (demux, "Reached end of stream");
4586 if (demux->common.segment.rate < 0.0) {
4587 ret = gst_matroska_demux_seek_to_previous_keyframe (demux);
4588 if (ret == GST_FLOW_OK)
4595 const gchar *reason = gst_flow_get_name (ret);
4596 gboolean push_eos = FALSE;
4598 GST_LOG_OBJECT (demux, "pausing task, reason %s", reason);
4599 gst_pad_pause_task (demux->common.sinkpad);
4601 if (ret == GST_FLOW_EOS) {
4602 /* perform EOS logic */
4604 /* If we were in the headers, make sure we send no-more-pads.
4605 This will ensure decodebin does not get stuck thinking
4606 the chain is not complete yet, and waiting indefinitely. */
4607 if (G_UNLIKELY (demux->common.state == GST_MATROSKA_READ_STATE_HEADER)) {
4608 if (demux->common.src->len == 0) {
4609 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
4610 ("No pads created"));
4612 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL),
4613 ("Failed to finish reading headers"));
4615 gst_element_no_more_pads (GST_ELEMENT (demux));
4618 if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
4621 /* for segment playback we need to post when (in stream time)
4622 * we stopped, this is either stop (when set) or the duration. */
4623 if ((stop = demux->common.segment.stop) == -1)
4624 stop = demux->last_stop_end;
4626 GST_LOG_OBJECT (demux, "Sending segment done, at end of segment");
4627 gst_element_post_message (GST_ELEMENT (demux),
4628 gst_message_new_segment_done (GST_OBJECT (demux), GST_FORMAT_TIME,
4630 gst_matroska_demux_send_event (demux,
4631 gst_event_new_segment_done (GST_FORMAT_TIME, stop));
4635 } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS) {
4636 /* for fatal errors we post an error message */
4637 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
4638 ("stream stopped, reason %s", reason));
4642 /* send EOS, and prevent hanging if no streams yet */
4643 GST_LOG_OBJECT (demux, "Sending EOS, at end of stream");
4644 if (!gst_matroska_demux_send_event (demux, gst_event_new_eos ()) &&
4645 (ret == GST_FLOW_EOS)) {
4646 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4647 (NULL), ("got eos but no streams (yet)"));
4655 * Create and push a flushing seek event upstream
4658 perform_seek_to_offset (GstMatroskaDemux * demux, gdouble rate, guint64 offset,
4664 GST_DEBUG_OBJECT (demux, "Seeking to %" G_GUINT64_FORMAT, offset);
4667 gst_event_new_seek (rate, GST_FORMAT_BYTES,
4668 GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, GST_SEEK_TYPE_SET, offset,
4669 GST_SEEK_TYPE_NONE, -1);
4670 gst_event_set_seqnum (event, seqnum);
4672 res = gst_pad_push_event (demux->common.sinkpad, event);
4674 /* segment event will update offset */
4678 static GstFlowReturn
4679 gst_matroska_demux_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
4681 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4683 GstFlowReturn ret = GST_FLOW_OK;
4688 if (G_UNLIKELY (GST_BUFFER_IS_DISCONT (buffer))) {
4689 GST_DEBUG_OBJECT (demux, "got DISCONT");
4690 gst_adapter_clear (demux->common.adapter);
4691 GST_OBJECT_LOCK (demux);
4692 gst_matroska_read_common_reset_streams (&demux->common,
4693 GST_CLOCK_TIME_NONE, FALSE);
4694 GST_OBJECT_UNLOCK (demux);
4697 gst_adapter_push (demux->common.adapter, buffer);
4701 available = gst_adapter_available (demux->common.adapter);
4703 ret = gst_matroska_read_common_peek_id_length_push (&demux->common,
4704 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4705 if (G_UNLIKELY (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)) {
4706 if (demux->common.ebml_segment_length != G_MAXUINT64
4707 && demux->common.offset >=
4708 demux->common.ebml_segment_start + demux->common.ebml_segment_length)
4713 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
4714 "size %" G_GUINT64_FORMAT ", needed %d, available %d",
4715 demux->common.offset, id, length, needed, available);
4717 if (needed > available)
4720 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4721 if (ret == GST_FLOW_EOS) {
4722 /* need more data */
4724 } else if (ret != GST_FLOW_OK) {
4731 gst_matroska_demux_handle_sink_event (GstPad * pad, GstObject * parent,
4734 gboolean res = TRUE;
4735 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4737 GST_DEBUG_OBJECT (demux,
4738 "have event type %s: %p on sink pad", GST_EVENT_TYPE_NAME (event), event);
4740 switch (GST_EVENT_TYPE (event)) {
4741 case GST_EVENT_SEGMENT:
4743 const GstSegment *segment;
4745 /* some debug output */
4746 gst_event_parse_segment (event, &segment);
4747 /* FIXME: do we need to update segment base here (like accum in 0.10)? */
4748 GST_DEBUG_OBJECT (demux,
4749 "received format %d segment %" GST_SEGMENT_FORMAT, segment->format,
4752 if (demux->common.state < GST_MATROSKA_READ_STATE_DATA) {
4753 GST_DEBUG_OBJECT (demux, "still starting");
4757 /* we only expect a BYTE segment, e.g. following a seek */
4758 if (segment->format != GST_FORMAT_BYTES) {
4759 GST_DEBUG_OBJECT (demux, "unsupported segment format, ignoring");
4763 GST_DEBUG_OBJECT (demux, "clearing segment state");
4764 GST_OBJECT_LOCK (demux);
4765 /* clear current segment leftover */
4766 gst_adapter_clear (demux->common.adapter);
4767 /* and some streaming setup */
4768 demux->common.offset = segment->start;
4769 /* accumulate base based on current position */
4770 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.position))
4771 demux->common.segment.base +=
4772 (MAX (demux->common.segment.position, demux->stream_start_time)
4773 - demux->stream_start_time) / fabs (demux->common.segment.rate);
4774 /* do not know where we are;
4775 * need to come across a cluster and generate segment */
4776 demux->common.segment.position = GST_CLOCK_TIME_NONE;
4777 demux->cluster_time = GST_CLOCK_TIME_NONE;
4778 demux->cluster_offset = 0;
4779 demux->need_segment = TRUE;
4780 demux->segment_seqnum = gst_event_get_seqnum (event);
4781 /* but keep some of the upstream segment */
4782 demux->common.segment.rate = segment->rate;
4783 /* also check if need to keep some of the requested seek position */
4784 if (demux->seek_offset == segment->start) {
4785 GST_DEBUG_OBJECT (demux, "position matches requested seek");
4786 demux->common.segment.position = demux->requested_seek_time;
4788 GST_DEBUG_OBJECT (demux, "unexpected segment position");
4790 demux->requested_seek_time = GST_CLOCK_TIME_NONE;
4791 demux->seek_offset = -1;
4792 GST_OBJECT_UNLOCK (demux);
4794 /* chain will send initial segment after pads have been added,
4795 * or otherwise come up with one */
4796 GST_DEBUG_OBJECT (demux, "eating event");
4797 gst_event_unref (event);
4803 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
4804 gst_event_unref (event);
4805 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4806 (NULL), ("got eos and didn't receive a complete header object"));
4807 } else if (demux->common.num_streams == 0) {
4808 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4809 (NULL), ("got eos but no streams (yet)"));
4811 gst_matroska_demux_send_event (demux, event);
4815 case GST_EVENT_FLUSH_STOP:
4819 gst_adapter_clear (demux->common.adapter);
4820 GST_OBJECT_LOCK (demux);
4821 gst_matroska_read_common_reset_streams (&demux->common,
4822 GST_CLOCK_TIME_NONE, TRUE);
4823 gst_flow_combiner_reset (demux->flowcombiner);
4824 dur = demux->common.segment.duration;
4825 gst_segment_init (&demux->common.segment, GST_FORMAT_TIME);
4826 demux->common.segment.duration = dur;
4827 demux->cluster_time = GST_CLOCK_TIME_NONE;
4828 demux->cluster_offset = 0;
4829 GST_OBJECT_UNLOCK (demux);
4833 res = gst_pad_event_default (pad, parent, event);
4841 gst_matroska_demux_sink_activate (GstPad * sinkpad, GstObject * parent)
4843 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4845 gboolean pull_mode = FALSE;
4847 query = gst_query_new_scheduling ();
4849 if (gst_pad_peer_query (sinkpad, query))
4850 pull_mode = gst_query_has_scheduling_mode_with_flags (query,
4851 GST_PAD_MODE_PULL, GST_SCHEDULING_FLAG_SEEKABLE);
4853 gst_query_unref (query);
4856 GST_DEBUG ("going to pull mode");
4857 demux->streaming = FALSE;
4858 return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PULL, TRUE);
4860 GST_DEBUG ("going to push (streaming) mode");
4861 demux->streaming = TRUE;
4862 return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PUSH, TRUE);
4867 gst_matroska_demux_sink_activate_mode (GstPad * sinkpad, GstObject * parent,
4868 GstPadMode mode, gboolean active)
4871 case GST_PAD_MODE_PULL:
4873 /* if we have a scheduler we can start the task */
4874 gst_pad_start_task (sinkpad, (GstTaskFunction) gst_matroska_demux_loop,
4877 gst_pad_stop_task (sinkpad);
4880 case GST_PAD_MODE_PUSH:
4888 gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext *
4889 videocontext, const gchar * codec_id, guint8 * data, guint size,
4890 gchar ** codec_name, guint32 * riff_fourcc)
4892 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) videocontext;
4893 GstCaps *caps = NULL;
4895 g_assert (videocontext != NULL);
4896 g_assert (codec_name != NULL);
4901 /* TODO: check if we have all codec types from matroska-ids.h
4902 * check if we have to do more special things with codec_private
4905 * GST_MATROSKA_CODEC_ID_VIDEO_QUICKTIME
4906 * GST_MATROSKA_CODEC_ID_VIDEO_SNOW
4909 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VFW_FOURCC)) {
4910 gst_riff_strf_vids *vids = NULL;
4913 GstBuffer *buf = NULL;
4915 vids = (gst_riff_strf_vids *) data;
4917 /* assure size is big enough */
4919 GST_WARNING ("Too small BITMAPINFOHEADER (%d bytes)", size);
4922 if (size < sizeof (gst_riff_strf_vids)) {
4923 vids = g_new (gst_riff_strf_vids, 1);
4924 memcpy (vids, data, size);
4927 context->dts_only = TRUE; /* VFW files only store DTS */
4929 /* little-endian -> byte-order */
4930 vids->size = GUINT32_FROM_LE (vids->size);
4931 vids->width = GUINT32_FROM_LE (vids->width);
4932 vids->height = GUINT32_FROM_LE (vids->height);
4933 vids->planes = GUINT16_FROM_LE (vids->planes);
4934 vids->bit_cnt = GUINT16_FROM_LE (vids->bit_cnt);
4935 vids->compression = GUINT32_FROM_LE (vids->compression);
4936 vids->image_size = GUINT32_FROM_LE (vids->image_size);
4937 vids->xpels_meter = GUINT32_FROM_LE (vids->xpels_meter);
4938 vids->ypels_meter = GUINT32_FROM_LE (vids->ypels_meter);
4939 vids->num_colors = GUINT32_FROM_LE (vids->num_colors);
4940 vids->imp_colors = GUINT32_FROM_LE (vids->imp_colors);
4942 if (size > sizeof (gst_riff_strf_vids)) { /* some extra_data */
4943 gsize offset = sizeof (gst_riff_strf_vids);
4946 gst_buffer_new_wrapped (g_memdup ((guint8 *) vids + offset,
4947 size - offset), size - offset);
4951 *riff_fourcc = vids->compression;
4953 caps = gst_riff_create_video_caps (vids->compression, NULL, vids,
4954 buf, NULL, codec_name);
4957 GST_WARNING ("Unhandled RIFF fourcc %" GST_FOURCC_FORMAT,
4958 GST_FOURCC_ARGS (vids->compression));
4960 static GstStaticCaps intra_caps = GST_STATIC_CAPS ("image/jpeg; "
4961 "video/x-raw; image/png; video/x-dv; video/x-huffyuv; video/x-ffv; "
4962 "video/x-compressed-yuv");
4963 context->intra_only =
4964 gst_caps_can_intersect (gst_static_caps_get (&intra_caps), caps);
4968 gst_buffer_unref (buf);
4970 if (vids != (gst_riff_strf_vids *) data)
4973 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_UNCOMPRESSED)) {
4975 GstVideoFormat format;
4977 gst_video_info_init (&info);
4978 switch (videocontext->fourcc) {
4979 case GST_MAKE_FOURCC ('I', '4', '2', '0'):
4980 format = GST_VIDEO_FORMAT_I420;
4982 case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
4983 format = GST_VIDEO_FORMAT_YUY2;
4985 case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
4986 format = GST_VIDEO_FORMAT_YV12;
4988 case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
4989 format = GST_VIDEO_FORMAT_UYVY;
4991 case GST_MAKE_FOURCC ('A', 'Y', 'U', 'V'):
4992 format = GST_VIDEO_FORMAT_AYUV;
4994 case GST_MAKE_FOURCC ('Y', '8', '0', '0'):
4995 case GST_MAKE_FOURCC ('Y', '8', ' ', ' '):
4996 format = GST_VIDEO_FORMAT_GRAY8;
4998 case GST_MAKE_FOURCC ('R', 'G', 'B', 24):
4999 format = GST_VIDEO_FORMAT_RGB;
5001 case GST_MAKE_FOURCC ('B', 'G', 'R', 24):
5002 format = GST_VIDEO_FORMAT_BGR;
5005 GST_DEBUG ("Unknown fourcc %" GST_FOURCC_FORMAT,
5006 GST_FOURCC_ARGS (videocontext->fourcc));
5010 context->intra_only = TRUE;
5012 gst_video_info_set_format (&info, format, videocontext->pixel_width,
5013 videocontext->pixel_height);
5014 caps = gst_video_info_to_caps (&info);
5015 *codec_name = gst_pb_utils_get_codec_description (caps);
5016 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_SP)) {
5017 caps = gst_caps_new_simple ("video/x-divx",
5018 "divxversion", G_TYPE_INT, 4, NULL);
5019 *codec_name = g_strdup ("MPEG-4 simple profile");
5020 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP) ||
5021 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AP)) {
5022 caps = gst_caps_new_simple ("video/mpeg",
5023 "mpegversion", G_TYPE_INT, 4,
5024 "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
5028 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
5029 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5030 gst_buffer_unref (priv);
5032 gst_codec_utils_mpeg4video_caps_set_level_and_profile (caps, data, size);
5034 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP))
5035 *codec_name = g_strdup ("MPEG-4 advanced simple profile");
5037 *codec_name = g_strdup ("MPEG-4 advanced profile");
5038 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MSMPEG4V3)) {
5040 caps = gst_caps_new_full (gst_structure_new ("video/x-divx",
5041 "divxversion", G_TYPE_INT, 3, NULL),
5042 gst_structure_new ("video/x-msmpeg",
5043 "msmpegversion", G_TYPE_INT, 43, NULL), NULL);
5045 caps = gst_caps_new_simple ("video/x-msmpeg",
5046 "msmpegversion", G_TYPE_INT, 43, NULL);
5047 *codec_name = g_strdup ("Microsoft MPEG-4 v.3");
5048 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1) ||
5049 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG2)) {
5052 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1))
5057 caps = gst_caps_new_simple ("video/mpeg",
5058 "systemstream", G_TYPE_BOOLEAN, FALSE,
5059 "mpegversion", G_TYPE_INT, mpegversion, NULL);
5060 *codec_name = g_strdup_printf ("MPEG-%d video", mpegversion);
5061 context->postprocess_frame = gst_matroska_demux_add_mpeg_seq_header;
5062 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MJPEG)) {
5063 caps = gst_caps_new_empty_simple ("image/jpeg");
5064 *codec_name = g_strdup ("Motion-JPEG");
5065 context->intra_only = TRUE;
5066 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AVC)) {
5067 caps = gst_caps_new_empty_simple ("video/x-h264");
5071 /* First byte is the version, second is the profile indication, and third
5072 * is the 5 contraint_set_flags and 3 reserved bits. Fourth byte is the
5073 * level indication. */
5074 gst_codec_utils_h264_caps_set_level_and_profile (caps, data + 1,
5077 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
5078 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5079 gst_buffer_unref (priv);
5081 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "avc",
5082 "alignment", G_TYPE_STRING, "au", NULL);
5084 GST_WARNING ("No codec data found, assuming output is byte-stream");
5085 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
5088 *codec_name = g_strdup ("H264");
5089 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEGH_HEVC)) {
5090 caps = gst_caps_new_empty_simple ("video/x-h265");
5094 gst_codec_utils_h265_caps_set_level_tier_and_profile (caps, data + 1,
5097 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
5098 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5099 gst_buffer_unref (priv);
5101 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "hvc1",
5102 "alignment", G_TYPE_STRING, "au", NULL);
5104 GST_WARNING ("No codec data found, assuming output is byte-stream");
5105 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
5108 *codec_name = g_strdup ("HEVC");
5109 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1)) ||
5110 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2)) ||
5111 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3)) ||
5112 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))) {
5113 gint rmversion = -1;
5115 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1))
5117 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2))
5119 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3))
5121 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))
5124 caps = gst_caps_new_simple ("video/x-pn-realvideo",
5125 "rmversion", G_TYPE_INT, rmversion, NULL);
5126 GST_DEBUG ("data:%p, size:0x%x", data, size);
5127 /* We need to extract the extradata ! */
5128 if (data && (size >= 0x22)) {
5133 subformat = GST_READ_UINT32_BE (data + 0x1a);
5134 rformat = GST_READ_UINT32_BE (data + 0x1e);
5137 gst_buffer_new_wrapped (g_memdup (data + 0x1a, size - 0x1a),
5139 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, "format",
5140 G_TYPE_INT, rformat, "subformat", G_TYPE_INT, subformat, NULL);
5141 gst_buffer_unref (priv);
5144 *codec_name = g_strdup_printf ("RealVideo %d.0", rmversion);
5145 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_THEORA)) {
5146 caps = gst_caps_new_empty_simple ("video/x-theora");
5147 context->stream_headers =
5148 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
5149 context->codec_priv_size);
5150 /* FIXME: mark stream as broken and skip if there are no stream headers */
5151 context->send_stream_headers = TRUE;
5152 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_DIRAC)) {
5153 caps = gst_caps_new_empty_simple ("video/x-dirac");
5154 *codec_name = g_strdup_printf ("Dirac");
5155 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8)) {
5156 caps = gst_caps_new_empty_simple ("video/x-vp8");
5157 *codec_name = g_strdup_printf ("On2 VP8");
5158 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP9)) {
5159 caps = gst_caps_new_empty_simple ("video/x-vp9");
5160 *codec_name = g_strdup_printf ("On2 VP9");
5162 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
5168 GstStructure *structure;
5170 for (i = 0; i < gst_caps_get_size (caps); i++) {
5171 structure = gst_caps_get_structure (caps, i);
5173 /* FIXME: use the real unit here! */
5174 GST_DEBUG ("video size %dx%d, target display size %dx%d (any unit)",
5175 videocontext->pixel_width,
5176 videocontext->pixel_height,
5177 videocontext->display_width, videocontext->display_height);
5179 /* pixel width and height are the w and h of the video in pixels */
5180 if (videocontext->pixel_width > 0 && videocontext->pixel_height > 0) {
5181 gint w = videocontext->pixel_width;
5182 gint h = videocontext->pixel_height;
5184 gst_structure_set (structure,
5185 "width", G_TYPE_INT, w, "height", G_TYPE_INT, h, NULL);
5188 if (videocontext->display_width > 0 || videocontext->display_height > 0) {
5191 if (videocontext->display_width <= 0)
5192 videocontext->display_width = videocontext->pixel_width;
5193 if (videocontext->display_height <= 0)
5194 videocontext->display_height = videocontext->pixel_height;
5196 /* calculate the pixel aspect ratio using the display and pixel w/h */
5197 n = videocontext->display_width * videocontext->pixel_height;
5198 d = videocontext->display_height * videocontext->pixel_width;
5199 GST_DEBUG ("setting PAR to %d/%d", n, d);
5200 gst_structure_set (structure, "pixel-aspect-ratio",
5202 videocontext->display_width * videocontext->pixel_height,
5203 videocontext->display_height * videocontext->pixel_width, NULL);
5206 if (videocontext->default_fps > 0.0) {
5209 gst_util_double_to_fraction (videocontext->default_fps, &fps_n, &fps_d);
5211 GST_DEBUG ("using default fps %d/%d", fps_n, fps_d);
5213 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION, fps_n,
5215 } else if (context->default_duration > 0) {
5218 gst_video_guess_framerate (context->default_duration, &fps_n, &fps_d);
5220 GST_INFO ("using default duration %" G_GUINT64_FORMAT
5221 " framerate %d/%d", context->default_duration, fps_n, fps_d);
5223 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
5224 fps_n, fps_d, NULL);
5226 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
5230 if (videocontext->parent.flags & GST_MATROSKA_VIDEOTRACK_INTERLACED)
5231 gst_structure_set (structure, "interlace-mode", G_TYPE_STRING,
5234 if (videocontext->multiview_mode != GST_VIDEO_MULTIVIEW_MODE_NONE) {
5235 if (gst_video_multiview_guess_half_aspect (videocontext->multiview_mode,
5236 videocontext->pixel_width, videocontext->pixel_height,
5237 videocontext->display_width * videocontext->pixel_height,
5238 videocontext->display_height * videocontext->pixel_width)) {
5239 videocontext->multiview_flags |= GST_VIDEO_MULTIVIEW_FLAGS_HALF_ASPECT;
5241 gst_caps_set_simple (caps,
5242 "multiview-mode", G_TYPE_STRING,
5243 gst_video_multiview_mode_to_caps_string
5244 (videocontext->multiview_mode), "multiview-flags",
5245 GST_TYPE_VIDEO_MULTIVIEW_FLAGSET, videocontext->multiview_flags,
5246 GST_FLAG_SET_MASK_EXACT, NULL);
5249 caps = gst_caps_simplify (caps);
5256 * Some AAC specific code... *sigh*
5257 * FIXME: maybe we should use '15' and code the sample rate explicitly
5258 * if the sample rate doesn't match the predefined rates exactly? (tpm)
5262 aac_rate_idx (gint rate)
5266 else if (75132 <= rate)
5268 else if (55426 <= rate)
5270 else if (46009 <= rate)
5272 else if (37566 <= rate)
5274 else if (27713 <= rate)
5276 else if (23004 <= rate)
5278 else if (18783 <= rate)
5280 else if (13856 <= rate)
5282 else if (11502 <= rate)
5284 else if (9391 <= rate)
5291 aac_profile_idx (const gchar * codec_id)
5295 if (strlen (codec_id) <= 12)
5297 else if (!strncmp (&codec_id[12], "MAIN", 4))
5299 else if (!strncmp (&codec_id[12], "LC", 2))
5301 else if (!strncmp (&codec_id[12], "SSR", 3))
5310 round_up_pow2 (guint n)
5321 #define AAC_SYNC_EXTENSION_TYPE 0x02b7
5324 gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext *
5325 audiocontext, const gchar * codec_id, guint8 * data, guint size,
5326 gchar ** codec_name, guint16 * riff_audio_fmt)
5328 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) audiocontext;
5329 GstCaps *caps = NULL;
5331 g_assert (audiocontext != NULL);
5332 g_assert (codec_name != NULL);
5335 *riff_audio_fmt = 0;
5337 /* TODO: check if we have all codec types from matroska-ids.h
5338 * check if we have to do more special things with codec_private
5339 * check if we need bitdepth in different places too
5340 * implement channel position magic
5342 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID9
5343 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID10
5344 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDMC
5345 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDM2
5348 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1) ||
5349 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2) ||
5350 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L3)) {
5353 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1))
5355 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2))
5360 caps = gst_caps_new_simple ("audio/mpeg",
5361 "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, layer, NULL);
5362 *codec_name = g_strdup_printf ("MPEG-1 layer %d", layer);
5363 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE) ||
5364 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_LE)) {
5367 GstAudioFormat format;
5369 sign = (audiocontext->bitdepth != 8);
5370 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE))
5371 endianness = G_BIG_ENDIAN;
5373 endianness = G_LITTLE_ENDIAN;
5375 format = gst_audio_format_build_integer (sign, endianness,
5376 audiocontext->bitdepth, audiocontext->bitdepth);
5378 /* FIXME: Channel mask and reordering */
5379 caps = gst_caps_new_simple ("audio/x-raw",
5380 "format", G_TYPE_STRING, gst_audio_format_to_string (format),
5381 "layout", G_TYPE_STRING, "interleaved", NULL);
5383 *codec_name = g_strdup_printf ("Raw %d-bit PCM audio",
5384 audiocontext->bitdepth);
5385 context->alignment = GST_ROUND_UP_8 (audiocontext->bitdepth) / 8;
5386 context->alignment = round_up_pow2 (context->alignment);
5387 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_FLOAT)) {
5388 const gchar *format;
5389 if (audiocontext->bitdepth == 32)
5393 /* FIXME: Channel mask and reordering */
5394 caps = gst_caps_new_simple ("audio/x-raw",
5395 "format", G_TYPE_STRING, format,
5396 "layout", G_TYPE_STRING, "interleaved", NULL);
5397 *codec_name = g_strdup_printf ("Raw %d-bit floating-point audio",
5398 audiocontext->bitdepth);
5399 context->alignment = audiocontext->bitdepth / 8;
5400 context->alignment = round_up_pow2 (context->alignment);
5401 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AC3,
5402 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AC3))) {
5403 caps = gst_caps_new_simple ("audio/x-ac3",
5404 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5405 *codec_name = g_strdup ("AC-3 audio");
5406 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_EAC3,
5407 strlen (GST_MATROSKA_CODEC_ID_AUDIO_EAC3))) {
5408 caps = gst_caps_new_simple ("audio/x-eac3",
5409 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5410 *codec_name = g_strdup ("E-AC-3 audio");
5411 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TRUEHD,
5412 strlen (GST_MATROSKA_CODEC_ID_AUDIO_TRUEHD))) {
5413 caps = gst_caps_new_empty_simple ("audio/x-true-hd");
5414 *codec_name = g_strdup ("Dolby TrueHD");
5415 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_DTS)) {
5416 caps = gst_caps_new_empty_simple ("audio/x-dts");
5417 *codec_name = g_strdup ("DTS audio");
5418 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_VORBIS)) {
5419 caps = gst_caps_new_empty_simple ("audio/x-vorbis");
5420 context->stream_headers =
5421 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
5422 context->codec_priv_size);
5423 /* FIXME: mark stream as broken and skip if there are no stream headers */
5424 context->send_stream_headers = TRUE;
5425 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_FLAC)) {
5426 caps = gst_caps_new_empty_simple ("audio/x-flac");
5427 context->stream_headers =
5428 gst_matroska_parse_flac_stream_headers (context->codec_priv,
5429 context->codec_priv_size);
5430 /* FIXME: mark stream as broken and skip if there are no stream headers */
5431 context->send_stream_headers = TRUE;
5432 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_SPEEX)) {
5433 caps = gst_caps_new_empty_simple ("audio/x-speex");
5434 context->stream_headers =
5435 gst_matroska_parse_speex_stream_headers (context->codec_priv,
5436 context->codec_priv_size);
5437 /* FIXME: mark stream as broken and skip if there are no stream headers */
5438 context->send_stream_headers = TRUE;
5439 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_OPUS)) {
5440 caps = gst_caps_new_empty_simple ("audio/x-opus");
5441 *codec_name = g_strdup ("Opus");
5442 context->stream_headers =
5443 gst_matroska_parse_opus_stream_headers (context->codec_priv,
5444 context->codec_priv_size);
5445 if (context->stream_headers) {
5446 /* There was a valid header. Multistream headers are more than
5447 * 19 bytes, as they include an extra channel mapping table. */
5448 gboolean multistream = (context->codec_priv_size > 19);
5449 gst_caps_set_simple (caps, "multistream", G_TYPE_BOOLEAN, multistream,
5452 /* FIXME: mark stream as broken and skip if there are no stream headers */
5453 context->send_stream_headers = TRUE;
5454 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_ACM)) {
5455 gst_riff_strf_auds auds;
5457 if (data && size >= 18) {
5458 GstBuffer *codec_data = NULL;
5460 /* little-endian -> byte-order */
5461 auds.format = GST_READ_UINT16_LE (data);
5462 auds.channels = GST_READ_UINT16_LE (data + 2);
5463 auds.rate = GST_READ_UINT32_LE (data + 4);
5464 auds.av_bps = GST_READ_UINT32_LE (data + 8);
5465 auds.blockalign = GST_READ_UINT16_LE (data + 12);
5466 auds.bits_per_sample = GST_READ_UINT16_LE (data + 16);
5468 /* 18 is the waveformatex size */
5470 codec_data = gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY,
5471 data + 18, size - 18, 0, size - 18, NULL, NULL);
5475 *riff_audio_fmt = auds.format;
5477 /* FIXME: Handle reorder map */
5478 caps = gst_riff_create_audio_caps (auds.format, NULL, &auds, NULL,
5479 codec_data, codec_name, NULL);
5481 gst_buffer_unref (codec_data);
5484 GST_WARNING ("Unhandled RIFF audio format 0x%02x", auds.format);
5487 GST_WARNING ("Invalid codec data size (%d expected, got %d)", 18, size);
5489 } else if (g_str_has_prefix (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC)) {
5490 GstBuffer *priv = NULL;
5492 gint rate_idx, profile;
5493 guint8 *data = NULL;
5495 /* unspecified AAC profile with opaque private codec data */
5496 if (strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC) == 0) {
5497 if (context->codec_priv_size >= 2) {
5498 guint obj_type, freq_index, explicit_freq_bytes = 0;
5500 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
5502 freq_index = (GST_READ_UINT16_BE (context->codec_priv) & 0x780) >> 7;
5503 obj_type = (GST_READ_UINT16_BE (context->codec_priv) & 0xF800) >> 11;
5504 if (freq_index == 15)
5505 explicit_freq_bytes = 3;
5506 GST_DEBUG ("obj_type = %u, freq_index = %u", obj_type, freq_index);
5507 priv = gst_buffer_new_wrapped (g_memdup (context->codec_priv,
5508 context->codec_priv_size), context->codec_priv_size);
5509 /* assume SBR if samplerate <= 24kHz */
5510 if (obj_type == 5 || (freq_index >= 6 && freq_index != 15) ||
5511 (context->codec_priv_size == (5 + explicit_freq_bytes))) {
5512 audiocontext->samplerate *= 2;
5515 GST_WARNING ("Opaque A_AAC codec ID, but no codec private data");
5516 /* this is pretty broken;
5517 * maybe we need to make up some default private,
5518 * or maybe ADTS data got dumped in.
5519 * Let's set up some private data now, and check actual data later */
5520 /* just try this and see what happens ... */
5521 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
5522 context->postprocess_frame = gst_matroska_demux_check_aac;
5526 /* make up decoder-specific data if it is not supplied */
5530 priv = gst_buffer_new_allocate (NULL, 5, NULL);
5531 gst_buffer_map (priv, &map, GST_MAP_WRITE);
5533 rate_idx = aac_rate_idx (audiocontext->samplerate);
5534 profile = aac_profile_idx (codec_id);
5536 data[0] = ((profile + 1) << 3) | ((rate_idx & 0xE) >> 1);
5537 data[1] = ((rate_idx & 0x1) << 7) | (audiocontext->channels << 3);
5539 if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2,
5540 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2))) {
5542 gst_buffer_unmap (priv, &map);
5543 gst_buffer_set_size (priv, 2);
5544 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4,
5545 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4))) {
5548 if (g_strrstr (codec_id, "SBR")) {
5549 /* HE-AAC (aka SBR AAC) */
5550 audiocontext->samplerate *= 2;
5551 rate_idx = aac_rate_idx (audiocontext->samplerate);
5552 data[2] = AAC_SYNC_EXTENSION_TYPE >> 3;
5553 data[3] = ((AAC_SYNC_EXTENSION_TYPE & 0x07) << 5) | 5;
5554 data[4] = (1 << 7) | (rate_idx << 3);
5555 gst_buffer_unmap (priv, &map);
5557 gst_buffer_unmap (priv, &map);
5558 gst_buffer_set_size (priv, 2);
5561 gst_buffer_unmap (priv, &map);
5562 gst_buffer_unref (priv);
5564 GST_ERROR ("Unknown AAC profile and no codec private data");
5569 caps = gst_caps_new_simple ("audio/mpeg",
5570 "mpegversion", G_TYPE_INT, mpegversion,
5571 "framed", G_TYPE_BOOLEAN, TRUE,
5572 "stream-format", G_TYPE_STRING, "raw", NULL);
5573 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5574 if (context->codec_priv && context->codec_priv_size > 0)
5575 gst_codec_utils_aac_caps_set_level_and_profile (caps,
5576 context->codec_priv, context->codec_priv_size);
5577 *codec_name = g_strdup_printf ("MPEG-%d AAC audio", mpegversion);
5578 gst_buffer_unref (priv);
5580 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TTA)) {
5581 caps = gst_caps_new_simple ("audio/x-tta",
5582 "width", G_TYPE_INT, audiocontext->bitdepth, NULL);
5583 *codec_name = g_strdup ("TTA audio");
5584 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_WAVPACK4)) {
5585 caps = gst_caps_new_simple ("audio/x-wavpack",
5586 "width", G_TYPE_INT, audiocontext->bitdepth,
5587 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5588 *codec_name = g_strdup ("Wavpack audio");
5589 context->postprocess_frame = gst_matroska_demux_add_wvpk_header;
5590 audiocontext->wvpk_block_index = 0;
5591 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4)) ||
5592 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_28_8)) ||
5593 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))) {
5594 gint raversion = -1;
5596 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4))
5598 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))
5603 caps = gst_caps_new_simple ("audio/x-pn-realaudio",
5604 "raversion", G_TYPE_INT, raversion, NULL);
5605 /* Extract extra information from caps, mapping varies based on codec */
5606 if (data && (size >= 0x50)) {
5613 guint extra_data_size;
5615 GST_ERROR ("real audio raversion:%d", raversion);
5616 if (raversion == 8) {
5618 flavor = GST_READ_UINT16_BE (data + 22);
5619 packet_size = GST_READ_UINT32_BE (data + 24);
5620 height = GST_READ_UINT16_BE (data + 40);
5621 leaf_size = GST_READ_UINT16_BE (data + 44);
5622 sample_width = GST_READ_UINT16_BE (data + 58);
5623 extra_data_size = GST_READ_UINT32_BE (data + 74);
5626 ("flavor:%d, packet_size:%d, height:%d, leaf_size:%d, sample_width:%d, extra_data_size:%d",
5627 flavor, packet_size, height, leaf_size, sample_width,
5629 gst_caps_set_simple (caps, "flavor", G_TYPE_INT, flavor, "packet_size",
5630 G_TYPE_INT, packet_size, "height", G_TYPE_INT, height, "leaf_size",
5631 G_TYPE_INT, leaf_size, "width", G_TYPE_INT, sample_width, NULL);
5633 if ((size - 78) >= extra_data_size) {
5634 priv = gst_buffer_new_wrapped (g_memdup (data + 78, extra_data_size),
5636 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5637 gst_buffer_unref (priv);
5642 *codec_name = g_strdup_printf ("RealAudio %d.0", raversion);
5643 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_SIPR)) {
5644 caps = gst_caps_new_empty_simple ("audio/x-sipro");
5645 *codec_name = g_strdup ("Sipro/ACELP.NET Voice Codec");
5646 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_RALF)) {
5647 caps = gst_caps_new_empty_simple ("audio/x-ralf-mpeg4-generic");
5648 *codec_name = g_strdup ("Real Audio Lossless");
5649 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_ATRC)) {
5650 caps = gst_caps_new_empty_simple ("audio/x-vnd.sony.atrac3");
5651 *codec_name = g_strdup ("Sony ATRAC3");
5653 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
5658 if (audiocontext->samplerate > 0 && audiocontext->channels > 0) {
5661 for (i = 0; i < gst_caps_get_size (caps); i++) {
5662 gst_structure_set (gst_caps_get_structure (caps, i),
5663 "channels", G_TYPE_INT, audiocontext->channels,
5664 "rate", G_TYPE_INT, audiocontext->samplerate, NULL);
5668 caps = gst_caps_simplify (caps);
5675 gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
5676 subtitlecontext, const gchar * codec_id, gpointer data, guint size)
5678 GstCaps *caps = NULL;
5679 GstMatroskaTrackContext *context =
5680 (GstMatroskaTrackContext *) subtitlecontext;
5682 /* for backwards compatibility */
5683 if (!g_ascii_strcasecmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASCII))
5684 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8;
5685 else if (!g_ascii_strcasecmp (codec_id, "S_SSA"))
5686 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_SSA;
5687 else if (!g_ascii_strcasecmp (codec_id, "S_ASS"))
5688 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_ASS;
5689 else if (!g_ascii_strcasecmp (codec_id, "S_USF"))
5690 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_USF;
5692 /* TODO: Add GST_MATROSKA_CODEC_ID_SUBTITLE_BMP support
5693 * Check if we have to do something with codec_private */
5694 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8)) {
5695 /* well, plain text simply does not have a lot of markup ... */
5696 caps = gst_caps_new_simple ("text/x-raw", "format", G_TYPE_STRING,
5697 "pango-markup", NULL);
5698 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5699 subtitlecontext->check_markup = TRUE;
5700 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_SSA)) {
5701 caps = gst_caps_new_empty_simple ("application/x-ssa");
5702 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5703 subtitlecontext->check_markup = FALSE;
5704 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASS)) {
5705 caps = gst_caps_new_empty_simple ("application/x-ass");
5706 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5707 subtitlecontext->check_markup = FALSE;
5708 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_USF)) {
5709 caps = gst_caps_new_empty_simple ("application/x-usf");
5710 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5711 subtitlecontext->check_markup = FALSE;
5712 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB)) {
5713 caps = gst_caps_new_empty_simple ("subpicture/x-dvd");
5714 ((GstMatroskaTrackContext *) subtitlecontext)->send_dvd_event = TRUE;
5715 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_HDMVPGS)) {
5716 caps = gst_caps_new_empty_simple ("subpicture/x-pgs");
5717 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_KATE)) {
5718 caps = gst_caps_new_empty_simple ("subtitle/x-kate");
5719 context->stream_headers =
5720 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
5721 context->codec_priv_size);
5722 /* FIXME: mark stream as broken and skip if there are no stream headers */
5723 context->send_stream_headers = TRUE;
5725 GST_DEBUG ("Unknown subtitle stream: codec_id='%s'", codec_id);
5726 caps = gst_caps_new_empty_simple ("application/x-subtitle-unknown");
5729 if (data != NULL && size > 0) {
5732 buf = gst_buffer_new_wrapped (g_memdup (data, size), size);
5733 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, buf, NULL);
5734 gst_buffer_unref (buf);
5742 gst_matroska_demux_set_index (GstElement * element, GstIndex * index)
5744 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5746 GST_OBJECT_LOCK (demux);
5747 if (demux->common.element_index)
5748 gst_object_unref (demux->common.element_index);
5749 demux->common.element_index = index ? gst_object_ref (index) : NULL;
5750 GST_OBJECT_UNLOCK (demux);
5751 GST_DEBUG_OBJECT (demux, "Set index %" GST_PTR_FORMAT,
5752 demux->common.element_index);
5756 gst_matroska_demux_get_index (GstElement * element)
5758 GstIndex *result = NULL;
5759 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5761 GST_OBJECT_LOCK (demux);
5762 if (demux->common.element_index)
5763 result = gst_object_ref (demux->common.element_index);
5764 GST_OBJECT_UNLOCK (demux);
5766 GST_DEBUG_OBJECT (demux, "Returning index %" GST_PTR_FORMAT, result);
5772 static GstStateChangeReturn
5773 gst_matroska_demux_change_state (GstElement * element,
5774 GstStateChange transition)
5776 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5777 GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
5779 /* handle upwards state changes here */
5780 switch (transition) {
5785 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
5787 /* handle downwards state changes */
5788 switch (transition) {
5789 case GST_STATE_CHANGE_PAUSED_TO_READY:
5790 gst_matroska_demux_reset (GST_ELEMENT (demux));
5800 gst_matroska_demux_set_property (GObject * object,
5801 guint prop_id, const GValue * value, GParamSpec * pspec)
5803 GstMatroskaDemux *demux;
5805 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
5806 demux = GST_MATROSKA_DEMUX (object);
5809 case PROP_MAX_GAP_TIME:
5810 GST_OBJECT_LOCK (demux);
5811 demux->max_gap_time = g_value_get_uint64 (value);
5812 GST_OBJECT_UNLOCK (demux);
5815 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
5821 gst_matroska_demux_get_property (GObject * object,
5822 guint prop_id, GValue * value, GParamSpec * pspec)
5824 GstMatroskaDemux *demux;
5826 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
5827 demux = GST_MATROSKA_DEMUX (object);
5830 case PROP_MAX_GAP_TIME:
5831 GST_OBJECT_LOCK (demux);
5832 g_value_set_uint64 (value, demux->max_gap_time);
5833 GST_OBJECT_UNLOCK (demux);
5836 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
5842 gst_matroska_demux_plugin_init (GstPlugin * plugin)
5846 /* parser helper separate debug */
5847 GST_DEBUG_CATEGORY_INIT (ebmlread_debug, "ebmlread",
5848 0, "EBML stream helper class");
5850 /* create an elementfactory for the matroska_demux element */
5851 if (!gst_element_register (plugin, "matroskademux",
5852 GST_RANK_PRIMARY, GST_TYPE_MATROSKA_DEMUX))