1 /* GStreamer Matroska muxer/demuxer
2 * (c) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
3 * (c) 2006 Tim-Philipp Müller <tim centricular net>
4 * (c) 2008 Sebastian Dröge <slomo@circular-chaos.org>
5 * (c) 2011 Debarshi Ray <rishi@gnu.org>
7 * matroska-demux.c: matroska file/stream demuxer
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Library General Public License for more details.
19 * You should have received a copy of the GNU Library General Public
20 * License along with this library; if not, write to the
21 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
22 * Boston, MA 02110-1301, USA.
25 /* TODO: check CRC32 if present
26 * TODO: there can be a segment after the first segment. Handle like
27 * chained oggs. Fixes #334082
28 * TODO: Test samples: http://www.matroska.org/samples/matrix/index.html
29 * http://samples.mplayerhq.hu/Matroska/
30 * TODO: check if demuxing is done correct for all codecs according to spec
31 * TODO: seeking with incomplete or without CUE
35 * SECTION:element-matroskademux
37 * matroskademux demuxes a Matroska file into the different contained streams.
40 * <title>Example launch line</title>
42 * gst-launch-1.0 -v filesrc location=/path/to/mkv ! matroskademux ! vorbisdec ! audioconvert ! audioresample ! autoaudiosink
43 * ]| This pipeline demuxes a Matroska file and outputs the contained Vorbis audio.
54 #include <glib/gprintf.h>
56 /* For AVI compatibility mode
57 and for fourcc stuff */
58 #include <gst/riff/riff-read.h>
59 #include <gst/riff/riff-ids.h>
60 #include <gst/riff/riff-media.h>
62 #include <gst/audio/audio.h>
63 #include <gst/tag/tag.h>
64 #include <gst/pbutils/pbutils.h>
65 #include <gst/video/video.h>
67 #include "matroska-demux.h"
68 #include "matroska-ids.h"
70 GST_DEBUG_CATEGORY_STATIC (matroskademux_debug);
71 #define GST_CAT_DEFAULT matroskademux_debug
73 #define DEBUG_ELEMENT_START(demux, ebml, element) \
74 GST_DEBUG_OBJECT (demux, "Parsing " element " element at offset %" \
75 G_GUINT64_FORMAT, gst_ebml_read_get_pos (ebml))
77 #define DEBUG_ELEMENT_STOP(demux, ebml, element, ret) \
78 GST_DEBUG_OBJECT (demux, "Parsing " element " element " \
79 " finished with '%s'", gst_flow_get_name (ret))
89 #define DEFAULT_MAX_GAP_TIME (2 * GST_SECOND)
91 static GstStaticPadTemplate sink_templ = GST_STATIC_PAD_TEMPLATE ("sink",
94 GST_STATIC_CAPS ("audio/x-matroska; video/x-matroska; "
95 "video/x-matroska-3d; audio/webm; video/webm")
98 /* TODO: fill in caps! */
100 static GstStaticPadTemplate audio_src_templ =
101 GST_STATIC_PAD_TEMPLATE ("audio_%u",
104 GST_STATIC_CAPS ("ANY")
107 static GstStaticPadTemplate video_src_templ =
108 GST_STATIC_PAD_TEMPLATE ("video_%u",
111 GST_STATIC_CAPS ("ANY")
114 static GstStaticPadTemplate subtitle_src_templ =
115 GST_STATIC_PAD_TEMPLATE ("subtitle_%u",
118 GST_STATIC_CAPS ("text/x-raw, format=pango-markup; application/x-ssa; "
119 "application/x-ass;application/x-usf; subpicture/x-dvd; "
120 "subpicture/x-pgs; subtitle/x-kate; " "application/x-subtitle-unknown")
123 static GstFlowReturn gst_matroska_demux_parse_id (GstMatroskaDemux * demux,
124 guint32 id, guint64 length, guint needed);
126 /* element functions */
127 static void gst_matroska_demux_loop (GstPad * pad);
129 static gboolean gst_matroska_demux_element_send_event (GstElement * element,
131 static gboolean gst_matroska_demux_element_query (GstElement * element,
135 static gboolean gst_matroska_demux_sink_activate (GstPad * sinkpad,
137 static gboolean gst_matroska_demux_sink_activate_mode (GstPad * sinkpad,
138 GstObject * parent, GstPadMode mode, gboolean active);
140 static gboolean gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
141 GstPad * pad, GstEvent * event);
142 static gboolean gst_matroska_demux_handle_src_event (GstPad * pad,
143 GstObject * parent, GstEvent * event);
144 static gboolean gst_matroska_demux_handle_src_query (GstPad * pad,
145 GstObject * parent, GstQuery * query);
147 static gboolean gst_matroska_demux_handle_sink_event (GstPad * pad,
148 GstObject * parent, GstEvent * event);
149 static GstFlowReturn gst_matroska_demux_chain (GstPad * pad,
150 GstObject * object, GstBuffer * buffer);
152 static GstStateChangeReturn
153 gst_matroska_demux_change_state (GstElement * element,
154 GstStateChange transition);
157 gst_matroska_demux_set_index (GstElement * element, GstIndex * index);
158 static GstIndex *gst_matroska_demux_get_index (GstElement * element);
162 static GstCaps *gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext
163 * videocontext, const gchar * codec_id, guint8 * data, guint size,
164 gchar ** codec_name, guint32 * riff_fourcc);
165 static GstCaps *gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext
166 * audiocontext, const gchar * codec_id, guint8 * data, guint size,
167 gchar ** codec_name, guint16 * riff_audio_fmt);
169 * gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
170 subtitlecontext, const gchar * codec_id, gpointer data, guint size);
173 static void gst_matroska_demux_reset (GstElement * element);
174 static gboolean perform_seek_to_offset (GstMatroskaDemux * demux,
175 gdouble rate, guint64 offset, guint32 seqnum);
177 /* gobject functions */
178 static void gst_matroska_demux_set_property (GObject * object,
179 guint prop_id, const GValue * value, GParamSpec * pspec);
180 static void gst_matroska_demux_get_property (GObject * object,
181 guint prop_id, GValue * value, GParamSpec * pspec);
183 GType gst_matroska_demux_get_type (void);
184 #define parent_class gst_matroska_demux_parent_class
185 G_DEFINE_TYPE (GstMatroskaDemux, gst_matroska_demux, GST_TYPE_ELEMENT);
188 gst_matroska_demux_finalize (GObject * object)
190 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (object);
192 gst_matroska_read_common_finalize (&demux->common);
193 gst_flow_combiner_free (demux->flowcombiner);
194 G_OBJECT_CLASS (parent_class)->finalize (object);
198 gst_matroska_demux_class_init (GstMatroskaDemuxClass * klass)
200 GObjectClass *gobject_class = (GObjectClass *) klass;
201 GstElementClass *gstelement_class = (GstElementClass *) klass;
203 GST_DEBUG_CATEGORY_INIT (matroskademux_debug, "matroskademux", 0,
206 gobject_class->finalize = gst_matroska_demux_finalize;
208 gobject_class->get_property = gst_matroska_demux_get_property;
209 gobject_class->set_property = gst_matroska_demux_set_property;
211 g_object_class_install_property (gobject_class, ARG_MAX_GAP_TIME,
212 g_param_spec_uint64 ("max-gap-time", "Maximum gap time",
213 "The demuxer sends out segment events for skipping "
214 "gaps longer than this (0 = disabled).", 0, G_MAXUINT64,
215 DEFAULT_MAX_GAP_TIME, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
217 gstelement_class->change_state =
218 GST_DEBUG_FUNCPTR (gst_matroska_demux_change_state);
219 gstelement_class->send_event =
220 GST_DEBUG_FUNCPTR (gst_matroska_demux_element_send_event);
221 gstelement_class->query =
222 GST_DEBUG_FUNCPTR (gst_matroska_demux_element_query);
224 gstelement_class->set_index =
225 GST_DEBUG_FUNCPTR (gst_matroska_demux_set_index);
226 gstelement_class->get_index =
227 GST_DEBUG_FUNCPTR (gst_matroska_demux_get_index);
230 gst_element_class_add_pad_template (gstelement_class,
231 gst_static_pad_template_get (&video_src_templ));
232 gst_element_class_add_pad_template (gstelement_class,
233 gst_static_pad_template_get (&audio_src_templ));
234 gst_element_class_add_pad_template (gstelement_class,
235 gst_static_pad_template_get (&subtitle_src_templ));
236 gst_element_class_add_pad_template (gstelement_class,
237 gst_static_pad_template_get (&sink_templ));
239 gst_element_class_set_static_metadata (gstelement_class, "Matroska demuxer",
241 "Demuxes Matroska/WebM streams into video/audio/subtitles",
242 "GStreamer maintainers <gstreamer-devel@lists.sourceforge.net>");
246 gst_matroska_demux_init (GstMatroskaDemux * demux)
248 demux->common.sinkpad = gst_pad_new_from_static_template (&sink_templ,
250 gst_pad_set_activate_function (demux->common.sinkpad,
251 GST_DEBUG_FUNCPTR (gst_matroska_demux_sink_activate));
252 gst_pad_set_activatemode_function (demux->common.sinkpad,
253 GST_DEBUG_FUNCPTR (gst_matroska_demux_sink_activate_mode));
254 gst_pad_set_chain_function (demux->common.sinkpad,
255 GST_DEBUG_FUNCPTR (gst_matroska_demux_chain));
256 gst_pad_set_event_function (demux->common.sinkpad,
257 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_sink_event));
258 gst_element_add_pad (GST_ELEMENT (demux), demux->common.sinkpad);
260 /* init defaults for common read context */
261 gst_matroska_read_common_init (&demux->common);
263 /* property defaults */
264 demux->max_gap_time = DEFAULT_MAX_GAP_TIME;
266 GST_OBJECT_FLAG_SET (demux, GST_ELEMENT_FLAG_INDEXABLE);
268 demux->flowcombiner = gst_flow_combiner_new ();
271 gst_matroska_demux_reset (GST_ELEMENT (demux));
275 gst_matroska_demux_reset (GstElement * element)
277 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
279 GST_DEBUG_OBJECT (demux, "Resetting state");
281 gst_matroska_read_common_reset (GST_ELEMENT (demux), &demux->common);
283 demux->num_a_streams = 0;
284 demux->num_t_streams = 0;
285 demux->num_v_streams = 0;
287 demux->have_group_id = FALSE;
288 demux->group_id = G_MAXUINT;
291 demux->tracks_parsed = FALSE;
293 if (demux->clusters) {
294 g_array_free (demux->clusters, TRUE);
295 demux->clusters = NULL;
298 g_list_foreach (demux->seek_parsed,
299 (GFunc) gst_matroska_read_common_free_parsed_el, NULL);
300 g_list_free (demux->seek_parsed);
301 demux->seek_parsed = NULL;
303 demux->last_stop_end = GST_CLOCK_TIME_NONE;
304 demux->seek_block = 0;
305 demux->stream_start_time = GST_CLOCK_TIME_NONE;
306 demux->to_time = GST_CLOCK_TIME_NONE;
307 demux->cluster_time = GST_CLOCK_TIME_NONE;
308 demux->cluster_offset = 0;
309 demux->next_cluster_offset = 0;
310 demux->index_offset = 0;
311 demux->seekable = FALSE;
312 demux->need_segment = FALSE;
313 demux->segment_seqnum = 0;
314 demux->requested_seek_time = GST_CLOCK_TIME_NONE;
315 demux->seek_offset = -1;
316 demux->building_index = FALSE;
317 if (demux->seek_event) {
318 gst_event_unref (demux->seek_event);
319 demux->seek_event = NULL;
322 demux->seek_index = NULL;
323 demux->seek_entry = 0;
325 if (demux->new_segment) {
326 gst_event_unref (demux->new_segment);
327 demux->new_segment = NULL;
330 demux->invalid_duration = FALSE;
332 demux->cached_length = G_MAXUINT64;
334 gst_flow_combiner_clear (demux->flowcombiner);
338 gst_matroska_decode_buffer (GstMatroskaTrackContext * context, GstBuffer * buf)
344 g_return_val_if_fail (GST_IS_BUFFER (buf), NULL);
346 GST_DEBUG ("decoding buffer %p", buf);
348 gst_buffer_map (buf, &map, GST_MAP_READ);
352 g_return_val_if_fail (size > 0, buf);
354 if (gst_matroska_decode_data (context->encodings, &data, &size,
355 GST_MATROSKA_TRACK_ENCODING_SCOPE_FRAME, FALSE)) {
356 gst_buffer_unmap (buf, &map);
357 gst_buffer_unref (buf);
358 return gst_buffer_new_wrapped (data, size);
360 GST_DEBUG ("decode data failed");
361 gst_buffer_unmap (buf, &map);
362 gst_buffer_unref (buf);
368 gst_matroska_demux_add_stream_headers_to_caps (GstMatroskaDemux * demux,
369 GstBufferList * list, GstCaps * caps)
372 GValue arr_val = G_VALUE_INIT;
373 GValue buf_val = G_VALUE_INIT;
376 g_assert (gst_caps_is_writable (caps));
378 g_value_init (&arr_val, GST_TYPE_ARRAY);
379 g_value_init (&buf_val, GST_TYPE_BUFFER);
381 num = gst_buffer_list_length (list);
382 for (i = 0; i < num; ++i) {
383 g_value_set_boxed (&buf_val, gst_buffer_list_get (list, i));
384 gst_value_array_append_value (&arr_val, &buf_val);
387 s = gst_caps_get_structure (caps, 0);
388 gst_structure_take_value (s, "streamheader", &arr_val);
389 g_value_unset (&buf_val);
393 gst_matroska_demux_add_stream (GstMatroskaDemux * demux, GstEbmlRead * ebml)
395 GstElementClass *klass = GST_ELEMENT_GET_CLASS (demux);
396 GstMatroskaTrackContext *context;
397 GstPadTemplate *templ = NULL;
398 GstStreamFlags stream_flags;
399 GstCaps *caps = NULL;
400 gchar *padname = NULL;
402 guint32 id, riff_fourcc = 0;
403 guint16 riff_audio_fmt = 0;
404 GstTagList *list = NULL;
405 GstEvent *stream_start;
409 DEBUG_ELEMENT_START (demux, ebml, "TrackEntry");
411 /* start with the master */
412 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
413 DEBUG_ELEMENT_STOP (demux, ebml, "TrackEntry", ret);
417 /* allocate generic... if we know the type, we'll g_renew()
418 * with the precise type */
419 context = g_new0 (GstMatroskaTrackContext, 1);
420 g_ptr_array_add (demux->common.src, context);
421 context->index = demux->common.num_streams;
422 context->index_writer_id = -1;
423 context->type = 0; /* no type yet */
424 context->default_duration = 0;
426 context->set_discont = TRUE;
427 context->timecodescale = 1.0;
429 GST_MATROSKA_TRACK_ENABLED | GST_MATROSKA_TRACK_DEFAULT |
430 GST_MATROSKA_TRACK_LACING;
431 context->from_time = GST_CLOCK_TIME_NONE;
432 context->from_offset = -1;
433 context->to_offset = G_MAXINT64;
434 context->alignment = 1;
435 context->dts_only = FALSE;
436 context->intra_only = FALSE;
437 demux->common.num_streams++;
438 g_assert (demux->common.src->len == demux->common.num_streams);
440 GST_DEBUG_OBJECT (demux, "Stream number %d", context->index);
442 /* try reading the trackentry headers */
443 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
444 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
448 /* track number (unique stream ID) */
449 case GST_MATROSKA_ID_TRACKNUMBER:{
452 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
456 GST_ERROR_OBJECT (demux, "Invalid TrackNumber 0");
457 ret = GST_FLOW_ERROR;
459 } else if (!gst_matroska_read_common_tracknumber_unique (&demux->common,
461 GST_ERROR_OBJECT (demux, "TrackNumber %" G_GUINT64_FORMAT
462 " is not unique", num);
463 ret = GST_FLOW_ERROR;
467 GST_DEBUG_OBJECT (demux, "TrackNumber: %" G_GUINT64_FORMAT, num);
471 /* track UID (unique identifier) */
472 case GST_MATROSKA_ID_TRACKUID:{
475 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
479 GST_ERROR_OBJECT (demux, "Invalid TrackUID 0");
480 ret = GST_FLOW_ERROR;
484 GST_DEBUG_OBJECT (demux, "TrackUID: %" G_GUINT64_FORMAT, num);
489 /* track type (video, audio, combined, subtitle, etc.) */
490 case GST_MATROSKA_ID_TRACKTYPE:{
493 if ((ret = gst_ebml_read_uint (ebml, &id, &track_type)) != GST_FLOW_OK) {
497 if (context->type != 0 && context->type != track_type) {
498 GST_WARNING_OBJECT (demux,
499 "More than one tracktype defined in a TrackEntry - skipping");
501 } else if (track_type < 1 || track_type > 254) {
502 GST_WARNING_OBJECT (demux, "Invalid TrackType %" G_GUINT64_FORMAT,
507 GST_DEBUG_OBJECT (demux, "TrackType: %" G_GUINT64_FORMAT, track_type);
509 /* ok, so we're actually going to reallocate this thing */
510 switch (track_type) {
511 case GST_MATROSKA_TRACK_TYPE_VIDEO:
512 gst_matroska_track_init_video_context (&context);
514 case GST_MATROSKA_TRACK_TYPE_AUDIO:
515 gst_matroska_track_init_audio_context (&context);
517 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
518 gst_matroska_track_init_subtitle_context (&context);
520 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
521 case GST_MATROSKA_TRACK_TYPE_LOGO:
522 case GST_MATROSKA_TRACK_TYPE_BUTTONS:
523 case GST_MATROSKA_TRACK_TYPE_CONTROL:
525 GST_WARNING_OBJECT (demux,
526 "Unknown or unsupported TrackType %" G_GUINT64_FORMAT,
531 g_ptr_array_index (demux->common.src, demux->common.num_streams - 1)
536 /* tracktype specific stuff for video */
537 case GST_MATROSKA_ID_TRACKVIDEO:{
538 GstMatroskaTrackVideoContext *videocontext;
540 DEBUG_ELEMENT_START (demux, ebml, "TrackVideo");
542 if (!gst_matroska_track_init_video_context (&context)) {
543 GST_WARNING_OBJECT (demux,
544 "TrackVideo element in non-video track - ignoring track");
545 ret = GST_FLOW_ERROR;
547 } else if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
550 videocontext = (GstMatroskaTrackVideoContext *) context;
551 g_ptr_array_index (demux->common.src, demux->common.num_streams - 1)
554 while (ret == GST_FLOW_OK &&
555 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
556 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
560 /* Should be one level up but some broken muxers write it here. */
561 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
564 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
568 GST_WARNING_OBJECT (demux, "Invalid TrackDefaultDuration 0");
572 GST_DEBUG_OBJECT (demux,
573 "TrackDefaultDuration: %" G_GUINT64_FORMAT, num);
574 context->default_duration = num;
578 /* video framerate */
579 /* NOTE: This one is here only for backward compatibility.
580 * Use _TRACKDEFAULDURATION one level up. */
581 case GST_MATROSKA_ID_VIDEOFRAMERATE:{
584 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
588 GST_WARNING_OBJECT (demux, "Invalid TrackVideoFPS %lf", num);
592 GST_DEBUG_OBJECT (demux, "TrackVideoFrameRate: %lf", num);
593 if (context->default_duration == 0)
594 context->default_duration =
595 gst_gdouble_to_guint64 ((gdouble) GST_SECOND * (1.0 / num));
596 videocontext->default_fps = num;
600 /* width of the size to display the video at */
601 case GST_MATROSKA_ID_VIDEODISPLAYWIDTH:{
604 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
608 GST_WARNING_OBJECT (demux, "Invalid TrackVideoDisplayWidth 0");
612 GST_DEBUG_OBJECT (demux,
613 "TrackVideoDisplayWidth: %" G_GUINT64_FORMAT, num);
614 videocontext->display_width = num;
618 /* height of the size to display the video at */
619 case GST_MATROSKA_ID_VIDEODISPLAYHEIGHT:{
622 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
626 GST_WARNING_OBJECT (demux, "Invalid TrackVideoDisplayHeight 0");
630 GST_DEBUG_OBJECT (demux,
631 "TrackVideoDisplayHeight: %" G_GUINT64_FORMAT, num);
632 videocontext->display_height = num;
636 /* width of the video in the file */
637 case GST_MATROSKA_ID_VIDEOPIXELWIDTH:{
640 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
644 GST_WARNING_OBJECT (demux, "Invalid TrackVideoPixelWidth 0");
648 GST_DEBUG_OBJECT (demux,
649 "TrackVideoPixelWidth: %" G_GUINT64_FORMAT, num);
650 videocontext->pixel_width = num;
654 /* height of the video in the file */
655 case GST_MATROSKA_ID_VIDEOPIXELHEIGHT:{
658 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
662 GST_WARNING_OBJECT (demux, "Invalid TrackVideoPixelHeight 0");
666 GST_DEBUG_OBJECT (demux,
667 "TrackVideoPixelHeight: %" G_GUINT64_FORMAT, num);
668 videocontext->pixel_height = num;
672 /* whether the video is interlaced */
673 case GST_MATROSKA_ID_VIDEOFLAGINTERLACED:{
676 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
680 context->flags |= GST_MATROSKA_VIDEOTRACK_INTERLACED;
682 context->flags &= ~GST_MATROSKA_VIDEOTRACK_INTERLACED;
683 GST_DEBUG_OBJECT (demux, "TrackVideoInterlaced: %d",
684 (context->flags & GST_MATROSKA_VIDEOTRACK_INTERLACED) ? 1 :
689 /* aspect ratio behaviour */
690 case GST_MATROSKA_ID_VIDEOASPECTRATIOTYPE:{
693 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
696 if (num != GST_MATROSKA_ASPECT_RATIO_MODE_FREE &&
697 num != GST_MATROSKA_ASPECT_RATIO_MODE_KEEP &&
698 num != GST_MATROSKA_ASPECT_RATIO_MODE_FIXED) {
699 GST_WARNING_OBJECT (demux,
700 "Unknown TrackVideoAspectRatioType 0x%x", (guint) num);
703 GST_DEBUG_OBJECT (demux,
704 "TrackVideoAspectRatioType: %" G_GUINT64_FORMAT, num);
705 videocontext->asr_mode = num;
709 /* colourspace (only matters for raw video) fourcc */
710 case GST_MATROSKA_ID_VIDEOCOLOURSPACE:{
715 gst_ebml_read_binary (ebml, &id, &data,
716 &datalen)) != GST_FLOW_OK)
721 GST_WARNING_OBJECT (demux,
722 "Invalid TrackVideoColourSpace length %" G_GUINT64_FORMAT,
727 memcpy (&videocontext->fourcc, data, 4);
728 GST_DEBUG_OBJECT (demux,
729 "TrackVideoColourSpace: %" GST_FOURCC_FORMAT,
730 GST_FOURCC_ARGS (videocontext->fourcc));
736 GST_WARNING_OBJECT (demux,
737 "Unknown TrackVideo subelement 0x%x - ignoring", id);
739 case GST_MATROSKA_ID_VIDEOSTEREOMODE:
740 case GST_MATROSKA_ID_VIDEODISPLAYUNIT:
741 case GST_MATROSKA_ID_VIDEOPIXELCROPBOTTOM:
742 case GST_MATROSKA_ID_VIDEOPIXELCROPTOP:
743 case GST_MATROSKA_ID_VIDEOPIXELCROPLEFT:
744 case GST_MATROSKA_ID_VIDEOPIXELCROPRIGHT:
745 case GST_MATROSKA_ID_VIDEOGAMMAVALUE:
746 ret = gst_ebml_read_skip (ebml);
751 DEBUG_ELEMENT_STOP (demux, ebml, "TrackVideo", ret);
755 /* tracktype specific stuff for audio */
756 case GST_MATROSKA_ID_TRACKAUDIO:{
757 GstMatroskaTrackAudioContext *audiocontext;
759 DEBUG_ELEMENT_START (demux, ebml, "TrackAudio");
761 if (!gst_matroska_track_init_audio_context (&context)) {
762 GST_WARNING_OBJECT (demux,
763 "TrackAudio element in non-audio track - ignoring track");
764 ret = GST_FLOW_ERROR;
768 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
771 audiocontext = (GstMatroskaTrackAudioContext *) context;
772 g_ptr_array_index (demux->common.src, demux->common.num_streams - 1)
775 while (ret == GST_FLOW_OK &&
776 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
777 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
782 case GST_MATROSKA_ID_AUDIOSAMPLINGFREQ:{
785 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
790 GST_WARNING_OBJECT (demux,
791 "Invalid TrackAudioSamplingFrequency %lf", num);
795 GST_DEBUG_OBJECT (demux, "TrackAudioSamplingFrequency: %lf", num);
796 audiocontext->samplerate = num;
801 case GST_MATROSKA_ID_AUDIOBITDEPTH:{
804 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
808 GST_WARNING_OBJECT (demux, "Invalid TrackAudioBitDepth 0");
812 GST_DEBUG_OBJECT (demux, "TrackAudioBitDepth: %" G_GUINT64_FORMAT,
814 audiocontext->bitdepth = num;
819 case GST_MATROSKA_ID_AUDIOCHANNELS:{
822 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
826 GST_WARNING_OBJECT (demux, "Invalid TrackAudioChannels 0");
830 GST_DEBUG_OBJECT (demux, "TrackAudioChannels: %" G_GUINT64_FORMAT,
832 audiocontext->channels = num;
837 GST_WARNING_OBJECT (demux,
838 "Unknown TrackAudio subelement 0x%x - ignoring", id);
840 case GST_MATROSKA_ID_AUDIOCHANNELPOSITIONS:
841 case GST_MATROSKA_ID_AUDIOOUTPUTSAMPLINGFREQ:
842 ret = gst_ebml_read_skip (ebml);
847 DEBUG_ELEMENT_STOP (demux, ebml, "TrackAudio", ret);
852 /* codec identifier */
853 case GST_MATROSKA_ID_CODECID:{
856 if ((ret = gst_ebml_read_ascii (ebml, &id, &text)) != GST_FLOW_OK)
859 GST_DEBUG_OBJECT (demux, "CodecID: %s", GST_STR_NULL (text));
860 context->codec_id = text;
864 /* codec private data */
865 case GST_MATROSKA_ID_CODECPRIVATE:{
870 gst_ebml_read_binary (ebml, &id, &data, &size)) != GST_FLOW_OK)
873 context->codec_priv = data;
874 context->codec_priv_size = size;
876 GST_DEBUG_OBJECT (demux, "CodecPrivate of size %" G_GUINT64_FORMAT,
881 /* name of the codec */
882 case GST_MATROSKA_ID_CODECNAME:{
885 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
888 GST_DEBUG_OBJECT (demux, "CodecName: %s", GST_STR_NULL (text));
889 context->codec_name = text;
893 /* name of this track */
894 case GST_MATROSKA_ID_TRACKNAME:{
897 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
900 context->name = text;
901 GST_DEBUG_OBJECT (demux, "TrackName: %s", GST_STR_NULL (text));
905 /* language (matters for audio/subtitles, mostly) */
906 case GST_MATROSKA_ID_TRACKLANGUAGE:{
909 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
913 context->language = text;
916 if (strlen (context->language) >= 4 && context->language[3] == '-')
917 context->language[3] = '\0';
919 GST_DEBUG_OBJECT (demux, "TrackLanguage: %s",
920 GST_STR_NULL (context->language));
924 /* whether this is actually used */
925 case GST_MATROSKA_ID_TRACKFLAGENABLED:{
928 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
932 context->flags |= GST_MATROSKA_TRACK_ENABLED;
934 context->flags &= ~GST_MATROSKA_TRACK_ENABLED;
936 GST_DEBUG_OBJECT (demux, "TrackEnabled: %d",
937 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
941 /* whether it's the default for this track type */
942 case GST_MATROSKA_ID_TRACKFLAGDEFAULT:{
945 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
949 context->flags |= GST_MATROSKA_TRACK_DEFAULT;
951 context->flags &= ~GST_MATROSKA_TRACK_DEFAULT;
953 GST_DEBUG_OBJECT (demux, "TrackDefault: %d",
954 (context->flags & GST_MATROSKA_TRACK_DEFAULT) ? 1 : 0);
958 /* whether the track must be used during playback */
959 case GST_MATROSKA_ID_TRACKFLAGFORCED:{
962 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
966 context->flags |= GST_MATROSKA_TRACK_FORCED;
968 context->flags &= ~GST_MATROSKA_TRACK_FORCED;
970 GST_DEBUG_OBJECT (demux, "TrackForced: %d",
971 (context->flags & GST_MATROSKA_TRACK_FORCED) ? 1 : 0);
975 /* lacing (like MPEG, where blocks don't end/start on frame
977 case GST_MATROSKA_ID_TRACKFLAGLACING:{
980 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
984 context->flags |= GST_MATROSKA_TRACK_LACING;
986 context->flags &= ~GST_MATROSKA_TRACK_LACING;
988 GST_DEBUG_OBJECT (demux, "TrackLacing: %d",
989 (context->flags & GST_MATROSKA_TRACK_LACING) ? 1 : 0);
993 /* default length (in time) of one data block in this track */
994 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
997 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1002 GST_WARNING_OBJECT (demux, "Invalid TrackDefaultDuration 0");
1006 GST_DEBUG_OBJECT (demux, "TrackDefaultDuration: %" G_GUINT64_FORMAT,
1008 context->default_duration = num;
1012 case GST_MATROSKA_ID_CONTENTENCODINGS:{
1013 ret = gst_matroska_read_common_read_track_encodings (&demux->common,
1018 case GST_MATROSKA_ID_TRACKTIMECODESCALE:{
1021 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
1025 GST_WARNING_OBJECT (demux, "Invalid TrackTimeCodeScale %lf", num);
1029 GST_DEBUG_OBJECT (demux, "TrackTimeCodeScale: %lf", num);
1030 context->timecodescale = num;
1035 GST_WARNING ("Unknown TrackEntry subelement 0x%x - ignoring", id);
1038 /* we ignore these because they're nothing useful (i.e. crap)
1039 * or simply not implemented yet. */
1040 case GST_MATROSKA_ID_TRACKMINCACHE:
1041 case GST_MATROSKA_ID_TRACKMAXCACHE:
1042 case GST_MATROSKA_ID_MAXBLOCKADDITIONID:
1043 case GST_MATROSKA_ID_TRACKATTACHMENTLINK:
1044 case GST_MATROSKA_ID_TRACKOVERLAY:
1045 case GST_MATROSKA_ID_TRACKTRANSLATE:
1046 case GST_MATROSKA_ID_TRACKOFFSET:
1047 case GST_MATROSKA_ID_CODECSETTINGS:
1048 case GST_MATROSKA_ID_CODECINFOURL:
1049 case GST_MATROSKA_ID_CODECDOWNLOADURL:
1050 case GST_MATROSKA_ID_CODECDECODEALL:
1051 ret = gst_ebml_read_skip (ebml);
1056 DEBUG_ELEMENT_STOP (demux, ebml, "TrackEntry", ret);
1058 /* Decode codec private data if necessary */
1059 if (context->encodings && context->encodings->len > 0 && context->codec_priv
1060 && context->codec_priv_size > 0) {
1061 if (!gst_matroska_decode_data (context->encodings,
1062 &context->codec_priv, &context->codec_priv_size,
1063 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
1064 GST_WARNING_OBJECT (demux, "Decoding codec private data failed");
1065 ret = GST_FLOW_ERROR;
1069 if (context->type == 0 || context->codec_id == NULL || (ret != GST_FLOW_OK
1070 && ret != GST_FLOW_EOS)) {
1071 if (ret == GST_FLOW_OK || ret == GST_FLOW_EOS)
1072 GST_WARNING_OBJECT (ebml, "Unknown stream/codec in track entry header");
1074 demux->common.num_streams--;
1075 g_ptr_array_remove_index (demux->common.src, demux->common.num_streams);
1076 g_assert (demux->common.src->len == demux->common.num_streams);
1078 gst_matroska_track_free (context);
1084 /* now create the GStreamer connectivity */
1085 switch (context->type) {
1086 case GST_MATROSKA_TRACK_TYPE_VIDEO:{
1087 GstMatroskaTrackVideoContext *videocontext =
1088 (GstMatroskaTrackVideoContext *) context;
1090 padname = g_strdup_printf ("video_%u", demux->num_v_streams++);
1091 templ = gst_element_class_get_pad_template (klass, "video_%u");
1092 caps = gst_matroska_demux_video_caps (videocontext,
1093 context->codec_id, context->codec_priv,
1094 context->codec_priv_size, &codec, &riff_fourcc);
1097 list = gst_tag_list_new (GST_TAG_VIDEO_CODEC, codec, NULL);
1103 case GST_MATROSKA_TRACK_TYPE_AUDIO:{
1104 GstMatroskaTrackAudioContext *audiocontext =
1105 (GstMatroskaTrackAudioContext *) context;
1107 padname = g_strdup_printf ("audio_%u", demux->num_a_streams++);
1108 templ = gst_element_class_get_pad_template (klass, "audio_%u");
1109 caps = gst_matroska_demux_audio_caps (audiocontext,
1110 context->codec_id, context->codec_priv, context->codec_priv_size,
1111 &codec, &riff_audio_fmt);
1114 list = gst_tag_list_new (GST_TAG_AUDIO_CODEC, codec, NULL);
1120 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:{
1121 GstMatroskaTrackSubtitleContext *subtitlecontext =
1122 (GstMatroskaTrackSubtitleContext *) context;
1124 padname = g_strdup_printf ("subtitle_%u", demux->num_t_streams++);
1125 templ = gst_element_class_get_pad_template (klass, "subtitle_%u");
1126 caps = gst_matroska_demux_subtitle_caps (subtitlecontext,
1127 context->codec_id, context->codec_priv, context->codec_priv_size);
1131 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1132 case GST_MATROSKA_TRACK_TYPE_LOGO:
1133 case GST_MATROSKA_TRACK_TYPE_BUTTONS:
1134 case GST_MATROSKA_TRACK_TYPE_CONTROL:
1136 /* we should already have quit by now */
1137 g_assert_not_reached ();
1140 if ((context->language == NULL || *context->language == '\0') &&
1141 (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO ||
1142 context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
1143 GST_LOG ("stream %d: language=eng (assuming default)", context->index);
1144 context->language = g_strdup ("eng");
1147 if (context->language) {
1151 list = gst_tag_list_new_empty ();
1153 /* Matroska contains ISO 639-2B codes, we want ISO 639-1 */
1154 lang = gst_tag_get_language_code (context->language);
1155 gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
1156 GST_TAG_LANGUAGE_CODE, (lang) ? lang : context->language, NULL);
1160 GST_WARNING_OBJECT (demux, "could not determine caps for stream with "
1161 "codec_id='%s'", context->codec_id);
1162 switch (context->type) {
1163 case GST_MATROSKA_TRACK_TYPE_VIDEO:
1164 caps = gst_caps_new_empty_simple ("video/x-unknown");
1166 case GST_MATROSKA_TRACK_TYPE_AUDIO:
1167 caps = gst_caps_new_empty_simple ("audio/x-unknown");
1169 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
1170 caps = gst_caps_new_empty_simple ("application/x-subtitle-unknown");
1172 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1174 caps = gst_caps_new_empty_simple ("application/x-matroska-unknown");
1177 gst_caps_set_simple (caps, "codec-id", G_TYPE_STRING, context->codec_id,
1180 /* add any unrecognised riff fourcc / audio format, but after codec-id */
1181 if (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO && riff_audio_fmt != 0)
1182 gst_caps_set_simple (caps, "format", G_TYPE_INT, riff_audio_fmt, NULL);
1183 else if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO && riff_fourcc != 0) {
1184 gchar *fstr = g_strdup_printf ("%" GST_FOURCC_FORMAT,
1185 GST_FOURCC_ARGS (riff_fourcc));
1186 gst_caps_set_simple (caps, "fourcc", G_TYPE_STRING, fstr, NULL);
1189 } else if (context->stream_headers != NULL) {
1190 gst_matroska_demux_add_stream_headers_to_caps (demux,
1191 context->stream_headers, caps);
1194 /* the pad in here */
1195 context->pad = gst_pad_new_from_template (templ, padname);
1196 context->caps = caps;
1198 gst_pad_set_event_function (context->pad,
1199 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_event));
1200 gst_pad_set_query_function (context->pad,
1201 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_query));
1203 GST_INFO_OBJECT (demux, "Adding pad '%s' with caps %" GST_PTR_FORMAT,
1206 context->pending_tags = list;
1208 gst_pad_set_element_private (context->pad, context);
1210 gst_pad_use_fixed_caps (context->pad);
1211 gst_pad_set_active (context->pad, TRUE);
1214 gst_pad_create_stream_id_printf (context->pad, GST_ELEMENT_CAST (demux),
1215 "%03" G_GUINT64_FORMAT, context->uid);
1217 gst_pad_get_sticky_event (demux->common.sinkpad, GST_EVENT_STREAM_START,
1220 if (gst_event_parse_group_id (stream_start, &demux->group_id))
1221 demux->have_group_id = TRUE;
1223 demux->have_group_id = FALSE;
1224 gst_event_unref (stream_start);
1225 } else if (!demux->have_group_id) {
1226 demux->have_group_id = TRUE;
1227 demux->group_id = gst_util_group_id_next ();
1230 stream_start = gst_event_new_stream_start (stream_id);
1232 if (demux->have_group_id)
1233 gst_event_set_group_id (stream_start, demux->group_id);
1234 stream_flags = GST_STREAM_FLAG_NONE;
1235 if (context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)
1236 stream_flags |= GST_STREAM_FLAG_SPARSE;
1237 if (context->flags & GST_MATROSKA_TRACK_DEFAULT)
1238 stream_flags |= GST_STREAM_FLAG_SELECT;
1239 gst_event_set_stream_flags (stream_start, stream_flags);
1240 gst_pad_push_event (context->pad, stream_start);
1241 gst_pad_set_caps (context->pad, context->caps);
1243 gst_element_add_pad (GST_ELEMENT (demux), context->pad);
1244 gst_flow_combiner_add_pad (demux->flowcombiner, context->pad);
1253 gst_matroska_demux_query (GstMatroskaDemux * demux, GstPad * pad,
1256 gboolean res = FALSE;
1257 GstMatroskaTrackContext *context = NULL;
1260 context = gst_pad_get_element_private (pad);
1263 switch (GST_QUERY_TYPE (query)) {
1264 case GST_QUERY_POSITION:
1268 gst_query_parse_position (query, &format, NULL);
1271 if (format == GST_FORMAT_TIME) {
1272 GST_OBJECT_LOCK (demux);
1274 gst_query_set_position (query, GST_FORMAT_TIME,
1275 MAX (context->pos, demux->stream_start_time) -
1276 demux->stream_start_time);
1278 gst_query_set_position (query, GST_FORMAT_TIME,
1279 MAX (demux->common.segment.position, demux->stream_start_time) -
1280 demux->stream_start_time);
1281 GST_OBJECT_UNLOCK (demux);
1282 } else if (format == GST_FORMAT_DEFAULT && context
1283 && context->default_duration) {
1284 GST_OBJECT_LOCK (demux);
1285 gst_query_set_position (query, GST_FORMAT_DEFAULT,
1286 context->pos / context->default_duration);
1287 GST_OBJECT_UNLOCK (demux);
1289 GST_DEBUG_OBJECT (demux,
1290 "only position query in TIME and DEFAULT format is supported");
1296 case GST_QUERY_DURATION:
1300 gst_query_parse_duration (query, &format, NULL);
1303 if (format == GST_FORMAT_TIME) {
1304 GST_OBJECT_LOCK (demux);
1305 gst_query_set_duration (query, GST_FORMAT_TIME,
1306 demux->common.segment.duration);
1307 GST_OBJECT_UNLOCK (demux);
1308 } else if (format == GST_FORMAT_DEFAULT && context
1309 && context->default_duration) {
1310 GST_OBJECT_LOCK (demux);
1311 gst_query_set_duration (query, GST_FORMAT_DEFAULT,
1312 demux->common.segment.duration / context->default_duration);
1313 GST_OBJECT_UNLOCK (demux);
1315 GST_DEBUG_OBJECT (demux,
1316 "only duration query in TIME and DEFAULT format is supported");
1322 case GST_QUERY_SEEKING:
1326 gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
1327 GST_OBJECT_LOCK (demux);
1328 if (fmt == GST_FORMAT_TIME) {
1331 if (demux->streaming) {
1332 /* assuming we'll be able to get an index ... */
1333 seekable = demux->seekable;
1338 gst_query_set_seeking (query, GST_FORMAT_TIME, seekable,
1339 0, demux->common.segment.duration);
1342 GST_OBJECT_UNLOCK (demux);
1345 case GST_QUERY_SEGMENT:
1350 format = demux->common.segment.format;
1353 gst_segment_to_stream_time (&demux->common.segment, format,
1354 demux->common.segment.start);
1355 if ((stop = demux->common.segment.stop) == -1)
1356 stop = demux->common.segment.duration;
1359 gst_segment_to_stream_time (&demux->common.segment, format, stop);
1361 gst_query_set_segment (query, demux->common.segment.rate, format, start,
1368 res = gst_pad_query_default (pad, (GstObject *) demux, query);
1371 GST_ELEMENT_CLASS (parent_class)->query (GST_ELEMENT_CAST (demux),
1380 gst_matroska_demux_element_query (GstElement * element, GstQuery * query)
1382 return gst_matroska_demux_query (GST_MATROSKA_DEMUX (element), NULL, query);
1386 gst_matroska_demux_handle_src_query (GstPad * pad, GstObject * parent,
1389 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
1391 return gst_matroska_demux_query (demux, pad, query);
1394 /* returns FALSE if there are no pads to deliver event to,
1395 * otherwise TRUE (whatever the outcome of event sending),
1396 * takes ownership of the passed event! */
1398 gst_matroska_demux_send_event (GstMatroskaDemux * demux, GstEvent * event)
1400 gboolean ret = FALSE;
1403 g_return_val_if_fail (event != NULL, FALSE);
1405 GST_DEBUG_OBJECT (demux, "Sending event of type %s to all source pads",
1406 GST_EVENT_TYPE_NAME (event));
1408 g_assert (demux->common.src->len == demux->common.num_streams);
1409 for (i = 0; i < demux->common.src->len; i++) {
1410 GstMatroskaTrackContext *stream;
1412 stream = g_ptr_array_index (demux->common.src, i);
1413 gst_event_ref (event);
1414 gst_pad_push_event (stream->pad, event);
1418 gst_event_unref (event);
1423 gst_matroska_demux_send_tags (GstMatroskaDemux * demux)
1427 if (G_UNLIKELY (demux->common.global_tags_changed)) {
1428 GstEvent *tag_event;
1429 gst_tag_list_add (demux->common.global_tags, GST_TAG_MERGE_REPLACE,
1430 GST_TAG_CONTAINER_FORMAT, "Matroska", NULL);
1431 GST_DEBUG_OBJECT (demux, "Sending global_tags %p : %" GST_PTR_FORMAT,
1432 demux->common.global_tags, demux->common.global_tags);
1435 gst_event_new_tag (gst_tag_list_copy (demux->common.global_tags));
1437 for (i = 0; i < demux->common.src->len; i++) {
1438 GstMatroskaTrackContext *stream;
1440 stream = g_ptr_array_index (demux->common.src, i);
1441 gst_pad_push_event (stream->pad, gst_event_ref (tag_event));
1444 gst_event_unref (tag_event);
1445 demux->common.global_tags_changed = FALSE;
1448 g_assert (demux->common.src->len == demux->common.num_streams);
1449 for (i = 0; i < demux->common.src->len; i++) {
1450 GstMatroskaTrackContext *stream;
1452 stream = g_ptr_array_index (demux->common.src, i);
1454 if (G_UNLIKELY (stream->pending_tags != NULL)) {
1455 GST_DEBUG_OBJECT (demux, "Sending pending_tags %p for pad %s:%s : %"
1456 GST_PTR_FORMAT, stream->pending_tags,
1457 GST_DEBUG_PAD_NAME (stream->pad), stream->pending_tags);
1458 gst_pad_push_event (stream->pad,
1459 gst_event_new_tag (stream->pending_tags));
1460 stream->pending_tags = NULL;
1466 gst_matroska_demux_element_send_event (GstElement * element, GstEvent * event)
1468 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
1471 g_return_val_if_fail (event != NULL, FALSE);
1473 if (GST_EVENT_TYPE (event) == GST_EVENT_SEEK) {
1474 res = gst_matroska_demux_handle_seek_event (demux, NULL, event);
1476 GST_WARNING_OBJECT (demux, "Unhandled event of type %s",
1477 GST_EVENT_TYPE_NAME (event));
1480 gst_event_unref (event);
1485 gst_matroska_demux_move_to_entry (GstMatroskaDemux * demux,
1486 GstMatroskaIndex * entry, gboolean reset, gboolean update)
1490 GST_OBJECT_LOCK (demux);
1493 /* seek (relative to matroska segment) */
1494 /* position might be invalid; will error when streaming resumes ... */
1495 demux->common.offset = entry->pos + demux->common.ebml_segment_start;
1496 demux->next_cluster_offset = 0;
1498 GST_DEBUG_OBJECT (demux,
1499 "Seeked to offset %" G_GUINT64_FORMAT ", block %d, " "time %"
1500 GST_TIME_FORMAT, entry->pos + demux->common.ebml_segment_start,
1501 entry->block, GST_TIME_ARGS (entry->time));
1503 /* update the time */
1504 gst_matroska_read_common_reset_streams (&demux->common, entry->time, TRUE);
1505 demux->common.segment.position = entry->time;
1506 demux->seek_block = entry->block;
1507 demux->seek_first = TRUE;
1508 demux->last_stop_end = GST_CLOCK_TIME_NONE;
1511 for (i = 0; i < demux->common.src->len; i++) {
1512 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
1515 stream->to_offset = G_MAXINT64;
1517 if (stream->from_offset != -1)
1518 stream->to_offset = stream->from_offset;
1520 stream->from_offset = -1;
1521 stream->from_time = GST_CLOCK_TIME_NONE;
1524 GST_OBJECT_UNLOCK (demux);
1530 gst_matroska_cluster_compare (gint64 * i1, gint64 * i2)
1540 /* searches for a cluster start from @pos,
1541 * return GST_FLOW_OK and cluster position in @pos if found */
1542 static GstFlowReturn
1543 gst_matroska_demux_search_cluster (GstMatroskaDemux * demux, gint64 * pos)
1545 gint64 newpos = *pos;
1547 GstFlowReturn ret = GST_FLOW_OK;
1548 const guint chunk = 64 * 1024;
1549 GstBuffer *buf = NULL;
1551 gpointer data = NULL;
1556 gint64 oldpos, oldlength;
1558 orig_offset = demux->common.offset;
1560 GST_LOG_OBJECT (demux, "searching cluster following offset %" G_GINT64_FORMAT,
1563 if (demux->clusters) {
1566 cpos = gst_util_array_binary_search (demux->clusters->data,
1567 demux->clusters->len, sizeof (gint64),
1568 (GCompareDataFunc) gst_matroska_cluster_compare,
1569 GST_SEARCH_MODE_AFTER, pos, NULL);
1572 GST_DEBUG_OBJECT (demux,
1573 "cluster reported at offset %" G_GINT64_FORMAT, *cpos);
1574 demux->common.offset = *cpos;
1575 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1576 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1577 if (ret == GST_FLOW_OK && id == GST_MATROSKA_ID_CLUSTER) {
1584 /* read in at newpos and scan for ebml cluster id */
1585 oldpos = oldlength = -1;
1587 GstByteReader reader;
1591 gst_buffer_unmap (buf, &map);
1592 gst_buffer_unref (buf);
1595 ret = gst_pad_pull_range (demux->common.sinkpad, newpos, chunk, &buf);
1596 if (ret != GST_FLOW_OK)
1598 GST_DEBUG_OBJECT (demux,
1599 "read buffer size %" G_GSIZE_FORMAT " at offset %" G_GINT64_FORMAT,
1600 gst_buffer_get_size (buf), newpos);
1601 gst_buffer_map (buf, &map, GST_MAP_READ);
1604 if (oldpos == newpos && oldlength == map.size) {
1605 GST_ERROR_OBJECT (demux, "Stuck at same position");
1606 ret = GST_FLOW_ERROR;
1610 oldlength = map.size;
1613 gst_byte_reader_init (&reader, data, size);
1615 cluster_pos = gst_byte_reader_masked_scan_uint32 (&reader, 0xffffffff,
1616 GST_MATROSKA_ID_CLUSTER, 0, gst_byte_reader_get_remaining (&reader));
1617 if (cluster_pos >= 0) {
1618 newpos += cluster_pos;
1619 /* prepare resuming at next byte */
1620 if (!gst_byte_reader_skip (&reader, cluster_pos + 1)) {
1621 GST_DEBUG_OBJECT (demux, "Need more data -> continue");
1624 GST_DEBUG_OBJECT (demux,
1625 "found cluster ebml id at offset %" G_GINT64_FORMAT, newpos);
1626 /* extra checks whether we really sync'ed to a cluster:
1627 * - either it is the first and only cluster
1628 * - either there is a cluster after this one
1629 * - either cluster length is undefined
1631 /* ok if first cluster (there may not a subsequent one) */
1632 if (newpos == demux->first_cluster_offset) {
1633 GST_DEBUG_OBJECT (demux, "cluster is first cluster -> OK");
1636 demux->common.offset = newpos;
1637 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1638 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1639 if (ret != GST_FLOW_OK) {
1640 GST_DEBUG_OBJECT (demux, "need more data -> continue");
1643 g_assert (id == GST_MATROSKA_ID_CLUSTER);
1644 GST_DEBUG_OBJECT (demux, "cluster size %" G_GUINT64_FORMAT ", prefix %d",
1646 /* ok if undefined length or first cluster */
1647 if (length == GST_EBML_SIZE_UNKNOWN || length == G_MAXUINT64) {
1648 GST_DEBUG_OBJECT (demux, "cluster has undefined length -> OK");
1652 demux->common.offset += length + needed;
1653 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1654 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1655 if (ret != GST_FLOW_OK)
1657 GST_DEBUG_OBJECT (demux, "next element is %scluster",
1658 id == GST_MATROSKA_ID_CLUSTER ? "" : "not ");
1659 if (id == GST_MATROSKA_ID_CLUSTER)
1661 /* not ok, resume */
1664 /* partial cluster id may have been in tail of buffer */
1665 newpos += MAX (gst_byte_reader_get_remaining (&reader), 4) - 3;
1670 gst_buffer_unmap (buf, &map);
1671 gst_buffer_unref (buf);
1676 demux->common.offset = orig_offset;
1681 /* bisect and scan through file for cluster starting before @time,
1682 * returns fake index entry with corresponding info on cluster */
1683 static GstMatroskaIndex *
1684 gst_matroska_demux_search_pos (GstMatroskaDemux * demux, GstClockTime time)
1686 GstMatroskaIndex *entry = NULL;
1687 GstMatroskaReadState current_state;
1688 GstClockTime otime, prev_cluster_time, current_cluster_time, cluster_time;
1689 gint64 opos, newpos, startpos = 0, current_offset;
1690 gint64 prev_cluster_offset = -1, current_cluster_offset, cluster_offset;
1691 const guint chunk = 64 * 1024;
1697 /* (under)estimate new position, resync using cluster ebml id,
1698 * and scan forward to appropriate cluster
1699 * (and re-estimate if need to go backward) */
1701 prev_cluster_time = GST_CLOCK_TIME_NONE;
1703 /* store some current state */
1704 current_state = demux->common.state;
1705 g_return_val_if_fail (current_state == GST_MATROSKA_READ_STATE_DATA, NULL);
1707 current_cluster_offset = demux->cluster_offset;
1708 current_cluster_time = demux->cluster_time;
1709 current_offset = demux->common.offset;
1711 demux->common.state = GST_MATROSKA_READ_STATE_SCANNING;
1713 /* estimate using start and current position */
1714 GST_OBJECT_LOCK (demux);
1715 opos = demux->common.offset - demux->common.ebml_segment_start;
1716 otime = demux->common.segment.position;
1717 GST_OBJECT_UNLOCK (demux);
1720 time = MAX (time, demux->stream_start_time);
1722 /* avoid division by zero in first estimation below */
1723 if (otime <= demux->stream_start_time)
1727 GST_LOG_OBJECT (demux,
1728 "opos: %" G_GUINT64_FORMAT ", otime: %" GST_TIME_FORMAT ", %"
1729 GST_TIME_FORMAT " in stream time (start %" GST_TIME_FORMAT "), time %"
1730 GST_TIME_FORMAT, opos, GST_TIME_ARGS (otime),
1731 GST_TIME_ARGS (otime - demux->stream_start_time),
1732 GST_TIME_ARGS (demux->stream_start_time), GST_TIME_ARGS (time));
1734 if (otime <= demux->stream_start_time) {
1738 gst_util_uint64_scale (opos - demux->common.ebml_segment_start,
1739 time - demux->stream_start_time,
1740 otime - demux->stream_start_time) - chunk;
1744 /* favour undershoot */
1745 newpos = newpos * 90 / 100;
1746 newpos += demux->common.ebml_segment_start;
1748 GST_DEBUG_OBJECT (demux,
1749 "estimated offset for %" GST_TIME_FORMAT ": %" G_GINT64_FORMAT,
1750 GST_TIME_ARGS (time), newpos);
1752 /* and at least start scanning before previous scan start to avoid looping */
1753 startpos = startpos * 90 / 100;
1754 if (startpos && startpos < newpos)
1757 /* read in at newpos and scan for ebml cluster id */
1761 ret = gst_matroska_demux_search_cluster (demux, &newpos);
1762 if (ret == GST_FLOW_EOS) {
1763 /* heuristic HACK */
1764 newpos = startpos * 80 / 100;
1765 GST_DEBUG_OBJECT (demux, "EOS; "
1766 "new estimated offset for %" GST_TIME_FORMAT ": %" G_GINT64_FORMAT,
1767 GST_TIME_ARGS (time), newpos);
1770 } else if (ret != GST_FLOW_OK) {
1777 /* then start scanning and parsing for cluster time,
1778 * re-estimate if overshoot, otherwise next cluster and so on */
1779 demux->common.offset = newpos;
1780 demux->cluster_time = cluster_time = GST_CLOCK_TIME_NONE;
1782 guint64 cluster_size = 0;
1784 /* peek and parse some elements */
1785 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1786 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1787 if (ret != GST_FLOW_OK)
1789 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
1790 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
1792 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
1793 if (ret != GST_FLOW_OK)
1796 if (id == GST_MATROSKA_ID_CLUSTER) {
1797 cluster_time = GST_CLOCK_TIME_NONE;
1798 if (length == G_MAXUINT64)
1801 cluster_size = length + needed;
1803 if (demux->cluster_time != GST_CLOCK_TIME_NONE &&
1804 cluster_time == GST_CLOCK_TIME_NONE) {
1805 cluster_time = demux->cluster_time * demux->common.time_scale;
1806 cluster_offset = demux->cluster_offset;
1807 GST_DEBUG_OBJECT (demux, "found cluster at offset %" G_GINT64_FORMAT
1808 " with time %" GST_TIME_FORMAT, cluster_offset,
1809 GST_TIME_ARGS (cluster_time));
1810 if (cluster_time > time) {
1811 GST_DEBUG_OBJECT (demux, "overshot target");
1812 /* cluster overshoots */
1813 if (cluster_offset == demux->first_cluster_offset) {
1814 /* but no prev one */
1815 GST_DEBUG_OBJECT (demux, "but using first cluster anyway");
1816 prev_cluster_time = cluster_time;
1817 prev_cluster_offset = cluster_offset;
1820 if (prev_cluster_time != GST_CLOCK_TIME_NONE) {
1821 /* prev cluster did not overshoot, so prev cluster is target */
1824 /* re-estimate using this new position info */
1825 opos = cluster_offset;
1826 otime = cluster_time;
1830 /* cluster undershoots, goto next one */
1831 prev_cluster_time = cluster_time;
1832 prev_cluster_offset = cluster_offset;
1833 /* skip cluster if length is defined,
1834 * otherwise will be skippingly parsed into */
1836 GST_DEBUG_OBJECT (demux, "skipping to next cluster");
1837 demux->common.offset = cluster_offset + cluster_size;
1838 demux->cluster_time = GST_CLOCK_TIME_NONE;
1840 GST_DEBUG_OBJECT (demux, "parsing/skipping cluster elements");
1847 if (ret == GST_FLOW_EOS) {
1848 if (prev_cluster_time != GST_CLOCK_TIME_NONE)
1854 entry = g_new0 (GstMatroskaIndex, 1);
1855 entry->time = prev_cluster_time;
1856 entry->pos = prev_cluster_offset - demux->common.ebml_segment_start;
1857 GST_DEBUG_OBJECT (demux, "simulated index entry; time %" GST_TIME_FORMAT
1858 ", pos %" G_GUINT64_FORMAT, GST_TIME_ARGS (entry->time), entry->pos);
1862 /* restore some state */
1863 demux->cluster_offset = current_cluster_offset;
1864 demux->cluster_time = current_cluster_time;
1865 demux->common.offset = current_offset;
1866 demux->common.state = current_state;
1872 gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
1873 GstPad * pad, GstEvent * event)
1875 GstMatroskaIndex *entry = NULL;
1876 GstMatroskaIndex scan_entry;
1878 GstSeekType cur_type, stop_type;
1880 gboolean flush, keyunit, before, after, snap_next;
1883 GstMatroskaTrackContext *track = NULL;
1884 GstSegment seeksegment = { 0, };
1885 gboolean update = TRUE;
1886 gboolean pad_locked = FALSE;
1888 GstSearchMode snap_dir;
1890 g_return_val_if_fail (event != NULL, FALSE);
1893 track = gst_pad_get_element_private (pad);
1895 GST_DEBUG_OBJECT (demux, "Have seek %" GST_PTR_FORMAT, event);
1897 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
1899 seqnum = gst_event_get_seqnum (event);
1901 /* we can only seek on time */
1902 if (format != GST_FORMAT_TIME) {
1903 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
1907 /* copy segment, we need this because we still need the old
1908 * segment when we close the current segment. */
1909 memcpy (&seeksegment, &demux->common.segment, sizeof (GstSegment));
1911 /* pull mode without index means that the actual duration is not known,
1912 * we might be playing a file that's still being recorded
1913 * so, invalidate our current duration, which is only a moving target,
1914 * and should not be used to clamp anything */
1915 if (!demux->streaming && !demux->common.index && demux->invalid_duration) {
1916 seeksegment.duration = GST_CLOCK_TIME_NONE;
1919 GST_DEBUG_OBJECT (demux, "configuring seek");
1920 /* Subtract stream_start_time so we always seek on a segment
1922 if (GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
1923 seeksegment.start -= demux->stream_start_time;
1924 seeksegment.position -= demux->stream_start_time;
1925 if (GST_CLOCK_TIME_IS_VALID (seeksegment.stop))
1926 seeksegment.stop -= demux->stream_start_time;
1928 seeksegment.stop = seeksegment.duration;
1931 gst_segment_do_seek (&seeksegment, rate, format, flags,
1932 cur_type, cur, stop_type, stop, &update);
1934 /* Restore the clip timestamp offset */
1935 if (GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
1936 seeksegment.position += demux->stream_start_time;
1937 seeksegment.start += demux->stream_start_time;
1938 if (!GST_CLOCK_TIME_IS_VALID (seeksegment.stop))
1939 seeksegment.stop = seeksegment.duration;
1940 if (GST_CLOCK_TIME_IS_VALID (seeksegment.stop))
1941 seeksegment.stop += demux->stream_start_time;
1944 /* restore segment duration (if any effect),
1945 * would be determined again when parsing, but anyway ... */
1946 seeksegment.duration = demux->common.segment.duration;
1948 flush = ! !(flags & GST_SEEK_FLAG_FLUSH);
1949 keyunit = ! !(flags & GST_SEEK_FLAG_KEY_UNIT);
1950 after = ! !(flags & GST_SEEK_FLAG_SNAP_AFTER);
1951 before = ! !(flags & GST_SEEK_FLAG_SNAP_BEFORE);
1953 /* always do full update if flushing,
1954 * otherwise problems might arise downstream with missing keyframes etc */
1955 update = update || flush;
1957 GST_DEBUG_OBJECT (demux, "New segment %" GST_SEGMENT_FORMAT, &seeksegment);
1959 /* check sanity before we start flushing and all that */
1960 snap_next = after && !before;
1961 if (seeksegment.rate < 0)
1962 snap_dir = snap_next ? GST_SEARCH_MODE_BEFORE : GST_SEARCH_MODE_AFTER;
1964 snap_dir = snap_next ? GST_SEARCH_MODE_AFTER : GST_SEARCH_MODE_BEFORE;
1966 GST_OBJECT_LOCK (demux);
1967 track = gst_matroska_read_common_get_seek_track (&demux->common, track);
1968 if ((entry = gst_matroska_read_common_do_index_seek (&demux->common, track,
1969 seeksegment.position, &demux->seek_index, &demux->seek_entry,
1970 snap_dir)) == NULL) {
1971 /* pull mode without index can scan later on */
1972 if (demux->streaming) {
1973 GST_DEBUG_OBJECT (demux, "No matching seek entry in index");
1974 GST_OBJECT_UNLOCK (demux);
1976 } else if (rate < 0.0) {
1977 /* FIXME: We should build an index during playback or when scanning
1978 * that can be used here. The reverse playback code requires seek_index
1979 * and seek_entry to be set!
1981 GST_DEBUG_OBJECT (demux,
1982 "No matching seek entry in index, needed for reverse playback");
1983 GST_OBJECT_UNLOCK (demux);
1987 GST_DEBUG_OBJECT (demux, "Seek position looks sane");
1988 GST_OBJECT_UNLOCK (demux);
1991 /* only have to update some segment,
1992 * but also still have to honour flush and so on */
1993 GST_DEBUG_OBJECT (demux, "... no update");
1994 /* bad goto, bad ... */
1998 if (demux->streaming)
2003 GstEvent *flush_event = gst_event_new_flush_start ();
2004 gst_event_set_seqnum (flush_event, seqnum);
2005 GST_DEBUG_OBJECT (demux, "Starting flush");
2006 gst_pad_push_event (demux->common.sinkpad, gst_event_ref (flush_event));
2007 gst_matroska_demux_send_event (demux, flush_event);
2009 GST_DEBUG_OBJECT (demux, "Non-flushing seek, pausing task");
2010 gst_pad_pause_task (demux->common.sinkpad);
2014 GST_PAD_STREAM_LOCK (demux->common.sinkpad);
2019 /* now grab the stream lock so that streaming cannot continue, for
2020 * non flushing seeks when the element is in PAUSED this could block
2022 GST_DEBUG_OBJECT (demux, "Waiting for streaming to stop");
2023 GST_PAD_STREAM_LOCK (demux->common.sinkpad);
2026 /* pull mode without index can do some scanning */
2027 if (!demux->streaming && !entry) {
2028 GstEvent *flush_event;
2030 /* need to stop flushing upstream as we need it next */
2032 flush_event = gst_event_new_flush_stop (TRUE);
2033 gst_event_set_seqnum (flush_event, seqnum);
2034 gst_pad_push_event (demux->common.sinkpad, flush_event);
2036 entry = gst_matroska_demux_search_pos (demux, seeksegment.position);
2037 /* keep local copy */
2039 scan_entry = *entry;
2041 entry = &scan_entry;
2043 GST_DEBUG_OBJECT (demux, "Scan failed to find matching position");
2045 flush_event = gst_event_new_flush_stop (TRUE);
2046 gst_event_set_seqnum (flush_event, seqnum);
2047 gst_matroska_demux_send_event (demux, flush_event);
2055 GST_DEBUG_OBJECT (demux, "seek to key unit, adjusting segment start from %"
2056 GST_TIME_FORMAT " to %" GST_TIME_FORMAT,
2057 GST_TIME_ARGS (seeksegment.start), GST_TIME_ARGS (entry->time));
2058 seeksegment.start = MAX (entry->time, demux->stream_start_time);
2059 seeksegment.position = seeksegment.start;
2060 seeksegment.time = seeksegment.start - demux->stream_start_time;
2063 if (demux->streaming) {
2064 GST_OBJECT_LOCK (demux);
2065 /* track real position we should start at */
2066 GST_DEBUG_OBJECT (demux, "storing segment start");
2067 demux->requested_seek_time = seeksegment.position;
2068 demux->seek_offset = entry->pos + demux->common.ebml_segment_start;
2069 GST_OBJECT_UNLOCK (demux);
2070 /* need to seek to cluster start to pick up cluster time */
2071 /* upstream takes care of flushing and all that
2072 * ... and newsegment event handling takes care of the rest */
2073 return perform_seek_to_offset (demux, rate,
2074 entry->pos + demux->common.ebml_segment_start, seqnum);
2079 GstEvent *flush_event = gst_event_new_flush_stop (TRUE);
2080 gst_event_set_seqnum (flush_event, seqnum);
2081 GST_DEBUG_OBJECT (demux, "Stopping flush");
2082 gst_pad_push_event (demux->common.sinkpad, gst_event_ref (flush_event));
2083 gst_matroska_demux_send_event (demux, flush_event);
2086 GST_OBJECT_LOCK (demux);
2087 /* now update the real segment info */
2088 GST_DEBUG_OBJECT (demux, "Committing new seek segment");
2089 memcpy (&demux->common.segment, &seeksegment, sizeof (GstSegment));
2090 GST_OBJECT_UNLOCK (demux);
2092 /* update some (segment) state */
2093 if (!gst_matroska_demux_move_to_entry (demux, entry, TRUE, update))
2096 /* notify start of new segment */
2097 if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
2100 msg = gst_message_new_segment_start (GST_OBJECT (demux),
2101 GST_FORMAT_TIME, demux->common.segment.start);
2102 gst_message_set_seqnum (msg, seqnum);
2103 gst_element_post_message (GST_ELEMENT (demux), msg);
2106 GST_OBJECT_LOCK (demux);
2107 if (demux->new_segment)
2108 gst_event_unref (demux->new_segment);
2110 /* On port from 0.10, discarded !update (for segment.update) here, FIXME? */
2111 demux->new_segment = gst_event_new_segment (&demux->common.segment);
2112 gst_event_set_seqnum (demux->new_segment, seqnum);
2113 if (demux->common.segment.rate < 0 && demux->common.segment.stop == -1)
2114 demux->to_time = demux->common.segment.position;
2116 demux->to_time = GST_CLOCK_TIME_NONE;
2117 GST_OBJECT_UNLOCK (demux);
2119 /* restart our task since it might have been stopped when we did the
2121 gst_pad_start_task (demux->common.sinkpad,
2122 (GstTaskFunction) gst_matroska_demux_loop, demux->common.sinkpad, NULL);
2124 /* streaming can continue now */
2126 GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
2134 GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
2136 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Got a seek error"));
2142 * Handle whether we can perform the seek event or if we have to let the chain
2143 * function handle seeks to build the seek indexes first.
2146 gst_matroska_demux_handle_seek_push (GstMatroskaDemux * demux, GstPad * pad,
2150 GstSeekType cur_type, stop_type;
2155 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
2160 /* we can only seek on time */
2161 if (format != GST_FORMAT_TIME) {
2162 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
2166 if (stop_type != GST_SEEK_TYPE_NONE && stop != GST_CLOCK_TIME_NONE) {
2167 GST_DEBUG_OBJECT (demux, "Seek end-time not supported in streaming mode");
2171 if (!(flags & GST_SEEK_FLAG_FLUSH)) {
2172 GST_DEBUG_OBJECT (demux,
2173 "Non-flushing seek not supported in streaming mode");
2177 if (flags & GST_SEEK_FLAG_SEGMENT) {
2178 GST_DEBUG_OBJECT (demux, "Segment seek not supported in streaming mode");
2182 /* check for having parsed index already */
2183 if (!demux->common.index_parsed) {
2184 gboolean building_index;
2187 if (!demux->index_offset) {
2188 GST_DEBUG_OBJECT (demux, "no index (location); no seek in push mode");
2192 GST_OBJECT_LOCK (demux);
2193 /* handle the seek event in the chain function */
2194 demux->common.state = GST_MATROSKA_READ_STATE_SEEK;
2195 /* no more seek can be issued until state reset to _DATA */
2197 /* copy the event */
2198 if (demux->seek_event)
2199 gst_event_unref (demux->seek_event);
2200 demux->seek_event = gst_event_ref (event);
2202 /* set the building_index flag so that only one thread can setup the
2203 * structures for index seeking. */
2204 building_index = demux->building_index;
2205 if (!building_index) {
2206 demux->building_index = TRUE;
2207 offset = demux->index_offset;
2209 GST_OBJECT_UNLOCK (demux);
2211 if (!building_index) {
2212 /* seek to the first subindex or legacy index */
2213 GST_INFO_OBJECT (demux, "Seeking to Cues at %" G_GUINT64_FORMAT, offset);
2214 return perform_seek_to_offset (demux, rate, offset,
2215 gst_event_get_seqnum (event));
2218 /* well, we are handling it already */
2222 /* delegate to tweaked regular seek */
2223 return gst_matroska_demux_handle_seek_event (demux, pad, event);
2227 gst_matroska_demux_handle_src_event (GstPad * pad, GstObject * parent,
2230 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
2231 gboolean res = TRUE;
2233 switch (GST_EVENT_TYPE (event)) {
2234 case GST_EVENT_SEEK:
2235 /* no seeking until we are (safely) ready */
2236 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
2237 GST_DEBUG_OBJECT (demux, "not ready for seeking yet");
2240 if (!demux->streaming)
2241 res = gst_matroska_demux_handle_seek_event (demux, pad, event);
2243 res = gst_matroska_demux_handle_seek_push (demux, pad, event);
2244 gst_event_unref (event);
2249 GstMatroskaTrackContext *context = gst_pad_get_element_private (pad);
2250 if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
2251 GstMatroskaTrackVideoContext *videocontext =
2252 (GstMatroskaTrackVideoContext *) context;
2254 GstClockTimeDiff diff;
2255 GstClockTime timestamp;
2257 gst_event_parse_qos (event, NULL, &proportion, &diff, ×tamp);
2259 GST_OBJECT_LOCK (demux);
2260 videocontext->earliest_time = timestamp + diff;
2261 GST_OBJECT_UNLOCK (demux);
2264 gst_event_unref (event);
2268 case GST_EVENT_TOC_SELECT:
2271 GstTocEntry *entry = NULL;
2272 GstEvent *seek_event;
2275 if (!demux->common.toc) {
2276 GST_DEBUG_OBJECT (demux, "no TOC to select");
2279 gst_event_parse_toc_select (event, &uid);
2281 GST_OBJECT_LOCK (demux);
2282 entry = gst_toc_find_entry (demux->common.toc, uid);
2283 if (entry == NULL) {
2284 GST_OBJECT_UNLOCK (demux);
2285 GST_WARNING_OBJECT (demux, "no TOC entry with given UID: %s", uid);
2288 gst_toc_entry_get_start_stop_times (entry, &start_pos, NULL);
2289 GST_OBJECT_UNLOCK (demux);
2290 seek_event = gst_event_new_seek (1.0,
2292 GST_SEEK_FLAG_FLUSH,
2293 GST_SEEK_TYPE_SET, start_pos, GST_SEEK_TYPE_SET, -1);
2294 res = gst_matroska_demux_handle_seek_event (demux, pad, seek_event);
2295 gst_event_unref (seek_event);
2299 GST_WARNING_OBJECT (demux, "received empty TOC select event");
2303 gst_event_unref (event);
2307 /* events we don't need to handle */
2308 case GST_EVENT_NAVIGATION:
2309 gst_event_unref (event);
2313 case GST_EVENT_LATENCY:
2315 res = gst_pad_push_event (demux->common.sinkpad, event);
2322 static GstFlowReturn
2323 gst_matroska_demux_seek_to_previous_keyframe (GstMatroskaDemux * demux)
2325 GstFlowReturn ret = GST_FLOW_EOS;
2326 gboolean done = TRUE;
2329 g_return_val_if_fail (demux->seek_index, GST_FLOW_EOS);
2330 g_return_val_if_fail (demux->seek_entry < demux->seek_index->len,
2333 GST_DEBUG_OBJECT (demux, "locating previous keyframe");
2335 if (!demux->seek_entry) {
2336 GST_DEBUG_OBJECT (demux, "no earlier index entry");
2340 for (i = 0; i < demux->common.src->len; i++) {
2341 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
2343 GST_DEBUG_OBJECT (demux, "segment start %" GST_TIME_FORMAT
2344 ", stream %d at %" GST_TIME_FORMAT,
2345 GST_TIME_ARGS (demux->common.segment.start), stream->index,
2346 GST_TIME_ARGS (stream->from_time));
2347 if (GST_CLOCK_TIME_IS_VALID (stream->from_time)) {
2348 if (stream->from_time > demux->common.segment.start) {
2349 GST_DEBUG_OBJECT (demux, "stream %d not finished yet", stream->index);
2353 /* nothing pushed for this stream;
2354 * likely seek entry did not start at keyframe, so all was skipped.
2355 * So we need an earlier entry */
2361 GstMatroskaIndex *entry;
2363 entry = &g_array_index (demux->seek_index, GstMatroskaIndex,
2364 --demux->seek_entry);
2365 if (!gst_matroska_demux_move_to_entry (demux, entry, FALSE, TRUE))
2375 static GstFlowReturn
2376 gst_matroska_demux_parse_tracks (GstMatroskaDemux * demux, GstEbmlRead * ebml)
2378 GstFlowReturn ret = GST_FLOW_OK;
2381 DEBUG_ELEMENT_START (demux, ebml, "Tracks");
2383 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2384 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
2388 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
2389 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
2393 /* one track within the "all-tracks" header */
2394 case GST_MATROSKA_ID_TRACKENTRY:
2395 ret = gst_matroska_demux_add_stream (demux, ebml);
2399 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
2404 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
2406 demux->tracks_parsed = TRUE;
2412 * Read signed/unsigned "EBML" numbers.
2413 * Return: number of bytes processed.
2417 gst_matroska_ebmlnum_uint (guint8 * data, guint size, guint64 * num)
2419 gint len_mask = 0x80, read = 1, n = 1, num_ffs = 0;
2427 while (read <= 8 && !(total & len_mask)) {
2434 if ((total &= (len_mask - 1)) == len_mask - 1)
2439 if (data[n] == 0xff)
2441 total = (total << 8) | data[n];
2445 if (read == num_ffs && total != 0)
2454 gst_matroska_ebmlnum_sint (guint8 * data, guint size, gint64 * num)
2459 /* read as unsigned number first */
2460 if ((res = gst_matroska_ebmlnum_uint (data, size, &unum)) < 0)
2464 if (unum == G_MAXUINT64)
2467 *num = unum - ((1 << ((7 * res) - 1)) - 1);
2473 * Mostly used for subtitles. We add void filler data for each
2474 * lagging stream to make sure we don't deadlock.
2478 gst_matroska_demux_sync_streams (GstMatroskaDemux * demux)
2482 GST_OBJECT_LOCK (demux);
2484 GST_LOG_OBJECT (demux, "Sync to %" GST_TIME_FORMAT,
2485 GST_TIME_ARGS (demux->common.segment.position));
2487 g_assert (demux->common.num_streams == demux->common.src->len);
2488 for (stream_nr = 0; stream_nr < demux->common.src->len; stream_nr++) {
2489 GstMatroskaTrackContext *context;
2491 context = g_ptr_array_index (demux->common.src, stream_nr);
2493 GST_LOG_OBJECT (demux,
2494 "Checking for resync on stream %d (%" GST_TIME_FORMAT ")", stream_nr,
2495 GST_TIME_ARGS (context->pos));
2497 if (G_LIKELY (context->type != GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
2498 GST_LOG_OBJECT (demux, "Skipping sync on non-subtitle stream");
2502 /* does it lag? 0.5 seconds is a random threshold...
2503 * lag need only be considered if we have advanced into requested segment */
2504 if (GST_CLOCK_TIME_IS_VALID (context->pos) &&
2505 GST_CLOCK_TIME_IS_VALID (demux->common.segment.position) &&
2506 demux->common.segment.position > demux->common.segment.start &&
2507 context->pos + (GST_SECOND / 2) < demux->common.segment.position) {
2510 guint64 start = context->pos;
2511 guint64 stop = demux->common.segment.position - (GST_SECOND / 2);
2513 GST_DEBUG_OBJECT (demux,
2514 "Synchronizing stream %d with other by advancing time from %"
2515 GST_TIME_FORMAT " to %" GST_TIME_FORMAT, stream_nr,
2516 GST_TIME_ARGS (start), GST_TIME_ARGS (stop));
2518 context->pos = stop;
2520 event = gst_event_new_gap (start, stop - start);
2521 GST_OBJECT_UNLOCK (demux);
2522 gst_pad_push_event (context->pad, event);
2523 GST_OBJECT_LOCK (demux);
2527 GST_OBJECT_UNLOCK (demux);
2530 static GstFlowReturn
2531 gst_matroska_demux_push_stream_headers (GstMatroskaDemux * demux,
2532 GstMatroskaTrackContext * stream)
2534 GstFlowReturn ret = GST_FLOW_OK;
2537 num = gst_buffer_list_length (stream->stream_headers);
2538 for (i = 0; i < num; ++i) {
2541 buf = gst_buffer_list_get (stream->stream_headers, i);
2542 buf = gst_buffer_copy (buf);
2544 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
2546 if (stream->set_discont) {
2547 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
2548 stream->set_discont = FALSE;
2550 GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DISCONT);
2553 /* push out all headers in one go and use last flow return */
2554 ret = gst_pad_push (stream->pad, buf);
2557 /* don't need these any longer */
2558 gst_buffer_list_unref (stream->stream_headers);
2559 stream->stream_headers = NULL;
2562 ret = gst_flow_combiner_update_flow (demux->flowcombiner, ret);
2568 gst_matroska_demux_push_dvd_clut_change_event (GstMatroskaDemux * demux,
2569 GstMatroskaTrackContext * stream)
2573 g_assert (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB));
2575 if (!stream->codec_priv)
2578 /* ideally, VobSub private data should be parsed and stored more convenient
2579 * elsewhere, but for now, only interested in a small part */
2581 /* make sure we have terminating 0 */
2582 buf = g_strndup (stream->codec_priv, stream->codec_priv_size);
2584 /* just locate and parse palette part */
2585 start = strstr (buf, "palette:");
2590 guint8 r, g, b, y, u, v;
2593 while (g_ascii_isspace (*start))
2595 for (i = 0; i < 16; i++) {
2596 if (sscanf (start, "%06x", &col) != 1)
2599 while ((*start == ',') || g_ascii_isspace (*start))
2601 /* sigh, need to convert this from vobsub pseudo-RGB to YUV */
2602 r = (col >> 16) & 0xff;
2603 g = (col >> 8) & 0xff;
2605 y = CLAMP ((0.1494 * r + 0.6061 * g + 0.2445 * b) * 219 / 255 + 16, 0,
2607 u = CLAMP (0.6066 * r - 0.4322 * g - 0.1744 * b + 128, 0, 255);
2608 v = CLAMP (-0.08435 * r - 0.3422 * g + 0.4266 * b + 128, 0, 255);
2609 clut[i] = (y << 16) | (u << 8) | v;
2612 /* got them all without problems; build and send event */
2616 s = gst_structure_new ("application/x-gst-dvd", "event", G_TYPE_STRING,
2617 "dvd-spu-clut-change", "clut00", G_TYPE_INT, clut[0], "clut01",
2618 G_TYPE_INT, clut[1], "clut02", G_TYPE_INT, clut[2], "clut03",
2619 G_TYPE_INT, clut[3], "clut04", G_TYPE_INT, clut[4], "clut05",
2620 G_TYPE_INT, clut[5], "clut06", G_TYPE_INT, clut[6], "clut07",
2621 G_TYPE_INT, clut[7], "clut08", G_TYPE_INT, clut[8], "clut09",
2622 G_TYPE_INT, clut[9], "clut10", G_TYPE_INT, clut[10], "clut11",
2623 G_TYPE_INT, clut[11], "clut12", G_TYPE_INT, clut[12], "clut13",
2624 G_TYPE_INT, clut[13], "clut14", G_TYPE_INT, clut[14], "clut15",
2625 G_TYPE_INT, clut[15], NULL);
2627 gst_pad_push_event (stream->pad,
2628 gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM_STICKY, s));
2635 gst_matroska_demux_push_codec_data_all (GstMatroskaDemux * demux)
2639 GST_OBJECT_LOCK (demux);
2641 g_assert (demux->common.num_streams == demux->common.src->len);
2642 for (stream_nr = 0; stream_nr < demux->common.src->len; stream_nr++) {
2643 GstMatroskaTrackContext *stream;
2645 stream = g_ptr_array_index (demux->common.src, stream_nr);
2647 if (stream->send_stream_headers) {
2648 if (stream->stream_headers != NULL) {
2649 gst_matroska_demux_push_stream_headers (demux, stream);
2651 /* FIXME: perhaps we can just disable and skip this stream then */
2652 GST_ELEMENT_ERROR (demux, STREAM, DECODE, (NULL),
2653 ("Failed to extract stream headers from codec private data"));
2655 stream->send_stream_headers = FALSE;
2658 if (stream->send_dvd_event) {
2659 gst_matroska_demux_push_dvd_clut_change_event (demux, stream);
2660 /* FIXME: should we send this event again after (flushing) seek ? */
2661 stream->send_dvd_event = FALSE;
2665 GST_OBJECT_UNLOCK (demux);
2668 static GstFlowReturn
2669 gst_matroska_demux_add_mpeg_seq_header (GstElement * element,
2670 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2673 guint seq_header_len;
2674 guint32 header, tmp;
2676 if (stream->codec_state) {
2677 seq_header = stream->codec_state;
2678 seq_header_len = stream->codec_state_size;
2679 } else if (stream->codec_priv) {
2680 seq_header = stream->codec_priv;
2681 seq_header_len = stream->codec_priv_size;
2686 /* Sequence header only needed for keyframes */
2687 if (GST_BUFFER_FLAG_IS_SET (*buf, GST_BUFFER_FLAG_DELTA_UNIT))
2690 if (gst_buffer_get_size (*buf) < 4)
2693 gst_buffer_extract (*buf, 0, &tmp, sizeof (guint32));
2694 header = GUINT32_FROM_BE (tmp);
2696 /* Sequence start code, if not found prepend */
2697 if (header != 0x000001b3) {
2700 GST_DEBUG_OBJECT (element, "Prepending MPEG sequence header");
2702 newbuf = gst_buffer_new_wrapped (g_memdup (seq_header, seq_header_len),
2705 gst_buffer_copy_into (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
2706 GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_MEMORY, 0,
2707 gst_buffer_get_size (*buf));
2709 gst_buffer_unref (*buf);
2716 static GstFlowReturn
2717 gst_matroska_demux_add_wvpk_header (GstElement * element,
2718 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2720 GstMatroskaTrackAudioContext *audiocontext =
2721 (GstMatroskaTrackAudioContext *) stream;
2722 GstBuffer *newbuf = NULL;
2723 GstMapInfo map, outmap;
2724 guint8 *buf_data, *data;
2732 wvh.version = GST_READ_UINT16_LE (stream->codec_priv);
2735 wvh.total_samples = -1;
2736 wvh.block_index = audiocontext->wvpk_block_index;
2738 if (audiocontext->channels <= 2) {
2739 guint32 block_samples, tmp;
2740 gsize size = gst_buffer_get_size (*buf);
2742 gst_buffer_extract (*buf, 0, &tmp, sizeof (guint32));
2743 block_samples = GUINT32_FROM_LE (tmp);
2744 /* we need to reconstruct the header of the wavpack block */
2746 /* -20 because ck_size is the size of the wavpack block -8
2747 * and lace_size is the size of the wavpack block + 12
2748 * (the three guint32 of the header that already are in the buffer) */
2749 wvh.ck_size = size + sizeof (Wavpack4Header) - 20;
2751 /* block_samples, flags and crc are already in the buffer */
2752 newbuf = gst_buffer_new_allocate (NULL, sizeof (Wavpack4Header) - 12, NULL);
2754 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2760 GST_WRITE_UINT32_LE (data + 4, wvh.ck_size);
2761 GST_WRITE_UINT16_LE (data + 8, wvh.version);
2762 GST_WRITE_UINT8 (data + 10, wvh.track_no);
2763 GST_WRITE_UINT8 (data + 11, wvh.index_no);
2764 GST_WRITE_UINT32_LE (data + 12, wvh.total_samples);
2765 GST_WRITE_UINT32_LE (data + 16, wvh.block_index);
2767 /* Append data from buf: */
2768 gst_buffer_copy_into (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
2769 GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_MEMORY, 0, size);
2771 gst_buffer_unref (*buf);
2773 audiocontext->wvpk_block_index += block_samples;
2775 guint8 *outdata = NULL;
2777 gsize buf_size, size, out_size = 0;
2778 guint32 block_samples, flags, crc, blocksize;
2780 gst_buffer_map (*buf, &map, GST_MAP_READ);
2781 buf_data = map.data;
2782 buf_size = map.size;
2785 GST_ERROR_OBJECT (element, "Too small wavpack buffer");
2786 gst_buffer_unmap (*buf, &map);
2787 return GST_FLOW_ERROR;
2793 block_samples = GST_READ_UINT32_LE (data);
2798 flags = GST_READ_UINT32_LE (data);
2801 crc = GST_READ_UINT32_LE (data);
2804 blocksize = GST_READ_UINT32_LE (data);
2808 if (blocksize == 0 || size < blocksize)
2811 g_assert ((newbuf == NULL) == (outdata == NULL));
2813 if (newbuf == NULL) {
2814 out_size = sizeof (Wavpack4Header) + blocksize;
2815 newbuf = gst_buffer_new_allocate (NULL, out_size, NULL);
2817 gst_buffer_copy_into (newbuf, *buf,
2818 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS, 0, -1);
2821 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2822 outdata = outmap.data;
2824 gst_buffer_unmap (newbuf, &outmap);
2825 out_size += sizeof (Wavpack4Header) + blocksize;
2826 gst_buffer_set_size (newbuf, out_size);
2827 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2828 outdata = outmap.data;
2831 outdata[outpos] = 'w';
2832 outdata[outpos + 1] = 'v';
2833 outdata[outpos + 2] = 'p';
2834 outdata[outpos + 3] = 'k';
2837 GST_WRITE_UINT32_LE (outdata + outpos,
2838 blocksize + sizeof (Wavpack4Header) - 8);
2839 GST_WRITE_UINT16_LE (outdata + outpos + 4, wvh.version);
2840 GST_WRITE_UINT8 (outdata + outpos + 6, wvh.track_no);
2841 GST_WRITE_UINT8 (outdata + outpos + 7, wvh.index_no);
2842 GST_WRITE_UINT32_LE (outdata + outpos + 8, wvh.total_samples);
2843 GST_WRITE_UINT32_LE (outdata + outpos + 12, wvh.block_index);
2844 GST_WRITE_UINT32_LE (outdata + outpos + 16, block_samples);
2845 GST_WRITE_UINT32_LE (outdata + outpos + 20, flags);
2846 GST_WRITE_UINT32_LE (outdata + outpos + 24, crc);
2849 memmove (outdata + outpos, data, blocksize);
2850 outpos += blocksize;
2854 gst_buffer_unmap (*buf, &map);
2855 gst_buffer_unref (*buf);
2858 gst_buffer_unmap (newbuf, &outmap);
2861 audiocontext->wvpk_block_index += block_samples;
2867 /* @text must be null-terminated */
2869 gst_matroska_demux_subtitle_chunk_has_tag (GstElement * element,
2874 g_return_val_if_fail (text != NULL, FALSE);
2876 /* yes, this might all lead to false positives ... */
2877 tag = (gchar *) text;
2878 while ((tag = strchr (tag, '<'))) {
2880 if (*tag != '\0' && *(tag + 1) == '>') {
2881 /* some common convenience ones */
2882 /* maybe any character will do here ? */
2895 if (strstr (text, "<span"))
2901 static GstFlowReturn
2902 gst_matroska_demux_check_subtitle_buffer (GstElement * element,
2903 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2905 GstMatroskaTrackSubtitleContext *sub_stream;
2906 const gchar *encoding;
2911 gboolean needs_unmap = TRUE;
2913 sub_stream = (GstMatroskaTrackSubtitleContext *) stream;
2915 if (!gst_buffer_get_size (*buf) || !gst_buffer_map (*buf, &map, GST_MAP_READ))
2918 /* Need \0-terminator at the end */
2919 if (map.data[map.size - 1] != '\0') {
2920 newbuf = gst_buffer_new_and_alloc (map.size + 1);
2922 /* Copy old buffer and add a 0 at the end */
2923 gst_buffer_fill (newbuf, 0, map.data, map.size);
2924 gst_buffer_memset (newbuf, map.size, 0, 1);
2925 gst_buffer_unmap (*buf, &map);
2927 gst_buffer_copy_into (newbuf, *buf,
2928 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS |
2929 GST_BUFFER_COPY_META, 0, -1);
2930 gst_buffer_unref (*buf);
2932 gst_buffer_map (*buf, &map, GST_MAP_READ);
2935 if (!sub_stream->invalid_utf8) {
2936 if (g_utf8_validate ((gchar *) map.data, map.size - 1, NULL)) {
2939 GST_WARNING_OBJECT (element, "subtitle stream %" G_GUINT64_FORMAT
2940 " is not valid UTF-8, this is broken according to the matroska"
2941 " specification", stream->num);
2942 sub_stream->invalid_utf8 = TRUE;
2945 /* file with broken non-UTF8 subtitle, do the best we can do to fix it */
2946 encoding = g_getenv ("GST_SUBTITLE_ENCODING");
2947 if (encoding == NULL || *encoding == '\0') {
2948 /* if local encoding is UTF-8 and no encoding specified
2949 * via the environment variable, assume ISO-8859-15 */
2950 if (g_get_charset (&encoding)) {
2951 encoding = "ISO-8859-15";
2956 g_convert_with_fallback ((gchar *) map.data, map.size, "UTF-8", encoding,
2957 (char *) "*", NULL, NULL, &err);
2960 GST_LOG_OBJECT (element, "could not convert string from '%s' to UTF-8: %s",
2961 encoding, err->message);
2965 /* invalid input encoding, fall back to ISO-8859-15 (always succeeds) */
2966 encoding = "ISO-8859-15";
2968 g_convert_with_fallback ((gchar *) map.data, map.size, "UTF-8",
2969 encoding, (char *) "*", NULL, NULL, NULL);
2972 GST_LOG_OBJECT (element, "converted subtitle text from %s to UTF-8 %s",
2973 encoding, (err) ? "(using ISO-8859-15 as fallback)" : "");
2976 utf8 = g_strdup ("invalid subtitle");
2978 newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
2979 gst_buffer_unmap (*buf, &map);
2980 gst_buffer_copy_into (newbuf, *buf,
2981 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_META,
2983 gst_buffer_unref (*buf);
2986 gst_buffer_map (*buf, &map, GST_MAP_READ);
2990 if (sub_stream->check_markup) {
2991 /* caps claim markup text, so we need to escape text,
2992 * except if text is already markup and then needs no further escaping */
2993 sub_stream->seen_markup_tag = sub_stream->seen_markup_tag ||
2994 gst_matroska_demux_subtitle_chunk_has_tag (element, (gchar *) map.data);
2996 if (!sub_stream->seen_markup_tag) {
2997 utf8 = g_markup_escape_text ((gchar *) map.data, map.size);
2999 newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
3000 gst_buffer_unmap (*buf, &map);
3001 gst_buffer_copy_into (newbuf, *buf,
3002 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS |
3003 GST_BUFFER_COPY_META, 0, -1);
3004 gst_buffer_unref (*buf);
3007 needs_unmap = FALSE;
3012 gst_buffer_unmap (*buf, &map);
3017 static GstFlowReturn
3018 gst_matroska_demux_check_aac (GstElement * element,
3019 GstMatroskaTrackContext * stream, GstBuffer ** buf)
3024 gst_buffer_extract (*buf, 0, data, 2);
3025 size = gst_buffer_get_size (*buf);
3027 if (size > 2 && data[0] == 0xff && (data[1] >> 4 == 0x0f)) {
3030 /* tss, ADTS data, remove codec_data
3031 * still assume it is at least parsed */
3032 stream->caps = gst_caps_make_writable (stream->caps);
3033 s = gst_caps_get_structure (stream->caps, 0);
3035 gst_structure_remove_field (s, "codec_data");
3036 gst_pad_set_caps (stream->pad, stream->caps);
3037 GST_DEBUG_OBJECT (element, "ADTS AAC audio data; removing codec-data, "
3038 "new caps: %" GST_PTR_FORMAT, stream->caps);
3041 /* disable subsequent checking */
3042 stream->postprocess_frame = NULL;
3048 gst_matroska_demux_align_buffer (GstMatroskaDemux * demux,
3049 GstBuffer * buffer, gsize alignment)
3053 gst_buffer_map (buffer, &map, GST_MAP_READ);
3055 if (map.size < sizeof (guintptr)) {
3056 gst_buffer_unmap (buffer, &map);
3060 if (((guintptr) map.data) & (alignment - 1)) {
3061 GstBuffer *new_buffer;
3062 GstAllocationParams params = { 0, alignment - 1, 0, 0, };
3064 new_buffer = gst_buffer_new_allocate (NULL,
3065 gst_buffer_get_size (buffer), ¶ms);
3067 /* Copy data "by hand", so ensure alignment is kept: */
3068 gst_buffer_fill (new_buffer, 0, map.data, map.size);
3070 gst_buffer_copy_into (new_buffer, buffer, GST_BUFFER_COPY_METADATA, 0, -1);
3071 GST_DEBUG_OBJECT (demux,
3072 "We want output aligned on %" G_GSIZE_FORMAT ", reallocated",
3075 gst_buffer_unmap (buffer, &map);
3076 gst_buffer_unref (buffer);
3081 gst_buffer_unmap (buffer, &map);
3085 static GstFlowReturn
3086 gst_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux,
3087 GstEbmlRead * ebml, guint64 cluster_time, guint64 cluster_offset,
3088 gboolean is_simpleblock)
3090 GstMatroskaTrackContext *stream = NULL;
3091 GstFlowReturn ret = GST_FLOW_OK;
3092 gboolean readblock = FALSE;
3094 guint64 block_duration = -1;
3095 GstBuffer *buf = NULL;
3097 gint stream_num = -1, n, laces = 0;
3099 gint *lace_size = NULL;
3102 gint64 referenceblock = 0;
3104 GstClockTime buffer_timestamp;
3106 offset = gst_ebml_read_get_offset (ebml);
3108 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3109 if (!is_simpleblock) {
3110 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK) {
3114 id = GST_MATROSKA_ID_SIMPLEBLOCK;
3118 /* one block inside the group. Note, block parsing is one
3119 * of the harder things, so this code is a bit complicated.
3120 * See http://www.matroska.org/ for documentation. */
3121 case GST_MATROSKA_ID_SIMPLEBLOCK:
3122 case GST_MATROSKA_ID_BLOCK:
3128 gst_buffer_unmap (buf, &map);
3129 gst_buffer_unref (buf);
3132 if ((ret = gst_ebml_read_buffer (ebml, &id, &buf)) != GST_FLOW_OK)
3135 gst_buffer_map (buf, &map, GST_MAP_READ);
3139 /* first byte(s): blocknum */
3140 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
3145 /* fetch stream from num */
3146 stream_num = gst_matroska_read_common_stream_from_num (&demux->common,
3148 if (G_UNLIKELY (size < 3)) {
3149 GST_WARNING_OBJECT (demux, "Invalid size %u", size);
3150 /* non-fatal, try next block(group) */
3153 } else if (G_UNLIKELY (stream_num < 0 ||
3154 stream_num >= demux->common.num_streams)) {
3155 /* let's not give up on a stray invalid track number */
3156 GST_WARNING_OBJECT (demux,
3157 "Invalid stream %d for track number %" G_GUINT64_FORMAT
3158 "; ignoring block", stream_num, num);
3162 stream = g_ptr_array_index (demux->common.src, stream_num);
3164 /* time (relative to cluster time) */
3165 time = ((gint16) GST_READ_UINT16_BE (data));
3168 flags = GST_READ_UINT8 (data);
3172 GST_LOG_OBJECT (demux, "time %" G_GUINT64_FORMAT ", flags %d", time,
3175 switch ((flags & 0x06) >> 1) {
3176 case 0x0: /* no lacing */
3178 lace_size = g_new (gint, 1);
3179 lace_size[0] = size;
3182 case 0x1: /* xiph lacing */
3183 case 0x2: /* fixed-size lacing */
3184 case 0x3: /* EBML lacing */
3186 goto invalid_lacing;
3187 laces = GST_READ_UINT8 (data) + 1;
3190 lace_size = g_new0 (gint, laces);
3192 switch ((flags & 0x06) >> 1) {
3193 case 0x1: /* xiph lacing */ {
3194 guint temp, total = 0;
3196 for (n = 0; ret == GST_FLOW_OK && n < laces - 1; n++) {
3199 goto invalid_lacing;
3200 temp = GST_READ_UINT8 (data);
3201 lace_size[n] += temp;
3207 total += lace_size[n];
3209 lace_size[n] = size - total;
3213 case 0x2: /* fixed-size lacing */
3214 for (n = 0; n < laces; n++)
3215 lace_size[n] = size / laces;
3218 case 0x3: /* EBML lacing */ {
3221 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
3225 total = lace_size[0] = num;
3226 for (n = 1; ret == GST_FLOW_OK && n < laces - 1; n++) {
3230 if ((r = gst_matroska_ebmlnum_sint (data, size, &snum)) < 0)
3234 lace_size[n] = lace_size[n - 1] + snum;
3235 total += lace_size[n];
3238 lace_size[n] = size - total;
3245 if (ret != GST_FLOW_OK)
3252 case GST_MATROSKA_ID_BLOCKDURATION:{
3253 ret = gst_ebml_read_uint (ebml, &id, &block_duration);
3254 GST_DEBUG_OBJECT (demux, "BlockDuration: %" G_GUINT64_FORMAT,
3259 case GST_MATROSKA_ID_REFERENCEBLOCK:{
3260 ret = gst_ebml_read_sint (ebml, &id, &referenceblock);
3261 GST_DEBUG_OBJECT (demux, "ReferenceBlock: %" G_GINT64_FORMAT,
3266 case GST_MATROSKA_ID_CODECSTATE:{
3268 guint64 data_len = 0;
3271 gst_ebml_read_binary (ebml, &id, &data,
3272 &data_len)) != GST_FLOW_OK)
3275 if (G_UNLIKELY (stream == NULL)) {
3276 GST_WARNING_OBJECT (demux,
3277 "Unexpected CodecState subelement - ignoring");
3281 g_free (stream->codec_state);
3282 stream->codec_state = data;
3283 stream->codec_state_size = data_len;
3285 /* Decode if necessary */
3286 if (stream->encodings && stream->encodings->len > 0
3287 && stream->codec_state && stream->codec_state_size > 0) {
3288 if (!gst_matroska_decode_data (stream->encodings,
3289 &stream->codec_state, &stream->codec_state_size,
3290 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
3291 GST_WARNING_OBJECT (demux, "Decoding codec state failed");
3295 GST_DEBUG_OBJECT (demux, "CodecState of %" G_GSIZE_FORMAT " bytes",
3296 stream->codec_state_size);
3301 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3305 case GST_MATROSKA_ID_BLOCKVIRTUAL:
3306 case GST_MATROSKA_ID_BLOCKADDITIONS:
3307 case GST_MATROSKA_ID_REFERENCEPRIORITY:
3308 case GST_MATROSKA_ID_REFERENCEVIRTUAL:
3309 case GST_MATROSKA_ID_SLICES:
3310 GST_DEBUG_OBJECT (demux,
3311 "Skipping BlockGroup subelement 0x%x - ignoring", id);
3312 ret = gst_ebml_read_skip (ebml);
3320 /* reading a number or so could have failed */
3321 if (ret != GST_FLOW_OK)
3324 if (ret == GST_FLOW_OK && readblock) {
3325 gboolean invisible_frame = FALSE;
3326 gboolean delta_unit = FALSE;
3327 guint64 duration = 0;
3328 gint64 lace_time = 0;
3330 stream = g_ptr_array_index (demux->common.src, stream_num);
3332 if (cluster_time != GST_CLOCK_TIME_NONE) {
3333 /* FIXME: What to do with negative timestamps? Give timestamp 0 or -1?
3334 * Drop unless the lace contains timestamp 0? */
3335 if (time < 0 && (-time) > cluster_time) {
3338 if (stream->timecodescale == 1.0)
3339 lace_time = (cluster_time + time) * demux->common.time_scale;
3342 gst_util_guint64_to_gdouble ((cluster_time + time) *
3343 demux->common.time_scale) * stream->timecodescale;
3346 lace_time = GST_CLOCK_TIME_NONE;
3349 /* need to refresh segment info ASAP */
3350 if (GST_CLOCK_TIME_IS_VALID (lace_time) && demux->need_segment) {
3351 GstSegment *segment = &demux->common.segment;
3353 GstEvent *segment_event;
3355 if (!GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
3356 demux->stream_start_time = lace_time;
3357 GST_DEBUG_OBJECT (demux,
3358 "Setting stream start time to %" GST_TIME_FORMAT,
3359 GST_TIME_ARGS (lace_time));
3361 clace_time = MAX (lace_time, demux->stream_start_time);
3362 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.position) &&
3363 demux->common.segment.position != 0) {
3364 GST_DEBUG_OBJECT (demux,
3365 "using stored seek position %" GST_TIME_FORMAT,
3366 GST_TIME_ARGS (demux->common.segment.position));
3367 clace_time = demux->common.segment.position + demux->stream_start_time;
3368 segment->position = GST_CLOCK_TIME_NONE;
3370 segment->start = clace_time;
3371 segment->stop = GST_CLOCK_TIME_NONE;
3372 segment->time = segment->start - demux->stream_start_time;
3373 segment->position = segment->start - demux->stream_start_time;
3374 GST_DEBUG_OBJECT (demux,
3375 "generated segment starting at %" GST_TIME_FORMAT ": %"
3376 GST_SEGMENT_FORMAT, GST_TIME_ARGS (lace_time), segment);
3377 /* now convey our segment notion downstream */
3378 segment_event = gst_event_new_segment (segment);
3379 if (demux->segment_seqnum)
3380 gst_event_set_seqnum (segment_event, demux->segment_seqnum);
3381 gst_matroska_demux_send_event (demux, segment_event);
3382 demux->need_segment = FALSE;
3383 demux->segment_seqnum = 0;
3386 /* send pending codec data headers for all streams,
3387 * before we perform sync across all streams */
3388 gst_matroska_demux_push_codec_data_all (demux);
3390 if (block_duration != -1) {
3391 if (stream->timecodescale == 1.0)
3392 duration = gst_util_uint64_scale (block_duration,
3393 demux->common.time_scale, 1);
3396 gst_util_gdouble_to_guint64 (gst_util_guint64_to_gdouble
3397 (gst_util_uint64_scale (block_duration, demux->common.time_scale,
3398 1)) * stream->timecodescale);
3399 } else if (stream->default_duration) {
3400 duration = stream->default_duration * laces;
3402 /* else duration is diff between timecode of this and next block */
3404 /* For SimpleBlock, look at the keyframe bit in flags. Otherwise,
3405 a ReferenceBlock implies that this is not a keyframe. In either
3406 case, it only makes sense for video streams. */
3407 if (stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
3408 if ((is_simpleblock && !(flags & 0x80)) || referenceblock) {
3410 invisible_frame = ((flags & 0x08)) &&
3411 (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8) ||
3412 !strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP9));
3416 for (n = 0; n < laces; n++) {
3419 if (G_UNLIKELY (lace_size[n] > size)) {
3420 GST_WARNING_OBJECT (demux, "Invalid lace size");
3424 /* QoS for video track with an index. the assumption is that
3425 index entries point to keyframes, but if that is not true we
3426 will instad skip until the next keyframe. */
3427 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
3428 stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
3429 stream->index_table && demux->common.segment.rate > 0.0) {
3430 GstMatroskaTrackVideoContext *videocontext =
3431 (GstMatroskaTrackVideoContext *) stream;
3432 GstClockTime earliest_time;
3433 GstClockTime earliest_stream_time;
3435 GST_OBJECT_LOCK (demux);
3436 earliest_time = videocontext->earliest_time;
3437 GST_OBJECT_UNLOCK (demux);
3438 earliest_stream_time = gst_segment_to_position (&demux->common.segment,
3439 GST_FORMAT_TIME, earliest_time);
3441 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
3442 GST_CLOCK_TIME_IS_VALID (earliest_stream_time) &&
3443 lace_time <= earliest_stream_time) {
3444 /* find index entry (keyframe) <= earliest_stream_time */
3445 GstMatroskaIndex *entry =
3446 gst_util_array_binary_search (stream->index_table->data,
3447 stream->index_table->len, sizeof (GstMatroskaIndex),
3448 (GCompareDataFunc) gst_matroska_index_seek_find,
3449 GST_SEARCH_MODE_BEFORE, &earliest_stream_time, NULL);
3451 /* if that entry (keyframe) is after the current the current
3452 buffer, we can skip pushing (and thus decoding) all
3453 buffers until that keyframe. */
3454 if (entry && GST_CLOCK_TIME_IS_VALID (entry->time) &&
3455 entry->time > lace_time) {
3456 GST_LOG_OBJECT (demux, "Skipping lace before late keyframe");
3457 stream->set_discont = TRUE;
3463 sub = gst_buffer_copy_region (buf, GST_BUFFER_COPY_ALL,
3464 gst_buffer_get_size (buf) - size, lace_size[n]);
3465 GST_DEBUG_OBJECT (demux, "created subbuffer %p", sub);
3468 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
3470 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
3472 if (invisible_frame)
3473 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DECODE_ONLY);
3475 if (stream->encodings != NULL && stream->encodings->len > 0)
3476 sub = gst_matroska_decode_buffer (stream, sub);
3479 GST_WARNING_OBJECT (demux, "Decoding buffer failed");
3483 buffer_timestamp = gst_matroska_track_get_buffer_timestamp (stream, sub);
3485 if (!stream->dts_only) {
3486 GST_BUFFER_PTS (sub) = lace_time;
3488 GST_BUFFER_DTS (sub) = lace_time;
3489 if (stream->intra_only)
3490 GST_BUFFER_PTS (sub) = lace_time;
3493 if (GST_CLOCK_TIME_IS_VALID (lace_time)) {
3494 GstClockTime last_stop_end;
3496 /* Check if this stream is after segment stop */
3497 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop) &&
3498 lace_time >= demux->common.segment.stop) {
3499 GST_DEBUG_OBJECT (demux,
3500 "Stream %d after segment stop %" GST_TIME_FORMAT, stream->index,
3501 GST_TIME_ARGS (demux->common.segment.stop));
3502 gst_buffer_unref (sub);
3505 if (offset >= stream->to_offset
3506 || (GST_CLOCK_TIME_IS_VALID (demux->to_time)
3507 && lace_time > demux->to_time)) {
3508 GST_DEBUG_OBJECT (demux, "Stream %d after playback section",
3510 gst_buffer_unref (sub);
3514 /* handle gaps, e.g. non-zero start-time, or an cue index entry
3515 * that landed us with timestamps not quite intended */
3516 GST_OBJECT_LOCK (demux);
3517 if (demux->max_gap_time &&
3518 GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) &&
3519 demux->common.segment.rate > 0.0) {
3520 GstClockTimeDiff diff;
3522 /* only send segments with increasing start times,
3523 * otherwise if these go back and forth downstream (sinks) increase
3524 * accumulated time and running_time */
3525 diff = GST_CLOCK_DIFF (demux->last_stop_end, lace_time);
3526 if (diff > 0 && diff > demux->max_gap_time
3527 && lace_time > demux->common.segment.start
3528 && (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop)
3529 || lace_time < demux->common.segment.stop)) {
3531 GST_DEBUG_OBJECT (demux,
3532 "Gap of %" G_GINT64_FORMAT " ns detected in"
3533 "stream %d (%" GST_TIME_FORMAT " -> %" GST_TIME_FORMAT "). "
3534 "Sending updated SEGMENT events", diff,
3535 stream->index, GST_TIME_ARGS (stream->pos),
3536 GST_TIME_ARGS (lace_time));
3538 event = gst_event_new_gap (demux->last_stop_end, diff);
3539 GST_OBJECT_UNLOCK (demux);
3540 gst_pad_push_event (stream->pad, event);
3541 GST_OBJECT_LOCK (demux);
3545 if (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.position)
3546 || demux->common.segment.position < lace_time) {
3547 demux->common.segment.position = lace_time;
3549 GST_OBJECT_UNLOCK (demux);
3551 last_stop_end = lace_time;
3553 GST_BUFFER_DURATION (sub) = duration / laces;
3554 last_stop_end += GST_BUFFER_DURATION (sub);
3557 if (!GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) ||
3558 demux->last_stop_end < last_stop_end)
3559 demux->last_stop_end = last_stop_end;
3561 GST_OBJECT_LOCK (demux);
3562 if (demux->common.segment.duration == -1 ||
3563 demux->stream_start_time + demux->common.segment.duration <
3565 demux->common.segment.duration =
3566 last_stop_end - demux->stream_start_time;
3567 GST_OBJECT_UNLOCK (demux);
3568 if (!demux->invalid_duration) {
3569 gst_element_post_message (GST_ELEMENT_CAST (demux),
3570 gst_message_new_duration_changed (GST_OBJECT_CAST (demux)));
3571 demux->invalid_duration = TRUE;
3574 GST_OBJECT_UNLOCK (demux);
3578 stream->pos = lace_time;
3580 gst_matroska_demux_sync_streams (demux);
3582 if (stream->set_discont) {
3583 GST_DEBUG_OBJECT (demux, "marking DISCONT");
3584 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DISCONT);
3585 stream->set_discont = FALSE;
3587 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DISCONT);
3590 /* reverse playback book-keeping */
3591 if (!GST_CLOCK_TIME_IS_VALID (stream->from_time))
3592 stream->from_time = lace_time;
3593 if (stream->from_offset == -1)
3594 stream->from_offset = offset;
3596 GST_DEBUG_OBJECT (demux,
3597 "Pushing lace %d, data of size %" G_GSIZE_FORMAT
3598 " for stream %d, time=%" GST_TIME_FORMAT " and duration=%"
3599 GST_TIME_FORMAT, n, gst_buffer_get_size (sub), stream_num,
3600 GST_TIME_ARGS (buffer_timestamp),
3601 GST_TIME_ARGS (GST_BUFFER_DURATION (sub)));
3604 if (demux->common.element_index) {
3605 if (stream->index_writer_id == -1)
3606 gst_index_get_writer_id (demux->common.element_index,
3607 GST_OBJECT (stream->pad), &stream->index_writer_id);
3609 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
3610 G_GUINT64_FORMAT " for writer id %d",
3611 GST_TIME_ARGS (buffer_timestamp), cluster_offset,
3612 stream->index_writer_id);
3613 gst_index_add_association (demux->common.element_index,
3614 stream->index_writer_id, GST_BUFFER_FLAG_IS_SET (sub,
3615 GST_BUFFER_FLAG_DELTA_UNIT) ? 0 : GST_ASSOCIATION_FLAG_KEY_UNIT,
3616 GST_FORMAT_TIME, buffer_timestamp, GST_FORMAT_BYTES, cluster_offset,
3621 /* Postprocess the buffers depending on the codec used */
3622 if (stream->postprocess_frame) {
3623 GST_LOG_OBJECT (demux, "running post process");
3624 ret = stream->postprocess_frame (GST_ELEMENT (demux), stream, &sub);
3627 /* At this point, we have a sub-buffer pointing at data within a larger
3628 buffer. This data might not be aligned with anything. If the data is
3629 raw samples though, we want it aligned to the raw type (eg, 4 bytes
3630 for 32 bit samples, etc), or bad things will happen downstream as
3631 elements typically assume minimal alignment.
3632 Therefore, create an aligned copy if necessary. */
3633 g_assert (stream->alignment <= G_MEM_ALIGN);
3634 sub = gst_matroska_demux_align_buffer (demux, sub, stream->alignment);
3636 if (GST_BUFFER_PTS_IS_VALID (sub)) {
3637 stream->pos = GST_BUFFER_PTS (sub);
3638 if (GST_BUFFER_DURATION_IS_VALID (sub))
3639 stream->pos += GST_BUFFER_DURATION (sub);
3640 } else if (GST_BUFFER_DTS_IS_VALID (sub)) {
3641 stream->pos = GST_BUFFER_DTS (sub);
3642 if (GST_BUFFER_DURATION_IS_VALID (sub))
3643 stream->pos += GST_BUFFER_DURATION (sub);
3646 ret = gst_pad_push (stream->pad, sub);
3648 if (demux->common.segment.rate < 0) {
3649 if (lace_time > demux->common.segment.stop && ret == GST_FLOW_EOS) {
3650 /* In reverse playback we can get a GST_FLOW_EOS when
3651 * we are at the end of the segment, so we just need to jump
3652 * back to the previous section. */
3653 GST_DEBUG_OBJECT (demux, "downstream has reached end of segment");
3658 ret = gst_flow_combiner_update_flow (demux->flowcombiner, ret);
3661 size -= lace_size[n];
3662 if (lace_time != GST_CLOCK_TIME_NONE && duration)
3663 lace_time += duration / laces;
3665 lace_time = GST_CLOCK_TIME_NONE;
3671 gst_buffer_unmap (buf, &map);
3672 gst_buffer_unref (buf);
3684 ret = gst_flow_combiner_update_flow (demux->flowcombiner, ret);
3689 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Invalid lacing size"));
3690 /* non-fatal, try next block(group) */
3696 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Data error"));
3697 /* non-fatal, try next block(group) */
3703 /* return FALSE if block(group) should be skipped (due to a seek) */
3704 static inline gboolean
3705 gst_matroska_demux_seek_block (GstMatroskaDemux * demux)
3707 if (G_UNLIKELY (demux->seek_block)) {
3708 if (!(--demux->seek_block)) {
3711 GST_LOG_OBJECT (demux, "should skip block due to seek");
3719 static GstFlowReturn
3720 gst_matroska_demux_parse_contents_seekentry (GstMatroskaDemux * demux,
3724 guint64 seek_pos = (guint64) - 1;
3725 guint32 seek_id = 0;
3728 DEBUG_ELEMENT_START (demux, ebml, "Seek");
3730 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3731 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
3735 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3736 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3740 case GST_MATROSKA_ID_SEEKID:
3744 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
3747 GST_DEBUG_OBJECT (demux, "SeekID: %" G_GUINT64_FORMAT, t);
3752 case GST_MATROSKA_ID_SEEKPOSITION:
3756 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
3759 if (t > G_MAXINT64) {
3760 GST_WARNING_OBJECT (demux,
3761 "Too large SeekPosition %" G_GUINT64_FORMAT, t);
3765 GST_DEBUG_OBJECT (demux, "SeekPosition: %" G_GUINT64_FORMAT, t);
3771 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3777 if (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)
3780 if (!seek_id || seek_pos == (guint64) - 1) {
3781 GST_WARNING_OBJECT (demux, "Incomplete seekhead entry (0x%x/%"
3782 G_GUINT64_FORMAT ")", seek_id, seek_pos);
3787 case GST_MATROSKA_ID_SEEKHEAD:
3790 case GST_MATROSKA_ID_CUES:
3791 case GST_MATROSKA_ID_TAGS:
3792 case GST_MATROSKA_ID_TRACKS:
3793 case GST_MATROSKA_ID_SEGMENTINFO:
3794 case GST_MATROSKA_ID_ATTACHMENTS:
3795 case GST_MATROSKA_ID_CHAPTERS:
3797 guint64 before_pos, length;
3801 length = gst_matroska_read_common_get_length (&demux->common);
3802 before_pos = demux->common.offset;
3804 if (length == (guint64) - 1) {
3805 GST_DEBUG_OBJECT (demux, "no upstream length, skipping SeakHead entry");
3809 /* check for validity */
3810 if (seek_pos + demux->common.ebml_segment_start + 12 >= length) {
3811 GST_WARNING_OBJECT (demux,
3812 "SeekHead reference lies outside file!" " (%"
3813 G_GUINT64_FORMAT "+%" G_GUINT64_FORMAT "+12 >= %"
3814 G_GUINT64_FORMAT ")", seek_pos, demux->common.ebml_segment_start,
3819 /* only pick up index location when streaming */
3820 if (demux->streaming) {
3821 if (seek_id == GST_MATROSKA_ID_CUES) {
3822 demux->index_offset = seek_pos + demux->common.ebml_segment_start;
3823 GST_DEBUG_OBJECT (demux, "Cues located at offset %" G_GUINT64_FORMAT,
3824 demux->index_offset);
3830 demux->common.offset = seek_pos + demux->common.ebml_segment_start;
3833 if ((ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
3834 GST_ELEMENT_CAST (demux), &id, &length, &needed)) !=
3838 if (id != seek_id) {
3839 GST_WARNING_OBJECT (demux,
3840 "We looked for ID=0x%x but got ID=0x%x (pos=%" G_GUINT64_FORMAT ")",
3841 seek_id, id, seek_pos + demux->common.ebml_segment_start);
3844 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
3849 demux->common.offset = before_pos;
3853 case GST_MATROSKA_ID_CLUSTER:
3855 guint64 pos = seek_pos + demux->common.ebml_segment_start;
3857 GST_LOG_OBJECT (demux, "Cluster position");
3858 if (G_UNLIKELY (!demux->clusters))
3859 demux->clusters = g_array_sized_new (TRUE, TRUE, sizeof (guint64), 100);
3860 g_array_append_val (demux->clusters, pos);
3865 GST_DEBUG_OBJECT (demux, "Ignoring Seek entry for ID=0x%x", seek_id);
3868 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
3873 static GstFlowReturn
3874 gst_matroska_demux_parse_contents (GstMatroskaDemux * demux, GstEbmlRead * ebml)
3876 GstFlowReturn ret = GST_FLOW_OK;
3879 DEBUG_ELEMENT_START (demux, ebml, "SeekHead");
3881 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3882 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
3886 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3887 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3891 case GST_MATROSKA_ID_SEEKENTRY:
3893 ret = gst_matroska_demux_parse_contents_seekentry (demux, ebml);
3894 /* Ignore EOS and errors here */
3895 if (ret != GST_FLOW_OK) {
3896 GST_DEBUG_OBJECT (demux, "Ignoring %s", gst_flow_get_name (ret));
3903 ret = gst_matroska_read_common_parse_skip (&demux->common,
3904 ebml, "SeekHead", id);
3909 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
3911 /* Sort clusters by position for easier searching */
3912 if (demux->clusters)
3913 g_array_sort (demux->clusters, (GCompareFunc) gst_matroska_cluster_compare);
3918 #define GST_FLOW_OVERFLOW GST_FLOW_CUSTOM_ERROR
3920 #define MAX_BLOCK_SIZE (15 * 1024 * 1024)
3922 static inline GstFlowReturn
3923 gst_matroska_demux_check_read_size (GstMatroskaDemux * demux, guint64 bytes)
3925 if (G_UNLIKELY (bytes > MAX_BLOCK_SIZE)) {
3926 /* only a few blocks are expected/allowed to be large,
3927 * and will be recursed into, whereas others will be read and must fit */
3928 if (demux->streaming) {
3929 /* fatal in streaming case, as we can't step over easily */
3930 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
3931 ("reading large block of size %" G_GUINT64_FORMAT " not supported; "
3932 "file might be corrupt.", bytes));
3933 return GST_FLOW_ERROR;
3935 /* indicate higher level to quietly give up */
3936 GST_DEBUG_OBJECT (demux,
3937 "too large block of size %" G_GUINT64_FORMAT, bytes);
3938 return GST_FLOW_ERROR;
3945 /* returns TRUE if we truely are in error state, and should give up */
3946 static inline GstFlowReturn
3947 gst_matroska_demux_check_parse_error (GstMatroskaDemux * demux)
3949 if (!demux->streaming && demux->next_cluster_offset > 0) {
3950 /* just repositioning to where next cluster should be and try from there */
3951 GST_WARNING_OBJECT (demux, "parse error, trying next cluster expected at %"
3952 G_GUINT64_FORMAT, demux->next_cluster_offset);
3953 demux->common.offset = demux->next_cluster_offset;
3954 demux->next_cluster_offset = 0;
3960 /* sigh, one last attempt above and beyond call of duty ...;
3961 * search for cluster mark following current pos */
3962 pos = demux->common.offset;
3963 GST_WARNING_OBJECT (demux, "parse error, looking for next cluster");
3964 if ((ret = gst_matroska_demux_search_cluster (demux, &pos)) != GST_FLOW_OK) {
3965 /* did not work, give up */
3968 GST_DEBUG_OBJECT (demux, "... found at %" G_GUINT64_FORMAT, pos);
3969 /* try that position */
3970 demux->common.offset = pos;
3976 static inline GstFlowReturn
3977 gst_matroska_demux_flush (GstMatroskaDemux * demux, guint flush)
3979 GST_LOG_OBJECT (demux, "skipping %d bytes", flush);
3980 demux->common.offset += flush;
3981 if (demux->streaming) {
3984 /* hard to skip large blocks when streaming */
3985 ret = gst_matroska_demux_check_read_size (demux, flush);
3986 if (ret != GST_FLOW_OK)
3988 if (flush <= gst_adapter_available (demux->common.adapter))
3989 gst_adapter_flush (demux->common.adapter, flush);
3991 return GST_FLOW_EOS;
3996 /* initializes @ebml with @bytes from input stream at current offset.
3997 * Returns EOS if insufficient available,
3998 * ERROR if too much was attempted to read. */
3999 static inline GstFlowReturn
4000 gst_matroska_demux_take (GstMatroskaDemux * demux, guint64 bytes,
4003 GstBuffer *buffer = NULL;
4004 GstFlowReturn ret = GST_FLOW_OK;
4006 GST_LOG_OBJECT (demux, "taking %" G_GUINT64_FORMAT " bytes for parsing",
4008 ret = gst_matroska_demux_check_read_size (demux, bytes);
4009 if (G_UNLIKELY (ret != GST_FLOW_OK)) {
4010 if (!demux->streaming) {
4011 /* in pull mode, we can skip */
4012 if ((ret = gst_matroska_demux_flush (demux, bytes)) == GST_FLOW_OK)
4013 ret = GST_FLOW_OVERFLOW;
4015 /* otherwise fatal */
4016 ret = GST_FLOW_ERROR;
4020 if (demux->streaming) {
4021 if (gst_adapter_available (demux->common.adapter) >= bytes)
4022 buffer = gst_adapter_take_buffer (demux->common.adapter, bytes);
4026 ret = gst_matroska_read_common_peek_bytes (&demux->common,
4027 demux->common.offset, bytes, &buffer, NULL);
4028 if (G_LIKELY (buffer)) {
4029 gst_ebml_read_init (ebml, GST_ELEMENT_CAST (demux), buffer,
4030 demux->common.offset);
4031 demux->common.offset += bytes;
4038 gst_matroska_demux_check_seekability (GstMatroskaDemux * demux)
4041 gboolean seekable = FALSE;
4042 gint64 start = -1, stop = -1;
4044 query = gst_query_new_seeking (GST_FORMAT_BYTES);
4045 if (!gst_pad_peer_query (demux->common.sinkpad, query)) {
4046 GST_DEBUG_OBJECT (demux, "seeking query failed");
4050 gst_query_parse_seeking (query, NULL, &seekable, &start, &stop);
4052 /* try harder to query upstream size if we didn't get it the first time */
4053 if (seekable && stop == -1) {
4054 GST_DEBUG_OBJECT (demux, "doing duration query to fix up unset stop");
4055 gst_pad_peer_query_duration (demux->common.sinkpad, GST_FORMAT_BYTES,
4059 /* if upstream doesn't know the size, it's likely that it's not seekable in
4060 * practice even if it technically may be seekable */
4061 if (seekable && (start != 0 || stop <= start)) {
4062 GST_DEBUG_OBJECT (demux, "seekable but unknown start/stop -> disable");
4067 GST_INFO_OBJECT (demux, "seekable: %d (%" G_GUINT64_FORMAT " - %"
4068 G_GUINT64_FORMAT ")", seekable, start, stop);
4069 demux->seekable = seekable;
4071 gst_query_unref (query);
4074 static GstFlowReturn
4075 gst_matroska_demux_find_tracks (GstMatroskaDemux * demux)
4081 GstFlowReturn ret = GST_FLOW_OK;
4083 GST_WARNING_OBJECT (demux,
4084 "Found Cluster element before Tracks, searching Tracks");
4087 before_pos = demux->common.offset;
4089 /* Search Tracks element */
4091 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4092 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4093 if (ret != GST_FLOW_OK)
4096 if (id != GST_MATROSKA_ID_TRACKS) {
4097 /* we may be skipping large cluster here, so forego size check etc */
4098 /* ... but we can't skip undefined size; force error */
4099 if (length == G_MAXUINT64) {
4100 ret = gst_matroska_demux_check_read_size (demux, length);
4103 demux->common.offset += needed;
4104 demux->common.offset += length;
4109 /* will lead to track parsing ... */
4110 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4115 demux->common.offset = before_pos;
4120 #define GST_READ_CHECK(stmt) \
4122 if (G_UNLIKELY ((ret = (stmt)) != GST_FLOW_OK)) { \
4123 if (ret == GST_FLOW_OVERFLOW) { \
4124 ret = GST_FLOW_OK; \
4130 static GstFlowReturn
4131 gst_matroska_demux_parse_id (GstMatroskaDemux * demux, guint32 id,
4132 guint64 length, guint needed)
4134 GstEbmlRead ebml = { 0, };
4135 GstFlowReturn ret = GST_FLOW_OK;
4138 GST_LOG_OBJECT (demux, "Parsing Element id 0x%x, "
4139 "size %" G_GUINT64_FORMAT ", prefix %d", id, length, needed);
4141 /* if we plan to read and parse this element, we need prefix (id + length)
4142 * and the contents */
4143 /* mind about overflow wrap-around when dealing with undefined size */
4145 if (G_LIKELY (length != G_MAXUINT64))
4148 switch (demux->common.state) {
4149 case GST_MATROSKA_READ_STATE_START:
4151 case GST_EBML_ID_HEADER:
4152 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4153 ret = gst_matroska_read_common_parse_header (&demux->common, &ebml);
4154 if (ret != GST_FLOW_OK)
4156 demux->common.state = GST_MATROSKA_READ_STATE_SEGMENT;
4157 gst_matroska_demux_check_seekability (demux);
4160 goto invalid_header;
4164 case GST_MATROSKA_READ_STATE_SEGMENT:
4166 case GST_MATROSKA_ID_SEGMENT:
4167 /* eat segment prefix */
4168 GST_READ_CHECK (gst_matroska_demux_flush (demux, needed));
4169 GST_DEBUG_OBJECT (demux,
4170 "Found Segment start at offset %" G_GUINT64_FORMAT " with size %"
4171 G_GUINT64_FORMAT, demux->common.offset, length);
4172 /* seeks are from the beginning of the segment,
4173 * after the segment ID/length */
4174 demux->common.ebml_segment_start = demux->common.offset;
4176 length = G_MAXUINT64;
4177 demux->common.ebml_segment_length = length;
4178 demux->common.state = GST_MATROSKA_READ_STATE_HEADER;
4181 GST_WARNING_OBJECT (demux,
4182 "Expected a Segment ID (0x%x), but received 0x%x!",
4183 GST_MATROSKA_ID_SEGMENT, id);
4184 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4188 case GST_MATROSKA_READ_STATE_SCANNING:
4189 if (id != GST_MATROSKA_ID_CLUSTER &&
4190 id != GST_MATROSKA_ID_CLUSTERTIMECODE)
4193 case GST_MATROSKA_READ_STATE_HEADER:
4194 case GST_MATROSKA_READ_STATE_DATA:
4195 case GST_MATROSKA_READ_STATE_SEEK:
4197 case GST_MATROSKA_ID_SEGMENTINFO:
4198 if (!demux->common.segmentinfo_parsed) {
4199 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4200 ret = gst_matroska_read_common_parse_info (&demux->common,
4201 GST_ELEMENT_CAST (demux), &ebml);
4202 if (ret == GST_FLOW_OK)
4203 gst_matroska_demux_send_tags (demux);
4205 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4208 case GST_MATROSKA_ID_TRACKS:
4209 if (!demux->tracks_parsed) {
4210 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4211 ret = gst_matroska_demux_parse_tracks (demux, &ebml);
4213 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4216 case GST_MATROSKA_ID_CLUSTER:
4217 if (G_UNLIKELY (!demux->tracks_parsed)) {
4218 if (demux->streaming) {
4219 GST_DEBUG_OBJECT (demux, "Cluster before Track");
4220 goto not_streamable;
4222 ret = gst_matroska_demux_find_tracks (demux);
4223 if (!demux->tracks_parsed)
4227 if (G_UNLIKELY (demux->common.state
4228 == GST_MATROSKA_READ_STATE_HEADER)) {
4229 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
4230 demux->first_cluster_offset = demux->common.offset;
4231 GST_DEBUG_OBJECT (demux, "signaling no more pads");
4232 gst_element_no_more_pads (GST_ELEMENT (demux));
4233 /* send initial segment - we wait till we know the first
4234 incoming timestamp, so we can properly set the start of
4236 demux->need_segment = TRUE;
4238 demux->cluster_time = GST_CLOCK_TIME_NONE;
4239 demux->cluster_offset = demux->common.offset;
4240 if (G_UNLIKELY (!demux->seek_first && demux->seek_block)) {
4241 GST_DEBUG_OBJECT (demux, "seek target block %" G_GUINT64_FORMAT
4242 " not found in Cluster, trying next Cluster's first block instead",
4244 demux->seek_block = 0;
4246 demux->seek_first = FALSE;
4247 /* record next cluster for recovery */
4248 if (read != G_MAXUINT64)
4249 demux->next_cluster_offset = demux->cluster_offset + read;
4250 /* eat cluster prefix */
4251 gst_matroska_demux_flush (demux, needed);
4253 case GST_MATROSKA_ID_CLUSTERTIMECODE:
4257 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4258 if ((ret = gst_ebml_read_uint (&ebml, &id, &num)) != GST_FLOW_OK)
4260 GST_DEBUG_OBJECT (demux, "ClusterTimeCode: %" G_GUINT64_FORMAT, num);
4261 demux->cluster_time = num;
4263 if (demux->common.element_index) {
4264 if (demux->common.element_index_writer_id == -1)
4265 gst_index_get_writer_id (demux->common.element_index,
4266 GST_OBJECT (demux), &demux->common.element_index_writer_id);
4267 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
4268 G_GUINT64_FORMAT " for writer id %d",
4269 GST_TIME_ARGS (demux->cluster_time), demux->cluster_offset,
4270 demux->common.element_index_writer_id);
4271 gst_index_add_association (demux->common.element_index,
4272 demux->common.element_index_writer_id,
4273 GST_ASSOCIATION_FLAG_KEY_UNIT,
4274 GST_FORMAT_TIME, demux->cluster_time,
4275 GST_FORMAT_BYTES, demux->cluster_offset, NULL);
4280 case GST_MATROSKA_ID_BLOCKGROUP:
4281 if (!gst_matroska_demux_seek_block (demux))
4283 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4284 DEBUG_ELEMENT_START (demux, &ebml, "BlockGroup");
4285 if ((ret = gst_ebml_read_master (&ebml, &id)) == GST_FLOW_OK) {
4286 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4287 &ebml, demux->cluster_time, demux->cluster_offset, FALSE);
4289 DEBUG_ELEMENT_STOP (demux, &ebml, "BlockGroup", ret);
4291 case GST_MATROSKA_ID_SIMPLEBLOCK:
4292 if (!gst_matroska_demux_seek_block (demux))
4294 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4295 DEBUG_ELEMENT_START (demux, &ebml, "SimpleBlock");
4296 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4297 &ebml, demux->cluster_time, demux->cluster_offset, TRUE);
4298 DEBUG_ELEMENT_STOP (demux, &ebml, "SimpleBlock", ret);
4300 case GST_MATROSKA_ID_ATTACHMENTS:
4301 if (!demux->common.attachments_parsed) {
4302 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4303 ret = gst_matroska_read_common_parse_attachments (&demux->common,
4304 GST_ELEMENT_CAST (demux), &ebml);
4305 if (ret == GST_FLOW_OK)
4306 gst_matroska_demux_send_tags (demux);
4308 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4311 case GST_MATROSKA_ID_TAGS:
4312 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4313 ret = gst_matroska_read_common_parse_metadata (&demux->common,
4314 GST_ELEMENT_CAST (demux), &ebml);
4315 if (ret == GST_FLOW_OK)
4316 gst_matroska_demux_send_tags (demux);
4318 case GST_MATROSKA_ID_CHAPTERS:
4319 if (!demux->common.chapters_parsed) {
4320 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4322 gst_matroska_read_common_parse_chapters (&demux->common, &ebml);
4324 if (demux->common.toc) {
4325 gst_matroska_demux_send_event (demux,
4326 gst_event_new_toc (demux->common.toc, FALSE));
4329 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4331 case GST_MATROSKA_ID_SEEKHEAD:
4332 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4333 ret = gst_matroska_demux_parse_contents (demux, &ebml);
4335 case GST_MATROSKA_ID_CUES:
4336 if (demux->common.index_parsed) {
4337 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4340 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4341 ret = gst_matroska_read_common_parse_index (&demux->common, &ebml);
4342 /* only push based; delayed index building */
4343 if (ret == GST_FLOW_OK
4344 && demux->common.state == GST_MATROSKA_READ_STATE_SEEK) {
4347 GST_OBJECT_LOCK (demux);
4348 event = demux->seek_event;
4349 demux->seek_event = NULL;
4350 GST_OBJECT_UNLOCK (demux);
4353 /* unlikely to fail, since we managed to seek to this point */
4354 if (!gst_matroska_demux_handle_seek_event (demux, NULL, event))
4356 /* resume data handling, main thread clear to seek again */
4357 GST_OBJECT_LOCK (demux);
4358 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
4359 GST_OBJECT_UNLOCK (demux);
4362 case GST_MATROSKA_ID_POSITION:
4363 case GST_MATROSKA_ID_PREVSIZE:
4364 case GST_MATROSKA_ID_ENCRYPTEDBLOCK:
4365 case GST_MATROSKA_ID_SILENTTRACKS:
4366 GST_DEBUG_OBJECT (demux,
4367 "Skipping Cluster subelement 0x%x - ignoring", id);
4371 GST_DEBUG_OBJECT (demux, "skipping Element 0x%x", id);
4372 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4378 if (ret == GST_FLOW_PARSE)
4382 gst_ebml_read_clear (&ebml);
4388 /* simply exit, maybe not enough data yet */
4389 /* no ebml to clear if read error */
4394 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4395 ("Failed to parse Element 0x%x", id));
4396 ret = GST_FLOW_ERROR;
4401 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4402 ("File layout does not permit streaming"));
4403 ret = GST_FLOW_ERROR;
4408 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4409 ("No Tracks element found"));
4410 ret = GST_FLOW_ERROR;
4415 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Invalid header"));
4416 ret = GST_FLOW_ERROR;
4421 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Failed to seek"));
4422 ret = GST_FLOW_ERROR;
4428 gst_matroska_demux_loop (GstPad * pad)
4430 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (pad));
4436 /* If we have to close a segment, send a new segment to do this now */
4437 if (G_LIKELY (demux->common.state == GST_MATROSKA_READ_STATE_DATA)) {
4438 if (G_UNLIKELY (demux->new_segment)) {
4439 gst_matroska_demux_send_event (demux, demux->new_segment);
4440 demux->new_segment = NULL;
4444 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4445 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4446 if (ret == GST_FLOW_EOS) {
4448 } else if (ret == GST_FLOW_FLUSHING) {
4450 } else if (ret != GST_FLOW_OK) {
4451 ret = gst_matroska_demux_check_parse_error (demux);
4453 /* Only handle EOS as no error if we're outside the segment already */
4454 if (ret == GST_FLOW_EOS && (demux->common.ebml_segment_length != G_MAXUINT64
4455 && demux->common.offset >=
4456 demux->common.ebml_segment_start +
4457 demux->common.ebml_segment_length))
4459 else if (ret != GST_FLOW_OK)
4465 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
4466 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
4469 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4470 if (ret == GST_FLOW_EOS)
4472 if (ret != GST_FLOW_OK)
4475 /* check if we're at the end of a configured segment */
4476 if (G_LIKELY (demux->common.src->len)) {
4479 g_assert (demux->common.num_streams == demux->common.src->len);
4480 for (i = 0; i < demux->common.src->len; i++) {
4481 GstMatroskaTrackContext *context = g_ptr_array_index (demux->common.src,
4483 GST_DEBUG_OBJECT (context->pad, "pos %" GST_TIME_FORMAT,
4484 GST_TIME_ARGS (context->pos));
4485 if (context->eos == FALSE)
4489 GST_INFO_OBJECT (demux, "All streams are EOS");
4495 if (G_UNLIKELY (demux->cached_length == G_MAXUINT64 ||
4496 demux->common.offset >= demux->cached_length)) {
4497 demux->cached_length = gst_matroska_read_common_get_length (&demux->common);
4498 if (demux->common.offset == demux->cached_length) {
4499 GST_LOG_OBJECT (demux, "Reached end of stream");
4510 if (demux->common.segment.rate < 0.0) {
4511 ret = gst_matroska_demux_seek_to_previous_keyframe (demux);
4512 if (ret == GST_FLOW_OK)
4519 const gchar *reason = gst_flow_get_name (ret);
4520 gboolean push_eos = FALSE;
4522 GST_LOG_OBJECT (demux, "pausing task, reason %s", reason);
4523 gst_pad_pause_task (demux->common.sinkpad);
4525 if (ret == GST_FLOW_EOS) {
4526 /* perform EOS logic */
4528 /* If we were in the headers, make sure we send no-more-pads.
4529 This will ensure decodebin2 does not get stuck thinking
4530 the chain is not complete yet, and waiting indefinitely. */
4531 if (G_UNLIKELY (demux->common.state == GST_MATROSKA_READ_STATE_HEADER)) {
4532 if (demux->common.src->len == 0) {
4533 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
4534 ("No pads created"));
4536 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL),
4537 ("Failed to finish reading headers"));
4539 gst_element_no_more_pads (GST_ELEMENT (demux));
4542 if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
4545 /* for segment playback we need to post when (in stream time)
4546 * we stopped, this is either stop (when set) or the duration. */
4547 if ((stop = demux->common.segment.stop) == -1)
4548 stop = demux->last_stop_end;
4550 GST_LOG_OBJECT (demux, "Sending segment done, at end of segment");
4551 gst_element_post_message (GST_ELEMENT (demux),
4552 gst_message_new_segment_done (GST_OBJECT (demux), GST_FORMAT_TIME,
4554 gst_matroska_demux_send_event (demux,
4555 gst_event_new_segment_done (GST_FORMAT_TIME, stop));
4559 } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS) {
4560 /* for fatal errors we post an error message */
4561 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
4562 ("stream stopped, reason %s", reason));
4566 /* send EOS, and prevent hanging if no streams yet */
4567 GST_LOG_OBJECT (demux, "Sending EOS, at end of stream");
4568 if (!gst_matroska_demux_send_event (demux, gst_event_new_eos ()) &&
4569 (ret == GST_FLOW_EOS)) {
4570 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4571 (NULL), ("got eos but no streams (yet)"));
4579 * Create and push a flushing seek event upstream
4582 perform_seek_to_offset (GstMatroskaDemux * demux, gdouble rate, guint64 offset,
4588 GST_DEBUG_OBJECT (demux, "Seeking to %" G_GUINT64_FORMAT, offset);
4591 gst_event_new_seek (rate, GST_FORMAT_BYTES,
4592 GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, GST_SEEK_TYPE_SET, offset,
4593 GST_SEEK_TYPE_NONE, -1);
4594 gst_event_set_seqnum (event, seqnum);
4596 res = gst_pad_push_event (demux->common.sinkpad, event);
4598 /* segment event will update offset */
4602 static GstFlowReturn
4603 gst_matroska_demux_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
4605 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4607 GstFlowReturn ret = GST_FLOW_OK;
4612 if (G_UNLIKELY (GST_BUFFER_IS_DISCONT (buffer))) {
4613 GST_DEBUG_OBJECT (demux, "got DISCONT");
4614 gst_adapter_clear (demux->common.adapter);
4615 GST_OBJECT_LOCK (demux);
4616 gst_matroska_read_common_reset_streams (&demux->common,
4617 GST_CLOCK_TIME_NONE, FALSE);
4618 GST_OBJECT_UNLOCK (demux);
4621 gst_adapter_push (demux->common.adapter, buffer);
4625 available = gst_adapter_available (demux->common.adapter);
4627 ret = gst_matroska_read_common_peek_id_length_push (&demux->common,
4628 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4629 if (G_UNLIKELY (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)) {
4630 if (demux->common.ebml_segment_length != G_MAXUINT64
4631 && demux->common.offset >=
4632 demux->common.ebml_segment_start + demux->common.ebml_segment_length)
4637 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
4638 "size %" G_GUINT64_FORMAT ", needed %d, available %d",
4639 demux->common.offset, id, length, needed, available);
4641 if (needed > available)
4644 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4645 if (ret == GST_FLOW_EOS) {
4646 /* need more data */
4648 } else if (ret != GST_FLOW_OK) {
4655 gst_matroska_demux_handle_sink_event (GstPad * pad, GstObject * parent,
4658 gboolean res = TRUE;
4659 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4661 GST_DEBUG_OBJECT (demux,
4662 "have event type %s: %p on sink pad", GST_EVENT_TYPE_NAME (event), event);
4664 switch (GST_EVENT_TYPE (event)) {
4665 case GST_EVENT_SEGMENT:
4667 const GstSegment *segment;
4669 /* some debug output */
4670 gst_event_parse_segment (event, &segment);
4671 /* FIXME: do we need to update segment base here (like accum in 0.10)? */
4672 GST_DEBUG_OBJECT (demux,
4673 "received format %d segment %" GST_SEGMENT_FORMAT, segment->format,
4676 if (demux->common.state < GST_MATROSKA_READ_STATE_DATA) {
4677 GST_DEBUG_OBJECT (demux, "still starting");
4681 /* we only expect a BYTE segment, e.g. following a seek */
4682 if (segment->format != GST_FORMAT_BYTES) {
4683 GST_DEBUG_OBJECT (demux, "unsupported segment format, ignoring");
4687 GST_DEBUG_OBJECT (demux, "clearing segment state");
4688 GST_OBJECT_LOCK (demux);
4689 /* clear current segment leftover */
4690 gst_adapter_clear (demux->common.adapter);
4691 /* and some streaming setup */
4692 demux->common.offset = segment->start;
4693 /* accumulate base based on current position */
4694 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.position))
4695 demux->common.segment.base +=
4696 (MAX (demux->common.segment.position, demux->stream_start_time)
4697 - demux->stream_start_time) / fabs (demux->common.segment.rate);
4698 /* do not know where we are;
4699 * need to come across a cluster and generate segment */
4700 demux->common.segment.position = GST_CLOCK_TIME_NONE;
4701 demux->cluster_time = GST_CLOCK_TIME_NONE;
4702 demux->cluster_offset = 0;
4703 demux->need_segment = TRUE;
4704 demux->segment_seqnum = gst_event_get_seqnum (event);
4705 /* but keep some of the upstream segment */
4706 demux->common.segment.rate = segment->rate;
4707 /* also check if need to keep some of the requested seek position */
4708 if (demux->seek_offset == segment->start) {
4709 GST_DEBUG_OBJECT (demux, "position matches requested seek");
4710 demux->common.segment.position = demux->requested_seek_time;
4712 GST_DEBUG_OBJECT (demux, "unexpected segment position");
4714 demux->requested_seek_time = GST_CLOCK_TIME_NONE;
4715 demux->seek_offset = -1;
4716 GST_OBJECT_UNLOCK (demux);
4718 /* chain will send initial segment after pads have been added,
4719 * or otherwise come up with one */
4720 GST_DEBUG_OBJECT (demux, "eating event");
4721 gst_event_unref (event);
4727 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
4728 gst_event_unref (event);
4729 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4730 (NULL), ("got eos and didn't receive a complete header object"));
4731 } else if (demux->common.num_streams == 0) {
4732 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4733 (NULL), ("got eos but no streams (yet)"));
4735 gst_matroska_demux_send_event (demux, event);
4739 case GST_EVENT_FLUSH_STOP:
4743 gst_adapter_clear (demux->common.adapter);
4744 GST_OBJECT_LOCK (demux);
4745 gst_matroska_read_common_reset_streams (&demux->common,
4746 GST_CLOCK_TIME_NONE, TRUE);
4747 dur = demux->common.segment.duration;
4748 gst_segment_init (&demux->common.segment, GST_FORMAT_TIME);
4749 demux->common.segment.duration = dur;
4750 demux->cluster_time = GST_CLOCK_TIME_NONE;
4751 demux->cluster_offset = 0;
4752 GST_OBJECT_UNLOCK (demux);
4756 res = gst_pad_event_default (pad, parent, event);
4764 gst_matroska_demux_sink_activate (GstPad * sinkpad, GstObject * parent)
4766 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4768 gboolean pull_mode = FALSE;
4770 query = gst_query_new_scheduling ();
4772 if (gst_pad_peer_query (sinkpad, query))
4773 pull_mode = gst_query_has_scheduling_mode_with_flags (query,
4774 GST_PAD_MODE_PULL, GST_SCHEDULING_FLAG_SEEKABLE);
4776 gst_query_unref (query);
4779 GST_DEBUG ("going to pull mode");
4780 demux->streaming = FALSE;
4781 return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PULL, TRUE);
4783 GST_DEBUG ("going to push (streaming) mode");
4784 demux->streaming = TRUE;
4785 return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PUSH, TRUE);
4790 gst_matroska_demux_sink_activate_mode (GstPad * sinkpad, GstObject * parent,
4791 GstPadMode mode, gboolean active)
4794 case GST_PAD_MODE_PULL:
4796 /* if we have a scheduler we can start the task */
4797 gst_pad_start_task (sinkpad, (GstTaskFunction) gst_matroska_demux_loop,
4800 gst_pad_stop_task (sinkpad);
4803 case GST_PAD_MODE_PUSH:
4811 gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext *
4812 videocontext, const gchar * codec_id, guint8 * data, guint size,
4813 gchar ** codec_name, guint32 * riff_fourcc)
4815 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) videocontext;
4816 GstCaps *caps = NULL;
4818 g_assert (videocontext != NULL);
4819 g_assert (codec_name != NULL);
4824 /* TODO: check if we have all codec types from matroska-ids.h
4825 * check if we have to do more special things with codec_private
4828 * GST_MATROSKA_CODEC_ID_VIDEO_QUICKTIME
4829 * GST_MATROSKA_CODEC_ID_VIDEO_SNOW
4832 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VFW_FOURCC)) {
4833 gst_riff_strf_vids *vids = NULL;
4836 GstBuffer *buf = NULL;
4838 vids = (gst_riff_strf_vids *) data;
4840 /* assure size is big enough */
4842 GST_WARNING ("Too small BITMAPINFOHEADER (%d bytes)", size);
4845 if (size < sizeof (gst_riff_strf_vids)) {
4846 vids = g_new (gst_riff_strf_vids, 1);
4847 memcpy (vids, data, size);
4850 context->dts_only = TRUE; /* VFW files only store DTS */
4852 /* little-endian -> byte-order */
4853 vids->size = GUINT32_FROM_LE (vids->size);
4854 vids->width = GUINT32_FROM_LE (vids->width);
4855 vids->height = GUINT32_FROM_LE (vids->height);
4856 vids->planes = GUINT16_FROM_LE (vids->planes);
4857 vids->bit_cnt = GUINT16_FROM_LE (vids->bit_cnt);
4858 vids->compression = GUINT32_FROM_LE (vids->compression);
4859 vids->image_size = GUINT32_FROM_LE (vids->image_size);
4860 vids->xpels_meter = GUINT32_FROM_LE (vids->xpels_meter);
4861 vids->ypels_meter = GUINT32_FROM_LE (vids->ypels_meter);
4862 vids->num_colors = GUINT32_FROM_LE (vids->num_colors);
4863 vids->imp_colors = GUINT32_FROM_LE (vids->imp_colors);
4865 if (size > sizeof (gst_riff_strf_vids)) { /* some extra_data */
4866 gsize offset = sizeof (gst_riff_strf_vids);
4869 gst_buffer_new_wrapped (g_memdup ((guint8 *) vids + offset,
4870 size - offset), size - offset);
4874 *riff_fourcc = vids->compression;
4876 caps = gst_riff_create_video_caps (vids->compression, NULL, vids,
4877 buf, NULL, codec_name);
4880 GST_WARNING ("Unhandled RIFF fourcc %" GST_FOURCC_FORMAT,
4881 GST_FOURCC_ARGS (vids->compression));
4883 static GstStaticCaps intra_caps = GST_STATIC_CAPS ("image/jpeg; "
4884 "video/x-raw; image/png; video/x-dv; video/x-huffyuv; video/x-ffv; "
4885 "video/x-compressed-yuv");
4886 context->intra_only =
4887 gst_caps_can_intersect (gst_static_caps_get (&intra_caps), caps);
4891 gst_buffer_unref (buf);
4893 if (vids != (gst_riff_strf_vids *) data)
4896 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_UNCOMPRESSED)) {
4898 GstVideoFormat format;
4900 gst_video_info_init (&info);
4901 switch (videocontext->fourcc) {
4902 case GST_MAKE_FOURCC ('I', '4', '2', '0'):
4903 format = GST_VIDEO_FORMAT_I420;
4905 case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
4906 format = GST_VIDEO_FORMAT_YUY2;
4908 case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
4909 format = GST_VIDEO_FORMAT_YV12;
4911 case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
4912 format = GST_VIDEO_FORMAT_UYVY;
4914 case GST_MAKE_FOURCC ('A', 'Y', 'U', 'V'):
4915 format = GST_VIDEO_FORMAT_AYUV;
4917 case GST_MAKE_FOURCC ('Y', '8', '0', '0'):
4918 case GST_MAKE_FOURCC ('Y', '8', ' ', ' '):
4919 format = GST_VIDEO_FORMAT_GRAY8;
4921 case GST_MAKE_FOURCC ('R', 'G', 'B', 24):
4922 format = GST_VIDEO_FORMAT_RGB;
4924 case GST_MAKE_FOURCC ('B', 'G', 'R', 24):
4925 format = GST_VIDEO_FORMAT_BGR;
4928 GST_DEBUG ("Unknown fourcc %" GST_FOURCC_FORMAT,
4929 GST_FOURCC_ARGS (videocontext->fourcc));
4933 context->intra_only = TRUE;
4935 gst_video_info_set_format (&info, format, videocontext->pixel_width,
4936 videocontext->pixel_height);
4937 caps = gst_video_info_to_caps (&info);
4938 *codec_name = gst_pb_utils_get_codec_description (caps);
4939 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_SP)) {
4940 caps = gst_caps_new_simple ("video/x-divx",
4941 "divxversion", G_TYPE_INT, 4, NULL);
4942 *codec_name = g_strdup ("MPEG-4 simple profile");
4943 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP) ||
4944 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AP)) {
4945 caps = gst_caps_new_simple ("video/mpeg",
4946 "mpegversion", G_TYPE_INT, 4,
4947 "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
4951 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
4952 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
4953 gst_buffer_unref (priv);
4955 gst_codec_utils_mpeg4video_caps_set_level_and_profile (caps, data, size);
4957 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP))
4958 *codec_name = g_strdup ("MPEG-4 advanced simple profile");
4960 *codec_name = g_strdup ("MPEG-4 advanced profile");
4961 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MSMPEG4V3)) {
4963 caps = gst_caps_new_full (gst_structure_new ("video/x-divx",
4964 "divxversion", G_TYPE_INT, 3, NULL),
4965 gst_structure_new ("video/x-msmpeg",
4966 "msmpegversion", G_TYPE_INT, 43, NULL), NULL);
4968 caps = gst_caps_new_simple ("video/x-msmpeg",
4969 "msmpegversion", G_TYPE_INT, 43, NULL);
4970 *codec_name = g_strdup ("Microsoft MPEG-4 v.3");
4971 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1) ||
4972 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG2)) {
4975 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1))
4980 caps = gst_caps_new_simple ("video/mpeg",
4981 "systemstream", G_TYPE_BOOLEAN, FALSE,
4982 "mpegversion", G_TYPE_INT, mpegversion, NULL);
4983 *codec_name = g_strdup_printf ("MPEG-%d video", mpegversion);
4984 context->postprocess_frame = gst_matroska_demux_add_mpeg_seq_header;
4985 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MJPEG)) {
4986 caps = gst_caps_new_empty_simple ("image/jpeg");
4987 *codec_name = g_strdup ("Motion-JPEG");
4988 context->intra_only = TRUE;
4989 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AVC)) {
4990 caps = gst_caps_new_empty_simple ("video/x-h264");
4994 /* First byte is the version, second is the profile indication, and third
4995 * is the 5 contraint_set_flags and 3 reserved bits. Fourth byte is the
4996 * level indication. */
4997 gst_codec_utils_h264_caps_set_level_and_profile (caps, data + 1,
5000 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
5001 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5002 gst_buffer_unref (priv);
5004 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "avc",
5005 "alignment", G_TYPE_STRING, "au", NULL);
5007 GST_WARNING ("No codec data found, assuming output is byte-stream");
5008 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
5011 *codec_name = g_strdup ("H264");
5012 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEGH_HEVC)) {
5013 caps = gst_caps_new_empty_simple ("video/x-h265");
5017 gst_codec_utils_h265_caps_set_level_tier_and_profile (caps, data + 1,
5020 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
5021 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5022 gst_buffer_unref (priv);
5024 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "hvc1",
5025 "alignment", G_TYPE_STRING, "au", NULL);
5027 GST_WARNING ("No codec data found, assuming output is byte-stream");
5028 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
5031 *codec_name = g_strdup ("HEVC");
5032 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1)) ||
5033 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2)) ||
5034 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3)) ||
5035 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))) {
5036 gint rmversion = -1;
5038 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1))
5040 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2))
5042 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3))
5044 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))
5047 caps = gst_caps_new_simple ("video/x-pn-realvideo",
5048 "rmversion", G_TYPE_INT, rmversion, NULL);
5049 GST_DEBUG ("data:%p, size:0x%x", data, size);
5050 /* We need to extract the extradata ! */
5051 if (data && (size >= 0x22)) {
5056 subformat = GST_READ_UINT32_BE (data + 0x1a);
5057 rformat = GST_READ_UINT32_BE (data + 0x1e);
5060 gst_buffer_new_wrapped (g_memdup (data + 0x1a, size - 0x1a),
5062 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, "format",
5063 G_TYPE_INT, rformat, "subformat", G_TYPE_INT, subformat, NULL);
5064 gst_buffer_unref (priv);
5067 *codec_name = g_strdup_printf ("RealVideo %d.0", rmversion);
5068 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_THEORA)) {
5069 caps = gst_caps_new_empty_simple ("video/x-theora");
5070 context->stream_headers =
5071 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
5072 context->codec_priv_size);
5073 /* FIXME: mark stream as broken and skip if there are no stream headers */
5074 context->send_stream_headers = TRUE;
5075 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_DIRAC)) {
5076 caps = gst_caps_new_empty_simple ("video/x-dirac");
5077 *codec_name = g_strdup_printf ("Dirac");
5078 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8)) {
5079 caps = gst_caps_new_empty_simple ("video/x-vp8");
5080 *codec_name = g_strdup_printf ("On2 VP8");
5081 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP9)) {
5082 caps = gst_caps_new_empty_simple ("video/x-vp9");
5083 *codec_name = g_strdup_printf ("On2 VP9");
5085 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
5091 GstStructure *structure;
5093 for (i = 0; i < gst_caps_get_size (caps); i++) {
5094 structure = gst_caps_get_structure (caps, i);
5096 /* FIXME: use the real unit here! */
5097 GST_DEBUG ("video size %dx%d, target display size %dx%d (any unit)",
5098 videocontext->pixel_width,
5099 videocontext->pixel_height,
5100 videocontext->display_width, videocontext->display_height);
5102 /* pixel width and height are the w and h of the video in pixels */
5103 if (videocontext->pixel_width > 0 && videocontext->pixel_height > 0) {
5104 gint w = videocontext->pixel_width;
5105 gint h = videocontext->pixel_height;
5107 gst_structure_set (structure,
5108 "width", G_TYPE_INT, w, "height", G_TYPE_INT, h, NULL);
5111 if (videocontext->display_width > 0 || videocontext->display_height > 0) {
5114 if (videocontext->display_width <= 0)
5115 videocontext->display_width = videocontext->pixel_width;
5116 if (videocontext->display_height <= 0)
5117 videocontext->display_height = videocontext->pixel_height;
5119 /* calculate the pixel aspect ratio using the display and pixel w/h */
5120 n = videocontext->display_width * videocontext->pixel_height;
5121 d = videocontext->display_height * videocontext->pixel_width;
5122 GST_DEBUG ("setting PAR to %d/%d", n, d);
5123 gst_structure_set (structure, "pixel-aspect-ratio",
5125 videocontext->display_width * videocontext->pixel_height,
5126 videocontext->display_height * videocontext->pixel_width, NULL);
5129 if (videocontext->default_fps > 0.0) {
5132 gst_util_double_to_fraction (videocontext->default_fps, &fps_n, &fps_d);
5134 GST_DEBUG ("using default fps %d/%d", fps_n, fps_d);
5136 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION, fps_n,
5138 } else if (context->default_duration > 0) {
5141 gst_video_guess_framerate (context->default_duration, &fps_n, &fps_d);
5143 GST_INFO ("using default duration %" G_GUINT64_FORMAT
5144 " framerate %d/%d", context->default_duration, fps_n, fps_d);
5146 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
5147 fps_n, fps_d, NULL);
5149 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
5153 if (videocontext->parent.flags & GST_MATROSKA_VIDEOTRACK_INTERLACED)
5154 gst_structure_set (structure, "interlace-mode", G_TYPE_STRING,
5158 caps = gst_caps_simplify (caps);
5165 * Some AAC specific code... *sigh*
5166 * FIXME: maybe we should use '15' and code the sample rate explicitly
5167 * if the sample rate doesn't match the predefined rates exactly? (tpm)
5171 aac_rate_idx (gint rate)
5175 else if (75132 <= rate)
5177 else if (55426 <= rate)
5179 else if (46009 <= rate)
5181 else if (37566 <= rate)
5183 else if (27713 <= rate)
5185 else if (23004 <= rate)
5187 else if (18783 <= rate)
5189 else if (13856 <= rate)
5191 else if (11502 <= rate)
5193 else if (9391 <= rate)
5200 aac_profile_idx (const gchar * codec_id)
5204 if (strlen (codec_id) <= 12)
5206 else if (!strncmp (&codec_id[12], "MAIN", 4))
5208 else if (!strncmp (&codec_id[12], "LC", 2))
5210 else if (!strncmp (&codec_id[12], "SSR", 3))
5219 round_up_pow2 (guint n)
5230 #define AAC_SYNC_EXTENSION_TYPE 0x02b7
5233 gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext *
5234 audiocontext, const gchar * codec_id, guint8 * data, guint size,
5235 gchar ** codec_name, guint16 * riff_audio_fmt)
5237 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) audiocontext;
5238 GstCaps *caps = NULL;
5240 g_assert (audiocontext != NULL);
5241 g_assert (codec_name != NULL);
5244 *riff_audio_fmt = 0;
5246 /* TODO: check if we have all codec types from matroska-ids.h
5247 * check if we have to do more special things with codec_private
5248 * check if we need bitdepth in different places too
5249 * implement channel position magic
5251 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID9
5252 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID10
5253 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDMC
5254 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDM2
5257 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1) ||
5258 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2) ||
5259 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L3)) {
5262 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1))
5264 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2))
5269 caps = gst_caps_new_simple ("audio/mpeg",
5270 "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, layer, NULL);
5271 *codec_name = g_strdup_printf ("MPEG-1 layer %d", layer);
5272 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE) ||
5273 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_LE)) {
5276 GstAudioFormat format;
5278 sign = (audiocontext->bitdepth != 8);
5279 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE))
5280 endianness = G_BIG_ENDIAN;
5282 endianness = G_LITTLE_ENDIAN;
5284 format = gst_audio_format_build_integer (sign, endianness,
5285 audiocontext->bitdepth, audiocontext->bitdepth);
5287 /* FIXME: Channel mask and reordering */
5288 caps = gst_caps_new_simple ("audio/x-raw",
5289 "format", G_TYPE_STRING, gst_audio_format_to_string (format),
5290 "layout", G_TYPE_STRING, "interleaved", NULL);
5292 *codec_name = g_strdup_printf ("Raw %d-bit PCM audio",
5293 audiocontext->bitdepth);
5294 context->alignment = GST_ROUND_UP_8 (audiocontext->bitdepth) / 8;
5295 context->alignment = round_up_pow2 (context->alignment);
5296 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_FLOAT)) {
5297 const gchar *format;
5298 if (audiocontext->bitdepth == 32)
5302 /* FIXME: Channel mask and reordering */
5303 caps = gst_caps_new_simple ("audio/x-raw",
5304 "format", G_TYPE_STRING, format,
5305 "layout", G_TYPE_STRING, "interleaved", NULL);
5306 *codec_name = g_strdup_printf ("Raw %d-bit floating-point audio",
5307 audiocontext->bitdepth);
5308 context->alignment = audiocontext->bitdepth / 8;
5309 context->alignment = round_up_pow2 (context->alignment);
5310 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AC3,
5311 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AC3))) {
5312 caps = gst_caps_new_simple ("audio/x-ac3",
5313 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5314 *codec_name = g_strdup ("AC-3 audio");
5315 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_EAC3,
5316 strlen (GST_MATROSKA_CODEC_ID_AUDIO_EAC3))) {
5317 caps = gst_caps_new_simple ("audio/x-eac3",
5318 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5319 *codec_name = g_strdup ("E-AC-3 audio");
5320 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TRUEHD,
5321 strlen (GST_MATROSKA_CODEC_ID_AUDIO_TRUEHD))) {
5322 caps = gst_caps_new_empty_simple ("audio/x-true-hd");
5323 *codec_name = g_strdup ("Dolby TrueHD");
5324 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_DTS)) {
5325 caps = gst_caps_new_empty_simple ("audio/x-dts");
5326 *codec_name = g_strdup ("DTS audio");
5327 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_VORBIS)) {
5328 caps = gst_caps_new_empty_simple ("audio/x-vorbis");
5329 context->stream_headers =
5330 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
5331 context->codec_priv_size);
5332 /* FIXME: mark stream as broken and skip if there are no stream headers */
5333 context->send_stream_headers = TRUE;
5334 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_FLAC)) {
5335 caps = gst_caps_new_empty_simple ("audio/x-flac");
5336 context->stream_headers =
5337 gst_matroska_parse_flac_stream_headers (context->codec_priv,
5338 context->codec_priv_size);
5339 /* FIXME: mark stream as broken and skip if there are no stream headers */
5340 context->send_stream_headers = TRUE;
5341 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_SPEEX)) {
5342 caps = gst_caps_new_empty_simple ("audio/x-speex");
5343 context->stream_headers =
5344 gst_matroska_parse_speex_stream_headers (context->codec_priv,
5345 context->codec_priv_size);
5346 /* FIXME: mark stream as broken and skip if there are no stream headers */
5347 context->send_stream_headers = TRUE;
5348 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_OPUS)) {
5349 caps = gst_caps_new_empty_simple ("audio/x-opus");
5350 *codec_name = g_strdup ("Opus");
5351 context->stream_headers =
5352 gst_matroska_parse_opus_stream_headers (context->codec_priv,
5353 context->codec_priv_size);
5354 if (context->stream_headers) {
5355 /* There was a valid header. Multistream headers are more than
5356 * 19 bytes, as they include an extra channel mapping table. */
5357 gboolean multistream = (context->codec_priv_size > 19);
5358 gst_caps_set_simple (caps, "multistream", G_TYPE_BOOLEAN, multistream,
5361 /* FIXME: mark stream as broken and skip if there are no stream headers */
5362 context->send_stream_headers = TRUE;
5363 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_ACM)) {
5364 gst_riff_strf_auds auds;
5366 if (data && size >= 18) {
5367 GstBuffer *codec_data = NULL;
5369 /* little-endian -> byte-order */
5370 auds.format = GST_READ_UINT16_LE (data);
5371 auds.channels = GST_READ_UINT16_LE (data + 2);
5372 auds.rate = GST_READ_UINT32_LE (data + 4);
5373 auds.av_bps = GST_READ_UINT32_LE (data + 8);
5374 auds.blockalign = GST_READ_UINT16_LE (data + 12);
5375 auds.bits_per_sample = GST_READ_UINT16_LE (data + 16);
5377 /* 18 is the waveformatex size */
5379 codec_data = gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY,
5380 data + 18, size - 18, 0, size - 18, NULL, NULL);
5384 *riff_audio_fmt = auds.format;
5386 /* FIXME: Handle reorder map */
5387 caps = gst_riff_create_audio_caps (auds.format, NULL, &auds, NULL,
5388 codec_data, codec_name, NULL);
5390 gst_buffer_unref (codec_data);
5393 GST_WARNING ("Unhandled RIFF audio format 0x%02x", auds.format);
5396 GST_WARNING ("Invalid codec data size (%d expected, got %d)", 18, size);
5398 } else if (g_str_has_prefix (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC)) {
5399 GstBuffer *priv = NULL;
5401 gint rate_idx, profile;
5402 guint8 *data = NULL;
5404 /* unspecified AAC profile with opaque private codec data */
5405 if (strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC) == 0) {
5406 if (context->codec_priv_size >= 2) {
5407 guint obj_type, freq_index, explicit_freq_bytes = 0;
5409 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
5411 freq_index = (GST_READ_UINT16_BE (context->codec_priv) & 0x780) >> 7;
5412 obj_type = (GST_READ_UINT16_BE (context->codec_priv) & 0xF800) >> 11;
5413 if (freq_index == 15)
5414 explicit_freq_bytes = 3;
5415 GST_DEBUG ("obj_type = %u, freq_index = %u", obj_type, freq_index);
5416 priv = gst_buffer_new_wrapped (g_memdup (context->codec_priv,
5417 context->codec_priv_size), context->codec_priv_size);
5418 /* assume SBR if samplerate <= 24kHz */
5419 if (obj_type == 5 || (freq_index >= 6 && freq_index != 15) ||
5420 (context->codec_priv_size == (5 + explicit_freq_bytes))) {
5421 audiocontext->samplerate *= 2;
5424 GST_WARNING ("Opaque A_AAC codec ID, but no codec private data");
5425 /* this is pretty broken;
5426 * maybe we need to make up some default private,
5427 * or maybe ADTS data got dumped in.
5428 * Let's set up some private data now, and check actual data later */
5429 /* just try this and see what happens ... */
5430 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
5431 context->postprocess_frame = gst_matroska_demux_check_aac;
5435 /* make up decoder-specific data if it is not supplied */
5439 priv = gst_buffer_new_allocate (NULL, 5, NULL);
5440 gst_buffer_map (priv, &map, GST_MAP_WRITE);
5442 rate_idx = aac_rate_idx (audiocontext->samplerate);
5443 profile = aac_profile_idx (codec_id);
5445 data[0] = ((profile + 1) << 3) | ((rate_idx & 0xE) >> 1);
5446 data[1] = ((rate_idx & 0x1) << 7) | (audiocontext->channels << 3);
5448 if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2,
5449 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2))) {
5451 gst_buffer_unmap (priv, &map);
5452 gst_buffer_set_size (priv, 2);
5453 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4,
5454 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4))) {
5457 if (g_strrstr (codec_id, "SBR")) {
5458 /* HE-AAC (aka SBR AAC) */
5459 audiocontext->samplerate *= 2;
5460 rate_idx = aac_rate_idx (audiocontext->samplerate);
5461 data[2] = AAC_SYNC_EXTENSION_TYPE >> 3;
5462 data[3] = ((AAC_SYNC_EXTENSION_TYPE & 0x07) << 5) | 5;
5463 data[4] = (1 << 7) | (rate_idx << 3);
5464 gst_buffer_unmap (priv, &map);
5466 gst_buffer_unmap (priv, &map);
5467 gst_buffer_set_size (priv, 2);
5470 gst_buffer_unmap (priv, &map);
5471 gst_buffer_unref (priv);
5473 GST_ERROR ("Unknown AAC profile and no codec private data");
5478 caps = gst_caps_new_simple ("audio/mpeg",
5479 "mpegversion", G_TYPE_INT, mpegversion,
5480 "framed", G_TYPE_BOOLEAN, TRUE,
5481 "stream-format", G_TYPE_STRING, "raw", NULL);
5482 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5483 if (context->codec_priv && context->codec_priv_size > 0)
5484 gst_codec_utils_aac_caps_set_level_and_profile (caps,
5485 context->codec_priv, context->codec_priv_size);
5486 *codec_name = g_strdup_printf ("MPEG-%d AAC audio", mpegversion);
5487 gst_buffer_unref (priv);
5489 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TTA)) {
5490 caps = gst_caps_new_simple ("audio/x-tta",
5491 "width", G_TYPE_INT, audiocontext->bitdepth, NULL);
5492 *codec_name = g_strdup ("TTA audio");
5493 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_WAVPACK4)) {
5494 caps = gst_caps_new_simple ("audio/x-wavpack",
5495 "width", G_TYPE_INT, audiocontext->bitdepth,
5496 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5497 *codec_name = g_strdup ("Wavpack audio");
5498 context->postprocess_frame = gst_matroska_demux_add_wvpk_header;
5499 audiocontext->wvpk_block_index = 0;
5500 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4)) ||
5501 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_28_8)) ||
5502 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))) {
5503 gint raversion = -1;
5505 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4))
5507 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))
5512 caps = gst_caps_new_simple ("audio/x-pn-realaudio",
5513 "raversion", G_TYPE_INT, raversion, NULL);
5514 /* Extract extra information from caps, mapping varies based on codec */
5515 if (data && (size >= 0x50)) {
5522 guint extra_data_size;
5524 GST_ERROR ("real audio raversion:%d", raversion);
5525 if (raversion == 8) {
5527 flavor = GST_READ_UINT16_BE (data + 22);
5528 packet_size = GST_READ_UINT32_BE (data + 24);
5529 height = GST_READ_UINT16_BE (data + 40);
5530 leaf_size = GST_READ_UINT16_BE (data + 44);
5531 sample_width = GST_READ_UINT16_BE (data + 58);
5532 extra_data_size = GST_READ_UINT32_BE (data + 74);
5535 ("flavor:%d, packet_size:%d, height:%d, leaf_size:%d, sample_width:%d, extra_data_size:%d",
5536 flavor, packet_size, height, leaf_size, sample_width,
5538 gst_caps_set_simple (caps, "flavor", G_TYPE_INT, flavor, "packet_size",
5539 G_TYPE_INT, packet_size, "height", G_TYPE_INT, height, "leaf_size",
5540 G_TYPE_INT, leaf_size, "width", G_TYPE_INT, sample_width, NULL);
5542 if ((size - 78) >= extra_data_size) {
5543 priv = gst_buffer_new_wrapped (g_memdup (data + 78, extra_data_size),
5545 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5546 gst_buffer_unref (priv);
5551 *codec_name = g_strdup_printf ("RealAudio %d.0", raversion);
5552 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_SIPR)) {
5553 caps = gst_caps_new_empty_simple ("audio/x-sipro");
5554 *codec_name = g_strdup ("Sipro/ACELP.NET Voice Codec");
5555 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_RALF)) {
5556 caps = gst_caps_new_empty_simple ("audio/x-ralf-mpeg4-generic");
5557 *codec_name = g_strdup ("Real Audio Lossless");
5558 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_ATRC)) {
5559 caps = gst_caps_new_empty_simple ("audio/x-vnd.sony.atrac3");
5560 *codec_name = g_strdup ("Sony ATRAC3");
5562 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
5567 if (audiocontext->samplerate > 0 && audiocontext->channels > 0) {
5570 for (i = 0; i < gst_caps_get_size (caps); i++) {
5571 gst_structure_set (gst_caps_get_structure (caps, i),
5572 "channels", G_TYPE_INT, audiocontext->channels,
5573 "rate", G_TYPE_INT, audiocontext->samplerate, NULL);
5577 caps = gst_caps_simplify (caps);
5584 gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
5585 subtitlecontext, const gchar * codec_id, gpointer data, guint size)
5587 GstCaps *caps = NULL;
5588 GstMatroskaTrackContext *context =
5589 (GstMatroskaTrackContext *) subtitlecontext;
5591 /* for backwards compatibility */
5592 if (!g_ascii_strcasecmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASCII))
5593 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8;
5594 else if (!g_ascii_strcasecmp (codec_id, "S_SSA"))
5595 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_SSA;
5596 else if (!g_ascii_strcasecmp (codec_id, "S_ASS"))
5597 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_ASS;
5598 else if (!g_ascii_strcasecmp (codec_id, "S_USF"))
5599 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_USF;
5601 /* TODO: Add GST_MATROSKA_CODEC_ID_SUBTITLE_BMP support
5602 * Check if we have to do something with codec_private */
5603 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8)) {
5604 /* well, plain text simply does not have a lot of markup ... */
5605 caps = gst_caps_new_simple ("text/x-raw", "format", G_TYPE_STRING,
5606 "pango-markup", NULL);
5607 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5608 subtitlecontext->check_markup = TRUE;
5609 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_SSA)) {
5610 caps = gst_caps_new_empty_simple ("application/x-ssa");
5611 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5612 subtitlecontext->check_markup = FALSE;
5613 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASS)) {
5614 caps = gst_caps_new_empty_simple ("application/x-ass");
5615 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5616 subtitlecontext->check_markup = FALSE;
5617 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_USF)) {
5618 caps = gst_caps_new_empty_simple ("application/x-usf");
5619 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5620 subtitlecontext->check_markup = FALSE;
5621 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB)) {
5622 caps = gst_caps_new_empty_simple ("subpicture/x-dvd");
5623 ((GstMatroskaTrackContext *) subtitlecontext)->send_dvd_event = TRUE;
5624 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_HDMVPGS)) {
5625 caps = gst_caps_new_empty_simple ("subpicture/x-pgs");
5626 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_KATE)) {
5627 caps = gst_caps_new_empty_simple ("subtitle/x-kate");
5628 context->stream_headers =
5629 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
5630 context->codec_priv_size);
5631 /* FIXME: mark stream as broken and skip if there are no stream headers */
5632 context->send_stream_headers = TRUE;
5634 GST_DEBUG ("Unknown subtitle stream: codec_id='%s'", codec_id);
5635 caps = gst_caps_new_empty_simple ("application/x-subtitle-unknown");
5638 if (data != NULL && size > 0) {
5641 buf = gst_buffer_new_wrapped (g_memdup (data, size), size);
5642 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, buf, NULL);
5643 gst_buffer_unref (buf);
5651 gst_matroska_demux_set_index (GstElement * element, GstIndex * index)
5653 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5655 GST_OBJECT_LOCK (demux);
5656 if (demux->common.element_index)
5657 gst_object_unref (demux->common.element_index);
5658 demux->common.element_index = index ? gst_object_ref (index) : NULL;
5659 GST_OBJECT_UNLOCK (demux);
5660 GST_DEBUG_OBJECT (demux, "Set index %" GST_PTR_FORMAT,
5661 demux->common.element_index);
5665 gst_matroska_demux_get_index (GstElement * element)
5667 GstIndex *result = NULL;
5668 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5670 GST_OBJECT_LOCK (demux);
5671 if (demux->common.element_index)
5672 result = gst_object_ref (demux->common.element_index);
5673 GST_OBJECT_UNLOCK (demux);
5675 GST_DEBUG_OBJECT (demux, "Returning index %" GST_PTR_FORMAT, result);
5681 static GstStateChangeReturn
5682 gst_matroska_demux_change_state (GstElement * element,
5683 GstStateChange transition)
5685 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5686 GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
5688 /* handle upwards state changes here */
5689 switch (transition) {
5694 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
5696 /* handle downwards state changes */
5697 switch (transition) {
5698 case GST_STATE_CHANGE_PAUSED_TO_READY:
5699 gst_matroska_demux_reset (GST_ELEMENT (demux));
5709 gst_matroska_demux_set_property (GObject * object,
5710 guint prop_id, const GValue * value, GParamSpec * pspec)
5712 GstMatroskaDemux *demux;
5714 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
5715 demux = GST_MATROSKA_DEMUX (object);
5718 case ARG_MAX_GAP_TIME:
5719 GST_OBJECT_LOCK (demux);
5720 demux->max_gap_time = g_value_get_uint64 (value);
5721 GST_OBJECT_UNLOCK (demux);
5724 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
5730 gst_matroska_demux_get_property (GObject * object,
5731 guint prop_id, GValue * value, GParamSpec * pspec)
5733 GstMatroskaDemux *demux;
5735 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
5736 demux = GST_MATROSKA_DEMUX (object);
5739 case ARG_MAX_GAP_TIME:
5740 GST_OBJECT_LOCK (demux);
5741 g_value_set_uint64 (value, demux->max_gap_time);
5742 GST_OBJECT_UNLOCK (demux);
5745 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
5751 gst_matroska_demux_plugin_init (GstPlugin * plugin)
5755 /* parser helper separate debug */
5756 GST_DEBUG_CATEGORY_INIT (ebmlread_debug, "ebmlread",
5757 0, "EBML stream helper class");
5759 /* create an elementfactory for the matroska_demux element */
5760 if (!gst_element_register (plugin, "matroskademux",
5761 GST_RANK_PRIMARY, GST_TYPE_MATROSKA_DEMUX))