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 demux->common.num_streams++;
437 g_assert (demux->common.src->len == demux->common.num_streams);
439 GST_DEBUG_OBJECT (demux, "Stream number %d", context->index);
441 /* try reading the trackentry headers */
442 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
443 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
447 /* track number (unique stream ID) */
448 case GST_MATROSKA_ID_TRACKNUMBER:{
451 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
455 GST_ERROR_OBJECT (demux, "Invalid TrackNumber 0");
456 ret = GST_FLOW_ERROR;
458 } else if (!gst_matroska_read_common_tracknumber_unique (&demux->common,
460 GST_ERROR_OBJECT (demux, "TrackNumber %" G_GUINT64_FORMAT
461 " is not unique", num);
462 ret = GST_FLOW_ERROR;
466 GST_DEBUG_OBJECT (demux, "TrackNumber: %" G_GUINT64_FORMAT, num);
470 /* track UID (unique identifier) */
471 case GST_MATROSKA_ID_TRACKUID:{
474 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
478 GST_ERROR_OBJECT (demux, "Invalid TrackUID 0");
479 ret = GST_FLOW_ERROR;
483 GST_DEBUG_OBJECT (demux, "TrackUID: %" G_GUINT64_FORMAT, num);
488 /* track type (video, audio, combined, subtitle, etc.) */
489 case GST_MATROSKA_ID_TRACKTYPE:{
492 if ((ret = gst_ebml_read_uint (ebml, &id, &track_type)) != GST_FLOW_OK) {
496 if (context->type != 0 && context->type != track_type) {
497 GST_WARNING_OBJECT (demux,
498 "More than one tracktype defined in a TrackEntry - skipping");
500 } else if (track_type < 1 || track_type > 254) {
501 GST_WARNING_OBJECT (demux, "Invalid TrackType %" G_GUINT64_FORMAT,
506 GST_DEBUG_OBJECT (demux, "TrackType: %" G_GUINT64_FORMAT, track_type);
508 /* ok, so we're actually going to reallocate this thing */
509 switch (track_type) {
510 case GST_MATROSKA_TRACK_TYPE_VIDEO:
511 gst_matroska_track_init_video_context (&context);
513 case GST_MATROSKA_TRACK_TYPE_AUDIO:
514 gst_matroska_track_init_audio_context (&context);
516 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
517 gst_matroska_track_init_subtitle_context (&context);
519 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
520 case GST_MATROSKA_TRACK_TYPE_LOGO:
521 case GST_MATROSKA_TRACK_TYPE_BUTTONS:
522 case GST_MATROSKA_TRACK_TYPE_CONTROL:
524 GST_WARNING_OBJECT (demux,
525 "Unknown or unsupported TrackType %" G_GUINT64_FORMAT,
530 g_ptr_array_index (demux->common.src, demux->common.num_streams - 1)
535 /* tracktype specific stuff for video */
536 case GST_MATROSKA_ID_TRACKVIDEO:{
537 GstMatroskaTrackVideoContext *videocontext;
539 DEBUG_ELEMENT_START (demux, ebml, "TrackVideo");
541 if (!gst_matroska_track_init_video_context (&context)) {
542 GST_WARNING_OBJECT (demux,
543 "TrackVideo element in non-video track - ignoring track");
544 ret = GST_FLOW_ERROR;
546 } else if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
549 videocontext = (GstMatroskaTrackVideoContext *) context;
550 g_ptr_array_index (demux->common.src, demux->common.num_streams - 1)
553 while (ret == GST_FLOW_OK &&
554 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
555 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
559 /* Should be one level up but some broken muxers write it here. */
560 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
563 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
567 GST_WARNING_OBJECT (demux, "Invalid TrackDefaultDuration 0");
571 GST_DEBUG_OBJECT (demux,
572 "TrackDefaultDuration: %" G_GUINT64_FORMAT, num);
573 context->default_duration = num;
577 /* video framerate */
578 /* NOTE: This one is here only for backward compatibility.
579 * Use _TRACKDEFAULDURATION one level up. */
580 case GST_MATROSKA_ID_VIDEOFRAMERATE:{
583 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
587 GST_WARNING_OBJECT (demux, "Invalid TrackVideoFPS %lf", num);
591 GST_DEBUG_OBJECT (demux, "TrackVideoFrameRate: %lf", num);
592 if (context->default_duration == 0)
593 context->default_duration =
594 gst_gdouble_to_guint64 ((gdouble) GST_SECOND * (1.0 / num));
595 videocontext->default_fps = num;
599 /* width of the size to display the video at */
600 case GST_MATROSKA_ID_VIDEODISPLAYWIDTH:{
603 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
607 GST_WARNING_OBJECT (demux, "Invalid TrackVideoDisplayWidth 0");
611 GST_DEBUG_OBJECT (demux,
612 "TrackVideoDisplayWidth: %" G_GUINT64_FORMAT, num);
613 videocontext->display_width = num;
617 /* height of the size to display the video at */
618 case GST_MATROSKA_ID_VIDEODISPLAYHEIGHT:{
621 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
625 GST_WARNING_OBJECT (demux, "Invalid TrackVideoDisplayHeight 0");
629 GST_DEBUG_OBJECT (demux,
630 "TrackVideoDisplayHeight: %" G_GUINT64_FORMAT, num);
631 videocontext->display_height = num;
635 /* width of the video in the file */
636 case GST_MATROSKA_ID_VIDEOPIXELWIDTH:{
639 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
643 GST_WARNING_OBJECT (demux, "Invalid TrackVideoPixelWidth 0");
647 GST_DEBUG_OBJECT (demux,
648 "TrackVideoPixelWidth: %" G_GUINT64_FORMAT, num);
649 videocontext->pixel_width = num;
653 /* height of the video in the file */
654 case GST_MATROSKA_ID_VIDEOPIXELHEIGHT:{
657 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
661 GST_WARNING_OBJECT (demux, "Invalid TrackVideoPixelHeight 0");
665 GST_DEBUG_OBJECT (demux,
666 "TrackVideoPixelHeight: %" G_GUINT64_FORMAT, num);
667 videocontext->pixel_height = num;
671 /* whether the video is interlaced */
672 case GST_MATROSKA_ID_VIDEOFLAGINTERLACED:{
675 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
679 context->flags |= GST_MATROSKA_VIDEOTRACK_INTERLACED;
681 context->flags &= ~GST_MATROSKA_VIDEOTRACK_INTERLACED;
682 GST_DEBUG_OBJECT (demux, "TrackVideoInterlaced: %d",
683 (context->flags & GST_MATROSKA_VIDEOTRACK_INTERLACED) ? 1 :
688 /* aspect ratio behaviour */
689 case GST_MATROSKA_ID_VIDEOASPECTRATIOTYPE:{
692 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
695 if (num != GST_MATROSKA_ASPECT_RATIO_MODE_FREE &&
696 num != GST_MATROSKA_ASPECT_RATIO_MODE_KEEP &&
697 num != GST_MATROSKA_ASPECT_RATIO_MODE_FIXED) {
698 GST_WARNING_OBJECT (demux,
699 "Unknown TrackVideoAspectRatioType 0x%x", (guint) num);
702 GST_DEBUG_OBJECT (demux,
703 "TrackVideoAspectRatioType: %" G_GUINT64_FORMAT, num);
704 videocontext->asr_mode = num;
708 /* colourspace (only matters for raw video) fourcc */
709 case GST_MATROSKA_ID_VIDEOCOLOURSPACE:{
714 gst_ebml_read_binary (ebml, &id, &data,
715 &datalen)) != GST_FLOW_OK)
720 GST_WARNING_OBJECT (demux,
721 "Invalid TrackVideoColourSpace length %" G_GUINT64_FORMAT,
726 memcpy (&videocontext->fourcc, data, 4);
727 GST_DEBUG_OBJECT (demux,
728 "TrackVideoColourSpace: %" GST_FOURCC_FORMAT,
729 GST_FOURCC_ARGS (videocontext->fourcc));
735 GST_WARNING_OBJECT (demux,
736 "Unknown TrackVideo subelement 0x%x - ignoring", id);
738 case GST_MATROSKA_ID_VIDEOSTEREOMODE:
739 case GST_MATROSKA_ID_VIDEODISPLAYUNIT:
740 case GST_MATROSKA_ID_VIDEOPIXELCROPBOTTOM:
741 case GST_MATROSKA_ID_VIDEOPIXELCROPTOP:
742 case GST_MATROSKA_ID_VIDEOPIXELCROPLEFT:
743 case GST_MATROSKA_ID_VIDEOPIXELCROPRIGHT:
744 case GST_MATROSKA_ID_VIDEOGAMMAVALUE:
745 ret = gst_ebml_read_skip (ebml);
750 DEBUG_ELEMENT_STOP (demux, ebml, "TrackVideo", ret);
754 /* tracktype specific stuff for audio */
755 case GST_MATROSKA_ID_TRACKAUDIO:{
756 GstMatroskaTrackAudioContext *audiocontext;
758 DEBUG_ELEMENT_START (demux, ebml, "TrackAudio");
760 if (!gst_matroska_track_init_audio_context (&context)) {
761 GST_WARNING_OBJECT (demux,
762 "TrackAudio element in non-audio track - ignoring track");
763 ret = GST_FLOW_ERROR;
767 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
770 audiocontext = (GstMatroskaTrackAudioContext *) context;
771 g_ptr_array_index (demux->common.src, demux->common.num_streams - 1)
774 while (ret == GST_FLOW_OK &&
775 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
776 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
781 case GST_MATROSKA_ID_AUDIOSAMPLINGFREQ:{
784 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
789 GST_WARNING_OBJECT (demux,
790 "Invalid TrackAudioSamplingFrequency %lf", num);
794 GST_DEBUG_OBJECT (demux, "TrackAudioSamplingFrequency: %lf", num);
795 audiocontext->samplerate = num;
800 case GST_MATROSKA_ID_AUDIOBITDEPTH:{
803 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
807 GST_WARNING_OBJECT (demux, "Invalid TrackAudioBitDepth 0");
811 GST_DEBUG_OBJECT (demux, "TrackAudioBitDepth: %" G_GUINT64_FORMAT,
813 audiocontext->bitdepth = num;
818 case GST_MATROSKA_ID_AUDIOCHANNELS:{
821 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
825 GST_WARNING_OBJECT (demux, "Invalid TrackAudioChannels 0");
829 GST_DEBUG_OBJECT (demux, "TrackAudioChannels: %" G_GUINT64_FORMAT,
831 audiocontext->channels = num;
836 GST_WARNING_OBJECT (demux,
837 "Unknown TrackAudio subelement 0x%x - ignoring", id);
839 case GST_MATROSKA_ID_AUDIOCHANNELPOSITIONS:
840 case GST_MATROSKA_ID_AUDIOOUTPUTSAMPLINGFREQ:
841 ret = gst_ebml_read_skip (ebml);
846 DEBUG_ELEMENT_STOP (demux, ebml, "TrackAudio", ret);
851 /* codec identifier */
852 case GST_MATROSKA_ID_CODECID:{
855 if ((ret = gst_ebml_read_ascii (ebml, &id, &text)) != GST_FLOW_OK)
858 GST_DEBUG_OBJECT (demux, "CodecID: %s", GST_STR_NULL (text));
859 context->codec_id = text;
863 /* codec private data */
864 case GST_MATROSKA_ID_CODECPRIVATE:{
869 gst_ebml_read_binary (ebml, &id, &data, &size)) != GST_FLOW_OK)
872 context->codec_priv = data;
873 context->codec_priv_size = size;
875 GST_DEBUG_OBJECT (demux, "CodecPrivate of size %" G_GUINT64_FORMAT,
880 /* name of the codec */
881 case GST_MATROSKA_ID_CODECNAME:{
884 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
887 GST_DEBUG_OBJECT (demux, "CodecName: %s", GST_STR_NULL (text));
888 context->codec_name = text;
892 /* name of this track */
893 case GST_MATROSKA_ID_TRACKNAME:{
896 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
899 context->name = text;
900 GST_DEBUG_OBJECT (demux, "TrackName: %s", GST_STR_NULL (text));
904 /* language (matters for audio/subtitles, mostly) */
905 case GST_MATROSKA_ID_TRACKLANGUAGE:{
908 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
912 context->language = text;
915 if (strlen (context->language) >= 4 && context->language[3] == '-')
916 context->language[3] = '\0';
918 GST_DEBUG_OBJECT (demux, "TrackLanguage: %s",
919 GST_STR_NULL (context->language));
923 /* whether this is actually used */
924 case GST_MATROSKA_ID_TRACKFLAGENABLED:{
927 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
931 context->flags |= GST_MATROSKA_TRACK_ENABLED;
933 context->flags &= ~GST_MATROSKA_TRACK_ENABLED;
935 GST_DEBUG_OBJECT (demux, "TrackEnabled: %d",
936 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
940 /* whether it's the default for this track type */
941 case GST_MATROSKA_ID_TRACKFLAGDEFAULT:{
944 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
948 context->flags |= GST_MATROSKA_TRACK_DEFAULT;
950 context->flags &= ~GST_MATROSKA_TRACK_DEFAULT;
952 GST_DEBUG_OBJECT (demux, "TrackDefault: %d",
953 (context->flags & GST_MATROSKA_TRACK_DEFAULT) ? 1 : 0);
957 /* whether the track must be used during playback */
958 case GST_MATROSKA_ID_TRACKFLAGFORCED:{
961 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
965 context->flags |= GST_MATROSKA_TRACK_FORCED;
967 context->flags &= ~GST_MATROSKA_TRACK_FORCED;
969 GST_DEBUG_OBJECT (demux, "TrackForced: %d",
970 (context->flags & GST_MATROSKA_TRACK_FORCED) ? 1 : 0);
974 /* lacing (like MPEG, where blocks don't end/start on frame
976 case GST_MATROSKA_ID_TRACKFLAGLACING:{
979 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
983 context->flags |= GST_MATROSKA_TRACK_LACING;
985 context->flags &= ~GST_MATROSKA_TRACK_LACING;
987 GST_DEBUG_OBJECT (demux, "TrackLacing: %d",
988 (context->flags & GST_MATROSKA_TRACK_LACING) ? 1 : 0);
992 /* default length (in time) of one data block in this track */
993 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
996 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1001 GST_WARNING_OBJECT (demux, "Invalid TrackDefaultDuration 0");
1005 GST_DEBUG_OBJECT (demux, "TrackDefaultDuration: %" G_GUINT64_FORMAT,
1007 context->default_duration = num;
1011 case GST_MATROSKA_ID_CONTENTENCODINGS:{
1012 ret = gst_matroska_read_common_read_track_encodings (&demux->common,
1017 case GST_MATROSKA_ID_TRACKTIMECODESCALE:{
1020 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
1024 GST_WARNING_OBJECT (demux, "Invalid TrackTimeCodeScale %lf", num);
1028 GST_DEBUG_OBJECT (demux, "TrackTimeCodeScale: %lf", num);
1029 context->timecodescale = num;
1034 GST_WARNING ("Unknown TrackEntry subelement 0x%x - ignoring", id);
1037 /* we ignore these because they're nothing useful (i.e. crap)
1038 * or simply not implemented yet. */
1039 case GST_MATROSKA_ID_TRACKMINCACHE:
1040 case GST_MATROSKA_ID_TRACKMAXCACHE:
1041 case GST_MATROSKA_ID_MAXBLOCKADDITIONID:
1042 case GST_MATROSKA_ID_TRACKATTACHMENTLINK:
1043 case GST_MATROSKA_ID_TRACKOVERLAY:
1044 case GST_MATROSKA_ID_TRACKTRANSLATE:
1045 case GST_MATROSKA_ID_TRACKOFFSET:
1046 case GST_MATROSKA_ID_CODECSETTINGS:
1047 case GST_MATROSKA_ID_CODECINFOURL:
1048 case GST_MATROSKA_ID_CODECDOWNLOADURL:
1049 case GST_MATROSKA_ID_CODECDECODEALL:
1050 ret = gst_ebml_read_skip (ebml);
1055 DEBUG_ELEMENT_STOP (demux, ebml, "TrackEntry", ret);
1057 /* Decode codec private data if necessary */
1058 if (context->encodings && context->encodings->len > 0 && context->codec_priv
1059 && context->codec_priv_size > 0) {
1060 if (!gst_matroska_decode_data (context->encodings,
1061 &context->codec_priv, &context->codec_priv_size,
1062 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
1063 GST_WARNING_OBJECT (demux, "Decoding codec private data failed");
1064 ret = GST_FLOW_ERROR;
1068 if (context->type == 0 || context->codec_id == NULL || (ret != GST_FLOW_OK
1069 && ret != GST_FLOW_EOS)) {
1070 if (ret == GST_FLOW_OK || ret == GST_FLOW_EOS)
1071 GST_WARNING_OBJECT (ebml, "Unknown stream/codec in track entry header");
1073 demux->common.num_streams--;
1074 g_ptr_array_remove_index (demux->common.src, demux->common.num_streams);
1075 g_assert (demux->common.src->len == demux->common.num_streams);
1077 gst_matroska_track_free (context);
1083 /* now create the GStreamer connectivity */
1084 switch (context->type) {
1085 case GST_MATROSKA_TRACK_TYPE_VIDEO:{
1086 GstMatroskaTrackVideoContext *videocontext =
1087 (GstMatroskaTrackVideoContext *) context;
1089 padname = g_strdup_printf ("video_%u", demux->num_v_streams++);
1090 templ = gst_element_class_get_pad_template (klass, "video_%u");
1091 caps = gst_matroska_demux_video_caps (videocontext,
1092 context->codec_id, context->codec_priv,
1093 context->codec_priv_size, &codec, &riff_fourcc);
1096 list = gst_tag_list_new (GST_TAG_VIDEO_CODEC, codec, NULL);
1102 case GST_MATROSKA_TRACK_TYPE_AUDIO:{
1103 GstMatroskaTrackAudioContext *audiocontext =
1104 (GstMatroskaTrackAudioContext *) context;
1106 padname = g_strdup_printf ("audio_%u", demux->num_a_streams++);
1107 templ = gst_element_class_get_pad_template (klass, "audio_%u");
1108 caps = gst_matroska_demux_audio_caps (audiocontext,
1109 context->codec_id, context->codec_priv, context->codec_priv_size,
1110 &codec, &riff_audio_fmt);
1113 list = gst_tag_list_new (GST_TAG_AUDIO_CODEC, codec, NULL);
1119 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:{
1120 GstMatroskaTrackSubtitleContext *subtitlecontext =
1121 (GstMatroskaTrackSubtitleContext *) context;
1123 padname = g_strdup_printf ("subtitle_%u", demux->num_t_streams++);
1124 templ = gst_element_class_get_pad_template (klass, "subtitle_%u");
1125 caps = gst_matroska_demux_subtitle_caps (subtitlecontext,
1126 context->codec_id, context->codec_priv, context->codec_priv_size);
1130 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1131 case GST_MATROSKA_TRACK_TYPE_LOGO:
1132 case GST_MATROSKA_TRACK_TYPE_BUTTONS:
1133 case GST_MATROSKA_TRACK_TYPE_CONTROL:
1135 /* we should already have quit by now */
1136 g_assert_not_reached ();
1139 if ((context->language == NULL || *context->language == '\0') &&
1140 (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO ||
1141 context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
1142 GST_LOG ("stream %d: language=eng (assuming default)", context->index);
1143 context->language = g_strdup ("eng");
1146 if (context->language) {
1150 list = gst_tag_list_new_empty ();
1152 /* Matroska contains ISO 639-2B codes, we want ISO 639-1 */
1153 lang = gst_tag_get_language_code (context->language);
1154 gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
1155 GST_TAG_LANGUAGE_CODE, (lang) ? lang : context->language, NULL);
1159 GST_WARNING_OBJECT (demux, "could not determine caps for stream with "
1160 "codec_id='%s'", context->codec_id);
1161 switch (context->type) {
1162 case GST_MATROSKA_TRACK_TYPE_VIDEO:
1163 caps = gst_caps_new_empty_simple ("video/x-unknown");
1165 case GST_MATROSKA_TRACK_TYPE_AUDIO:
1166 caps = gst_caps_new_empty_simple ("audio/x-unknown");
1168 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
1169 caps = gst_caps_new_empty_simple ("application/x-subtitle-unknown");
1171 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1173 caps = gst_caps_new_empty_simple ("application/x-matroska-unknown");
1176 gst_caps_set_simple (caps, "codec-id", G_TYPE_STRING, context->codec_id,
1179 /* add any unrecognised riff fourcc / audio format, but after codec-id */
1180 if (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO && riff_audio_fmt != 0)
1181 gst_caps_set_simple (caps, "format", G_TYPE_INT, riff_audio_fmt, NULL);
1182 else if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO && riff_fourcc != 0) {
1183 gchar *fstr = g_strdup_printf ("%" GST_FOURCC_FORMAT,
1184 GST_FOURCC_ARGS (riff_fourcc));
1185 gst_caps_set_simple (caps, "fourcc", G_TYPE_STRING, fstr, NULL);
1188 } else if (context->stream_headers != NULL) {
1189 gst_matroska_demux_add_stream_headers_to_caps (demux,
1190 context->stream_headers, caps);
1193 /* the pad in here */
1194 context->pad = gst_pad_new_from_template (templ, padname);
1195 context->caps = caps;
1197 gst_pad_set_event_function (context->pad,
1198 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_event));
1199 gst_pad_set_query_function (context->pad,
1200 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_query));
1202 GST_INFO_OBJECT (demux, "Adding pad '%s' with caps %" GST_PTR_FORMAT,
1205 context->pending_tags = list;
1207 gst_pad_set_element_private (context->pad, context);
1209 gst_pad_use_fixed_caps (context->pad);
1210 gst_pad_set_active (context->pad, TRUE);
1213 gst_pad_create_stream_id_printf (context->pad, GST_ELEMENT_CAST (demux),
1214 "%03" G_GUINT64_FORMAT, context->uid);
1216 gst_pad_get_sticky_event (demux->common.sinkpad, GST_EVENT_STREAM_START,
1219 if (gst_event_parse_group_id (stream_start, &demux->group_id))
1220 demux->have_group_id = TRUE;
1222 demux->have_group_id = FALSE;
1223 gst_event_unref (stream_start);
1224 } else if (!demux->have_group_id) {
1225 demux->have_group_id = TRUE;
1226 demux->group_id = gst_util_group_id_next ();
1229 stream_start = gst_event_new_stream_start (stream_id);
1231 if (demux->have_group_id)
1232 gst_event_set_group_id (stream_start, demux->group_id);
1233 stream_flags = GST_STREAM_FLAG_NONE;
1234 if (context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)
1235 stream_flags |= GST_STREAM_FLAG_SPARSE;
1236 if (context->flags & GST_MATROSKA_TRACK_DEFAULT)
1237 stream_flags |= GST_STREAM_FLAG_SELECT;
1238 gst_event_set_stream_flags (stream_start, stream_flags);
1239 gst_pad_push_event (context->pad, stream_start);
1240 gst_pad_set_caps (context->pad, context->caps);
1242 gst_element_add_pad (GST_ELEMENT (demux), context->pad);
1243 gst_flow_combiner_add_pad (demux->flowcombiner, context->pad);
1252 gst_matroska_demux_query (GstMatroskaDemux * demux, GstPad * pad,
1255 gboolean res = FALSE;
1256 GstMatroskaTrackContext *context = NULL;
1259 context = gst_pad_get_element_private (pad);
1262 switch (GST_QUERY_TYPE (query)) {
1263 case GST_QUERY_POSITION:
1267 gst_query_parse_position (query, &format, NULL);
1270 if (format == GST_FORMAT_TIME) {
1271 GST_OBJECT_LOCK (demux);
1273 gst_query_set_position (query, GST_FORMAT_TIME,
1274 MAX (context->pos, demux->stream_start_time) -
1275 demux->stream_start_time);
1277 gst_query_set_position (query, GST_FORMAT_TIME,
1278 MAX (demux->common.segment.position, demux->stream_start_time) -
1279 demux->stream_start_time);
1280 GST_OBJECT_UNLOCK (demux);
1281 } else if (format == GST_FORMAT_DEFAULT && context
1282 && context->default_duration) {
1283 GST_OBJECT_LOCK (demux);
1284 gst_query_set_position (query, GST_FORMAT_DEFAULT,
1285 context->pos / context->default_duration);
1286 GST_OBJECT_UNLOCK (demux);
1288 GST_DEBUG_OBJECT (demux,
1289 "only position query in TIME and DEFAULT format is supported");
1295 case GST_QUERY_DURATION:
1299 gst_query_parse_duration (query, &format, NULL);
1302 if (format == GST_FORMAT_TIME) {
1303 GST_OBJECT_LOCK (demux);
1304 gst_query_set_duration (query, GST_FORMAT_TIME,
1305 demux->common.segment.duration);
1306 GST_OBJECT_UNLOCK (demux);
1307 } else if (format == GST_FORMAT_DEFAULT && context
1308 && context->default_duration) {
1309 GST_OBJECT_LOCK (demux);
1310 gst_query_set_duration (query, GST_FORMAT_DEFAULT,
1311 demux->common.segment.duration / context->default_duration);
1312 GST_OBJECT_UNLOCK (demux);
1314 GST_DEBUG_OBJECT (demux,
1315 "only duration query in TIME and DEFAULT format is supported");
1321 case GST_QUERY_SEEKING:
1325 gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
1326 GST_OBJECT_LOCK (demux);
1327 if (fmt == GST_FORMAT_TIME) {
1330 if (demux->streaming) {
1331 /* assuming we'll be able to get an index ... */
1332 seekable = demux->seekable;
1337 gst_query_set_seeking (query, GST_FORMAT_TIME, seekable,
1338 0, demux->common.segment.duration);
1341 GST_OBJECT_UNLOCK (demux);
1344 case GST_QUERY_SEGMENT:
1349 format = demux->common.segment.format;
1352 gst_segment_to_stream_time (&demux->common.segment, format,
1353 demux->common.segment.start);
1354 if ((stop = demux->common.segment.stop) == -1)
1355 stop = demux->common.segment.duration;
1358 gst_segment_to_stream_time (&demux->common.segment, format, stop);
1360 gst_query_set_segment (query, demux->common.segment.rate, format, start,
1367 res = gst_pad_query_default (pad, (GstObject *) demux, query);
1370 GST_ELEMENT_CLASS (parent_class)->query (GST_ELEMENT_CAST (demux),
1379 gst_matroska_demux_element_query (GstElement * element, GstQuery * query)
1381 return gst_matroska_demux_query (GST_MATROSKA_DEMUX (element), NULL, query);
1385 gst_matroska_demux_handle_src_query (GstPad * pad, GstObject * parent,
1388 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
1390 return gst_matroska_demux_query (demux, pad, query);
1393 /* returns FALSE if there are no pads to deliver event to,
1394 * otherwise TRUE (whatever the outcome of event sending),
1395 * takes ownership of the passed event! */
1397 gst_matroska_demux_send_event (GstMatroskaDemux * demux, GstEvent * event)
1399 gboolean ret = FALSE;
1402 g_return_val_if_fail (event != NULL, FALSE);
1404 GST_DEBUG_OBJECT (demux, "Sending event of type %s to all source pads",
1405 GST_EVENT_TYPE_NAME (event));
1407 g_assert (demux->common.src->len == demux->common.num_streams);
1408 for (i = 0; i < demux->common.src->len; i++) {
1409 GstMatroskaTrackContext *stream;
1411 stream = g_ptr_array_index (demux->common.src, i);
1412 gst_event_ref (event);
1413 gst_pad_push_event (stream->pad, event);
1417 gst_event_unref (event);
1422 gst_matroska_demux_send_tags (GstMatroskaDemux * demux)
1426 if (G_UNLIKELY (demux->common.global_tags != NULL)) {
1427 GstEvent *tag_event;
1428 gst_tag_list_add (demux->common.global_tags, GST_TAG_MERGE_REPLACE,
1429 GST_TAG_CONTAINER_FORMAT, "Matroska", NULL);
1430 GST_DEBUG_OBJECT (demux, "Sending global_tags %p : %" GST_PTR_FORMAT,
1431 demux->common.global_tags, demux->common.global_tags);
1433 tag_event = gst_event_new_tag (demux->common.global_tags);
1435 for (i = 0; i < demux->common.src->len; i++) {
1436 GstMatroskaTrackContext *stream;
1438 stream = g_ptr_array_index (demux->common.src, i);
1439 gst_pad_push_event (stream->pad, gst_event_ref (tag_event));
1442 gst_event_unref (tag_event);
1443 demux->common.global_tags = NULL;
1446 g_assert (demux->common.src->len == demux->common.num_streams);
1447 for (i = 0; i < demux->common.src->len; i++) {
1448 GstMatroskaTrackContext *stream;
1450 stream = g_ptr_array_index (demux->common.src, i);
1452 if (G_UNLIKELY (stream->pending_tags != NULL)) {
1453 GST_DEBUG_OBJECT (demux, "Sending pending_tags %p for pad %s:%s : %"
1454 GST_PTR_FORMAT, stream->pending_tags,
1455 GST_DEBUG_PAD_NAME (stream->pad), stream->pending_tags);
1456 gst_pad_push_event (stream->pad,
1457 gst_event_new_tag (stream->pending_tags));
1458 stream->pending_tags = NULL;
1464 gst_matroska_demux_element_send_event (GstElement * element, GstEvent * event)
1466 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
1469 g_return_val_if_fail (event != NULL, FALSE);
1471 if (GST_EVENT_TYPE (event) == GST_EVENT_SEEK) {
1472 res = gst_matroska_demux_handle_seek_event (demux, NULL, event);
1474 GST_WARNING_OBJECT (demux, "Unhandled event of type %s",
1475 GST_EVENT_TYPE_NAME (event));
1478 gst_event_unref (event);
1483 gst_matroska_demux_move_to_entry (GstMatroskaDemux * demux,
1484 GstMatroskaIndex * entry, gboolean reset, gboolean update)
1488 GST_OBJECT_LOCK (demux);
1491 /* seek (relative to matroska segment) */
1492 /* position might be invalid; will error when streaming resumes ... */
1493 demux->common.offset = entry->pos + demux->common.ebml_segment_start;
1494 demux->next_cluster_offset = 0;
1496 GST_DEBUG_OBJECT (demux,
1497 "Seeked to offset %" G_GUINT64_FORMAT ", block %d, " "time %"
1498 GST_TIME_FORMAT, entry->pos + demux->common.ebml_segment_start,
1499 entry->block, GST_TIME_ARGS (entry->time));
1501 /* update the time */
1502 gst_matroska_read_common_reset_streams (&demux->common, entry->time, TRUE);
1503 demux->common.segment.position = entry->time;
1504 demux->seek_block = entry->block;
1505 demux->seek_first = TRUE;
1506 demux->last_stop_end = GST_CLOCK_TIME_NONE;
1509 for (i = 0; i < demux->common.src->len; i++) {
1510 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
1513 stream->to_offset = G_MAXINT64;
1515 if (stream->from_offset != -1)
1516 stream->to_offset = stream->from_offset;
1518 stream->from_offset = -1;
1519 stream->from_time = GST_CLOCK_TIME_NONE;
1522 GST_OBJECT_UNLOCK (demux);
1528 gst_matroska_cluster_compare (gint64 * i1, gint64 * i2)
1538 /* searches for a cluster start from @pos,
1539 * return GST_FLOW_OK and cluster position in @pos if found */
1540 static GstFlowReturn
1541 gst_matroska_demux_search_cluster (GstMatroskaDemux * demux, gint64 * pos)
1543 gint64 newpos = *pos;
1545 GstFlowReturn ret = GST_FLOW_OK;
1546 const guint chunk = 64 * 1024;
1547 GstBuffer *buf = NULL;
1549 gpointer data = NULL;
1554 gint64 oldpos, oldlength;
1556 orig_offset = demux->common.offset;
1558 GST_LOG_OBJECT (demux, "searching cluster following offset %" G_GINT64_FORMAT,
1561 if (demux->clusters) {
1564 cpos = gst_util_array_binary_search (demux->clusters->data,
1565 demux->clusters->len, sizeof (gint64),
1566 (GCompareDataFunc) gst_matroska_cluster_compare,
1567 GST_SEARCH_MODE_AFTER, pos, NULL);
1570 GST_DEBUG_OBJECT (demux,
1571 "cluster reported at offset %" G_GINT64_FORMAT, *cpos);
1572 demux->common.offset = *cpos;
1573 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1574 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1575 if (ret == GST_FLOW_OK && id == GST_MATROSKA_ID_CLUSTER) {
1582 /* read in at newpos and scan for ebml cluster id */
1583 oldpos = oldlength = -1;
1585 GstByteReader reader;
1589 gst_buffer_unmap (buf, &map);
1590 gst_buffer_unref (buf);
1593 ret = gst_pad_pull_range (demux->common.sinkpad, newpos, chunk, &buf);
1594 if (ret != GST_FLOW_OK)
1596 GST_DEBUG_OBJECT (demux,
1597 "read buffer size %" G_GSIZE_FORMAT " at offset %" G_GINT64_FORMAT,
1598 gst_buffer_get_size (buf), newpos);
1599 gst_buffer_map (buf, &map, GST_MAP_READ);
1602 if (oldpos == newpos && oldlength == map.size) {
1603 GST_ERROR_OBJECT (demux, "Stuck at same position");
1604 ret = GST_FLOW_ERROR;
1608 oldlength = map.size;
1611 gst_byte_reader_init (&reader, data, size);
1613 cluster_pos = gst_byte_reader_masked_scan_uint32 (&reader, 0xffffffff,
1614 GST_MATROSKA_ID_CLUSTER, 0, gst_byte_reader_get_remaining (&reader));
1615 if (cluster_pos >= 0) {
1616 newpos += cluster_pos;
1617 /* prepare resuming at next byte */
1618 if (!gst_byte_reader_skip (&reader, cluster_pos + 1)) {
1619 GST_DEBUG_OBJECT (demux, "Need more data -> continue");
1622 GST_DEBUG_OBJECT (demux,
1623 "found cluster ebml id at offset %" G_GINT64_FORMAT, newpos);
1624 /* extra checks whether we really sync'ed to a cluster:
1625 * - either it is the first and only cluster
1626 * - either there is a cluster after this one
1627 * - either cluster length is undefined
1629 /* ok if first cluster (there may not a subsequent one) */
1630 if (newpos == demux->first_cluster_offset) {
1631 GST_DEBUG_OBJECT (demux, "cluster is first cluster -> OK");
1634 demux->common.offset = newpos;
1635 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1636 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1637 if (ret != GST_FLOW_OK) {
1638 GST_DEBUG_OBJECT (demux, "need more data -> continue");
1641 g_assert (id == GST_MATROSKA_ID_CLUSTER);
1642 GST_DEBUG_OBJECT (demux, "cluster size %" G_GUINT64_FORMAT ", prefix %d",
1644 /* ok if undefined length or first cluster */
1645 if (length == GST_EBML_SIZE_UNKNOWN || length == G_MAXUINT64) {
1646 GST_DEBUG_OBJECT (demux, "cluster has undefined length -> OK");
1650 demux->common.offset += length + needed;
1651 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1652 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1653 if (ret != GST_FLOW_OK)
1655 GST_DEBUG_OBJECT (demux, "next element is %scluster",
1656 id == GST_MATROSKA_ID_CLUSTER ? "" : "not ");
1657 if (id == GST_MATROSKA_ID_CLUSTER)
1659 /* not ok, resume */
1662 /* partial cluster id may have been in tail of buffer */
1663 newpos += MAX (gst_byte_reader_get_remaining (&reader), 4) - 3;
1668 gst_buffer_unmap (buf, &map);
1669 gst_buffer_unref (buf);
1674 demux->common.offset = orig_offset;
1679 /* bisect and scan through file for cluster starting before @time,
1680 * returns fake index entry with corresponding info on cluster */
1681 static GstMatroskaIndex *
1682 gst_matroska_demux_search_pos (GstMatroskaDemux * demux, GstClockTime time)
1684 GstMatroskaIndex *entry = NULL;
1685 GstMatroskaReadState current_state;
1686 GstClockTime otime, prev_cluster_time, current_cluster_time, cluster_time;
1687 gint64 opos, newpos, startpos = 0, current_offset;
1688 gint64 prev_cluster_offset = -1, current_cluster_offset, cluster_offset;
1689 const guint chunk = 64 * 1024;
1695 /* (under)estimate new position, resync using cluster ebml id,
1696 * and scan forward to appropriate cluster
1697 * (and re-estimate if need to go backward) */
1699 prev_cluster_time = GST_CLOCK_TIME_NONE;
1701 /* store some current state */
1702 current_state = demux->common.state;
1703 g_return_val_if_fail (current_state == GST_MATROSKA_READ_STATE_DATA, NULL);
1705 current_cluster_offset = demux->cluster_offset;
1706 current_cluster_time = demux->cluster_time;
1707 current_offset = demux->common.offset;
1709 demux->common.state = GST_MATROSKA_READ_STATE_SCANNING;
1711 /* estimate using start and current position */
1712 GST_OBJECT_LOCK (demux);
1713 opos = demux->common.offset - demux->common.ebml_segment_start;
1714 otime = demux->common.segment.position;
1715 GST_OBJECT_UNLOCK (demux);
1718 time = MAX (time, demux->stream_start_time);
1720 /* avoid division by zero in first estimation below */
1721 if (otime <= demux->stream_start_time)
1725 GST_LOG_OBJECT (demux,
1726 "opos: %" G_GUINT64_FORMAT ", otime: %" GST_TIME_FORMAT ", %"
1727 GST_TIME_FORMAT " in stream time (start %" GST_TIME_FORMAT "), time %"
1728 GST_TIME_FORMAT, opos, GST_TIME_ARGS (otime),
1729 GST_TIME_ARGS (otime - demux->stream_start_time),
1730 GST_TIME_ARGS (demux->stream_start_time), GST_TIME_ARGS (time));
1732 if (otime <= demux->stream_start_time) {
1736 gst_util_uint64_scale (opos - demux->common.ebml_segment_start,
1737 time - demux->stream_start_time,
1738 otime - demux->stream_start_time) - chunk;
1742 /* favour undershoot */
1743 newpos = newpos * 90 / 100;
1744 newpos += demux->common.ebml_segment_start;
1746 GST_DEBUG_OBJECT (demux,
1747 "estimated offset for %" GST_TIME_FORMAT ": %" G_GINT64_FORMAT,
1748 GST_TIME_ARGS (time), newpos);
1750 /* and at least start scanning before previous scan start to avoid looping */
1751 startpos = startpos * 90 / 100;
1752 if (startpos && startpos < newpos)
1755 /* read in at newpos and scan for ebml cluster id */
1759 ret = gst_matroska_demux_search_cluster (demux, &newpos);
1760 if (ret == GST_FLOW_EOS) {
1761 /* heuristic HACK */
1762 newpos = startpos * 80 / 100;
1763 GST_DEBUG_OBJECT (demux, "EOS; "
1764 "new estimated offset for %" GST_TIME_FORMAT ": %" G_GINT64_FORMAT,
1765 GST_TIME_ARGS (time), newpos);
1768 } else if (ret != GST_FLOW_OK) {
1775 /* then start scanning and parsing for cluster time,
1776 * re-estimate if overshoot, otherwise next cluster and so on */
1777 demux->common.offset = newpos;
1778 demux->cluster_time = cluster_time = GST_CLOCK_TIME_NONE;
1780 guint64 cluster_size = 0;
1782 /* peek and parse some elements */
1783 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1784 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1785 if (ret != GST_FLOW_OK)
1787 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
1788 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
1790 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
1791 if (ret != GST_FLOW_OK)
1794 if (id == GST_MATROSKA_ID_CLUSTER) {
1795 cluster_time = GST_CLOCK_TIME_NONE;
1796 if (length == G_MAXUINT64)
1799 cluster_size = length + needed;
1801 if (demux->cluster_time != GST_CLOCK_TIME_NONE &&
1802 cluster_time == GST_CLOCK_TIME_NONE) {
1803 cluster_time = demux->cluster_time * demux->common.time_scale;
1804 cluster_offset = demux->cluster_offset;
1805 GST_DEBUG_OBJECT (demux, "found cluster at offset %" G_GINT64_FORMAT
1806 " with time %" GST_TIME_FORMAT, cluster_offset,
1807 GST_TIME_ARGS (cluster_time));
1808 if (cluster_time > time) {
1809 GST_DEBUG_OBJECT (demux, "overshot target");
1810 /* cluster overshoots */
1811 if (cluster_offset == demux->first_cluster_offset) {
1812 /* but no prev one */
1813 GST_DEBUG_OBJECT (demux, "but using first cluster anyway");
1814 prev_cluster_time = cluster_time;
1815 prev_cluster_offset = cluster_offset;
1818 if (prev_cluster_time != GST_CLOCK_TIME_NONE) {
1819 /* prev cluster did not overshoot, so prev cluster is target */
1822 /* re-estimate using this new position info */
1823 opos = cluster_offset;
1824 otime = cluster_time;
1828 /* cluster undershoots, goto next one */
1829 prev_cluster_time = cluster_time;
1830 prev_cluster_offset = cluster_offset;
1831 /* skip cluster if length is defined,
1832 * otherwise will be skippingly parsed into */
1834 GST_DEBUG_OBJECT (demux, "skipping to next cluster");
1835 demux->common.offset = cluster_offset + cluster_size;
1836 demux->cluster_time = GST_CLOCK_TIME_NONE;
1838 GST_DEBUG_OBJECT (demux, "parsing/skipping cluster elements");
1845 if (ret == GST_FLOW_EOS) {
1846 if (prev_cluster_time != GST_CLOCK_TIME_NONE)
1852 entry = g_new0 (GstMatroskaIndex, 1);
1853 entry->time = prev_cluster_time;
1854 entry->pos = prev_cluster_offset - demux->common.ebml_segment_start;
1855 GST_DEBUG_OBJECT (demux, "simulated index entry; time %" GST_TIME_FORMAT
1856 ", pos %" G_GUINT64_FORMAT, GST_TIME_ARGS (entry->time), entry->pos);
1860 /* restore some state */
1861 demux->cluster_offset = current_cluster_offset;
1862 demux->cluster_time = current_cluster_time;
1863 demux->common.offset = current_offset;
1864 demux->common.state = current_state;
1870 gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
1871 GstPad * pad, GstEvent * event)
1873 GstMatroskaIndex *entry = NULL;
1874 GstMatroskaIndex scan_entry;
1876 GstSeekType cur_type, stop_type;
1878 gboolean flush, keyunit, before, after, snap_next;
1881 GstMatroskaTrackContext *track = NULL;
1882 GstSegment seeksegment = { 0, };
1883 gboolean update = TRUE;
1884 gboolean pad_locked = FALSE;
1886 GstSearchMode snap_dir;
1888 g_return_val_if_fail (event != NULL, FALSE);
1891 track = gst_pad_get_element_private (pad);
1893 GST_DEBUG_OBJECT (demux, "Have seek %" GST_PTR_FORMAT, event);
1895 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
1897 seqnum = gst_event_get_seqnum (event);
1899 /* we can only seek on time */
1900 if (format != GST_FORMAT_TIME) {
1901 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
1905 /* copy segment, we need this because we still need the old
1906 * segment when we close the current segment. */
1907 memcpy (&seeksegment, &demux->common.segment, sizeof (GstSegment));
1909 /* pull mode without index means that the actual duration is not known,
1910 * we might be playing a file that's still being recorded
1911 * so, invalidate our current duration, which is only a moving target,
1912 * and should not be used to clamp anything */
1913 if (!demux->streaming && !demux->common.index && demux->invalid_duration) {
1914 seeksegment.duration = GST_CLOCK_TIME_NONE;
1917 GST_DEBUG_OBJECT (demux, "configuring seek");
1918 /* Subtract stream_start_time so we always seek on a segment
1920 if (GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
1921 seeksegment.start -= demux->stream_start_time;
1922 seeksegment.position -= demux->stream_start_time;
1923 if (GST_CLOCK_TIME_IS_VALID (seeksegment.stop))
1924 seeksegment.stop -= demux->stream_start_time;
1926 seeksegment.stop = seeksegment.duration;
1929 gst_segment_do_seek (&seeksegment, rate, format, flags,
1930 cur_type, cur, stop_type, stop, &update);
1932 /* Restore the clip timestamp offset */
1933 if (GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
1934 seeksegment.position += demux->stream_start_time;
1935 seeksegment.start += demux->stream_start_time;
1936 if (!GST_CLOCK_TIME_IS_VALID (seeksegment.stop))
1937 seeksegment.stop = seeksegment.duration;
1938 if (GST_CLOCK_TIME_IS_VALID (seeksegment.stop))
1939 seeksegment.stop += demux->stream_start_time;
1942 /* restore segment duration (if any effect),
1943 * would be determined again when parsing, but anyway ... */
1944 seeksegment.duration = demux->common.segment.duration;
1946 flush = ! !(flags & GST_SEEK_FLAG_FLUSH);
1947 keyunit = ! !(flags & GST_SEEK_FLAG_KEY_UNIT);
1948 after = ! !(flags & GST_SEEK_FLAG_SNAP_AFTER);
1949 before = ! !(flags & GST_SEEK_FLAG_SNAP_BEFORE);
1951 /* always do full update if flushing,
1952 * otherwise problems might arise downstream with missing keyframes etc */
1953 update = update || flush;
1955 GST_DEBUG_OBJECT (demux, "New segment %" GST_SEGMENT_FORMAT, &seeksegment);
1957 /* check sanity before we start flushing and all that */
1958 snap_next = after && !before;
1959 if (seeksegment.rate < 0)
1960 snap_dir = snap_next ? GST_SEARCH_MODE_BEFORE : GST_SEARCH_MODE_AFTER;
1962 snap_dir = snap_next ? GST_SEARCH_MODE_AFTER : GST_SEARCH_MODE_BEFORE;
1964 GST_OBJECT_LOCK (demux);
1965 track = gst_matroska_read_common_get_seek_track (&demux->common, track);
1966 if ((entry = gst_matroska_read_common_do_index_seek (&demux->common, track,
1967 seeksegment.position, &demux->seek_index, &demux->seek_entry,
1968 snap_dir)) == NULL) {
1969 /* pull mode without index can scan later on */
1970 if (demux->streaming) {
1971 GST_DEBUG_OBJECT (demux, "No matching seek entry in index");
1972 GST_OBJECT_UNLOCK (demux);
1974 } else if (rate < 0.0) {
1975 /* FIXME: We should build an index during playback or when scanning
1976 * that can be used here. The reverse playback code requires seek_index
1977 * and seek_entry to be set!
1979 GST_DEBUG_OBJECT (demux,
1980 "No matching seek entry in index, needed for reverse playback");
1981 GST_OBJECT_UNLOCK (demux);
1985 GST_DEBUG_OBJECT (demux, "Seek position looks sane");
1986 GST_OBJECT_UNLOCK (demux);
1989 /* only have to update some segment,
1990 * but also still have to honour flush and so on */
1991 GST_DEBUG_OBJECT (demux, "... no update");
1992 /* bad goto, bad ... */
1996 if (demux->streaming)
2001 GstEvent *flush_event = gst_event_new_flush_start ();
2002 gst_event_set_seqnum (flush_event, seqnum);
2003 GST_DEBUG_OBJECT (demux, "Starting flush");
2004 gst_pad_push_event (demux->common.sinkpad, gst_event_ref (flush_event));
2005 gst_matroska_demux_send_event (demux, flush_event);
2007 GST_DEBUG_OBJECT (demux, "Non-flushing seek, pausing task");
2008 gst_pad_pause_task (demux->common.sinkpad);
2012 GST_PAD_STREAM_LOCK (demux->common.sinkpad);
2017 /* now grab the stream lock so that streaming cannot continue, for
2018 * non flushing seeks when the element is in PAUSED this could block
2020 GST_DEBUG_OBJECT (demux, "Waiting for streaming to stop");
2021 GST_PAD_STREAM_LOCK (demux->common.sinkpad);
2024 /* pull mode without index can do some scanning */
2025 if (!demux->streaming && !entry) {
2026 GstEvent *flush_event;
2028 /* need to stop flushing upstream as we need it next */
2030 flush_event = gst_event_new_flush_stop (TRUE);
2031 gst_event_set_seqnum (flush_event, seqnum);
2032 gst_pad_push_event (demux->common.sinkpad, flush_event);
2034 entry = gst_matroska_demux_search_pos (demux, seeksegment.position);
2035 /* keep local copy */
2037 scan_entry = *entry;
2039 entry = &scan_entry;
2041 GST_DEBUG_OBJECT (demux, "Scan failed to find matching position");
2043 flush_event = gst_event_new_flush_stop (TRUE);
2044 gst_event_set_seqnum (flush_event, seqnum);
2045 gst_matroska_demux_send_event (demux, flush_event);
2053 GST_DEBUG_OBJECT (demux, "seek to key unit, adjusting segment start from %"
2054 GST_TIME_FORMAT " to %" GST_TIME_FORMAT,
2055 GST_TIME_ARGS (seeksegment.start), GST_TIME_ARGS (entry->time));
2056 seeksegment.start = MAX (entry->time, demux->stream_start_time);
2057 seeksegment.position = seeksegment.start;
2058 seeksegment.time = seeksegment.start - demux->stream_start_time;
2061 if (demux->streaming) {
2062 GST_OBJECT_LOCK (demux);
2063 /* track real position we should start at */
2064 GST_DEBUG_OBJECT (demux, "storing segment start");
2065 demux->requested_seek_time = seeksegment.position;
2066 demux->seek_offset = entry->pos + demux->common.ebml_segment_start;
2067 GST_OBJECT_UNLOCK (demux);
2068 /* need to seek to cluster start to pick up cluster time */
2069 /* upstream takes care of flushing and all that
2070 * ... and newsegment event handling takes care of the rest */
2071 return perform_seek_to_offset (demux, rate,
2072 entry->pos + demux->common.ebml_segment_start, seqnum);
2077 GstEvent *flush_event = gst_event_new_flush_stop (TRUE);
2078 gst_event_set_seqnum (flush_event, seqnum);
2079 GST_DEBUG_OBJECT (demux, "Stopping flush");
2080 gst_pad_push_event (demux->common.sinkpad, gst_event_ref (flush_event));
2081 gst_matroska_demux_send_event (demux, flush_event);
2084 GST_OBJECT_LOCK (demux);
2085 /* now update the real segment info */
2086 GST_DEBUG_OBJECT (demux, "Committing new seek segment");
2087 memcpy (&demux->common.segment, &seeksegment, sizeof (GstSegment));
2088 GST_OBJECT_UNLOCK (demux);
2090 /* update some (segment) state */
2091 if (!gst_matroska_demux_move_to_entry (demux, entry, TRUE, update))
2094 /* notify start of new segment */
2095 if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
2098 msg = gst_message_new_segment_start (GST_OBJECT (demux),
2099 GST_FORMAT_TIME, demux->common.segment.start);
2100 gst_message_set_seqnum (msg, seqnum);
2101 gst_element_post_message (GST_ELEMENT (demux), msg);
2104 GST_OBJECT_LOCK (demux);
2105 if (demux->new_segment)
2106 gst_event_unref (demux->new_segment);
2108 /* On port from 0.10, discarded !update (for segment.update) here, FIXME? */
2109 demux->new_segment = gst_event_new_segment (&demux->common.segment);
2110 gst_event_set_seqnum (demux->new_segment, seqnum);
2111 if (demux->common.segment.rate < 0 && demux->common.segment.stop == -1)
2112 demux->to_time = demux->common.segment.position;
2114 demux->to_time = GST_CLOCK_TIME_NONE;
2115 GST_OBJECT_UNLOCK (demux);
2117 /* restart our task since it might have been stopped when we did the
2119 gst_pad_start_task (demux->common.sinkpad,
2120 (GstTaskFunction) gst_matroska_demux_loop, demux->common.sinkpad, NULL);
2122 /* streaming can continue now */
2124 GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
2132 GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
2134 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Got a seek error"));
2140 * Handle whether we can perform the seek event or if we have to let the chain
2141 * function handle seeks to build the seek indexes first.
2144 gst_matroska_demux_handle_seek_push (GstMatroskaDemux * demux, GstPad * pad,
2148 GstSeekType cur_type, stop_type;
2153 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
2158 /* we can only seek on time */
2159 if (format != GST_FORMAT_TIME) {
2160 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
2164 if (stop_type != GST_SEEK_TYPE_NONE && stop != GST_CLOCK_TIME_NONE) {
2165 GST_DEBUG_OBJECT (demux, "Seek end-time not supported in streaming mode");
2169 if (!(flags & GST_SEEK_FLAG_FLUSH)) {
2170 GST_DEBUG_OBJECT (demux,
2171 "Non-flushing seek not supported in streaming mode");
2175 if (flags & GST_SEEK_FLAG_SEGMENT) {
2176 GST_DEBUG_OBJECT (demux, "Segment seek not supported in streaming mode");
2180 /* check for having parsed index already */
2181 if (!demux->common.index_parsed) {
2182 gboolean building_index;
2185 if (!demux->index_offset) {
2186 GST_DEBUG_OBJECT (demux, "no index (location); no seek in push mode");
2190 GST_OBJECT_LOCK (demux);
2191 /* handle the seek event in the chain function */
2192 demux->common.state = GST_MATROSKA_READ_STATE_SEEK;
2193 /* no more seek can be issued until state reset to _DATA */
2195 /* copy the event */
2196 if (demux->seek_event)
2197 gst_event_unref (demux->seek_event);
2198 demux->seek_event = gst_event_ref (event);
2200 /* set the building_index flag so that only one thread can setup the
2201 * structures for index seeking. */
2202 building_index = demux->building_index;
2203 if (!building_index) {
2204 demux->building_index = TRUE;
2205 offset = demux->index_offset;
2207 GST_OBJECT_UNLOCK (demux);
2209 if (!building_index) {
2210 /* seek to the first subindex or legacy index */
2211 GST_INFO_OBJECT (demux, "Seeking to Cues at %" G_GUINT64_FORMAT, offset);
2212 return perform_seek_to_offset (demux, rate, offset,
2213 gst_event_get_seqnum (event));
2216 /* well, we are handling it already */
2220 /* delegate to tweaked regular seek */
2221 return gst_matroska_demux_handle_seek_event (demux, pad, event);
2225 gst_matroska_demux_handle_src_event (GstPad * pad, GstObject * parent,
2228 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
2229 gboolean res = TRUE;
2231 switch (GST_EVENT_TYPE (event)) {
2232 case GST_EVENT_SEEK:
2233 /* no seeking until we are (safely) ready */
2234 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
2235 GST_DEBUG_OBJECT (demux, "not ready for seeking yet");
2238 if (!demux->streaming)
2239 res = gst_matroska_demux_handle_seek_event (demux, pad, event);
2241 res = gst_matroska_demux_handle_seek_push (demux, pad, event);
2242 gst_event_unref (event);
2247 GstMatroskaTrackContext *context = gst_pad_get_element_private (pad);
2248 if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
2249 GstMatroskaTrackVideoContext *videocontext =
2250 (GstMatroskaTrackVideoContext *) context;
2252 GstClockTimeDiff diff;
2253 GstClockTime timestamp;
2255 gst_event_parse_qos (event, NULL, &proportion, &diff, ×tamp);
2257 GST_OBJECT_LOCK (demux);
2258 videocontext->earliest_time = timestamp + diff;
2259 GST_OBJECT_UNLOCK (demux);
2262 gst_event_unref (event);
2266 case GST_EVENT_TOC_SELECT:
2269 GstTocEntry *entry = NULL;
2270 GstEvent *seek_event;
2273 if (!demux->common.toc) {
2274 GST_DEBUG_OBJECT (demux, "no TOC to select");
2277 gst_event_parse_toc_select (event, &uid);
2279 GST_OBJECT_LOCK (demux);
2280 entry = gst_toc_find_entry (demux->common.toc, uid);
2281 if (entry == NULL) {
2282 GST_OBJECT_UNLOCK (demux);
2283 GST_WARNING_OBJECT (demux, "no TOC entry with given UID: %s", uid);
2286 gst_toc_entry_get_start_stop_times (entry, &start_pos, NULL);
2287 GST_OBJECT_UNLOCK (demux);
2288 seek_event = gst_event_new_seek (1.0,
2290 GST_SEEK_FLAG_FLUSH,
2291 GST_SEEK_TYPE_SET, start_pos, GST_SEEK_TYPE_SET, -1);
2292 res = gst_matroska_demux_handle_seek_event (demux, pad, seek_event);
2293 gst_event_unref (seek_event);
2297 GST_WARNING_OBJECT (demux, "received empty TOC select event");
2301 gst_event_unref (event);
2305 /* events we don't need to handle */
2306 case GST_EVENT_NAVIGATION:
2307 gst_event_unref (event);
2311 case GST_EVENT_LATENCY:
2313 res = gst_pad_push_event (demux->common.sinkpad, event);
2320 static GstFlowReturn
2321 gst_matroska_demux_seek_to_previous_keyframe (GstMatroskaDemux * demux)
2323 GstFlowReturn ret = GST_FLOW_EOS;
2324 gboolean done = TRUE;
2327 g_return_val_if_fail (demux->seek_index, GST_FLOW_EOS);
2328 g_return_val_if_fail (demux->seek_entry < demux->seek_index->len,
2331 GST_DEBUG_OBJECT (demux, "locating previous keyframe");
2333 if (!demux->seek_entry) {
2334 GST_DEBUG_OBJECT (demux, "no earlier index entry");
2338 for (i = 0; i < demux->common.src->len; i++) {
2339 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
2341 GST_DEBUG_OBJECT (demux, "segment start %" GST_TIME_FORMAT
2342 ", stream %d at %" GST_TIME_FORMAT,
2343 GST_TIME_ARGS (demux->common.segment.start), stream->index,
2344 GST_TIME_ARGS (stream->from_time));
2345 if (GST_CLOCK_TIME_IS_VALID (stream->from_time)) {
2346 if (stream->from_time > demux->common.segment.start) {
2347 GST_DEBUG_OBJECT (demux, "stream %d not finished yet", stream->index);
2351 /* nothing pushed for this stream;
2352 * likely seek entry did not start at keyframe, so all was skipped.
2353 * So we need an earlier entry */
2359 GstMatroskaIndex *entry;
2361 entry = &g_array_index (demux->seek_index, GstMatroskaIndex,
2362 --demux->seek_entry);
2363 if (!gst_matroska_demux_move_to_entry (demux, entry, FALSE, TRUE))
2373 static GstFlowReturn
2374 gst_matroska_demux_parse_tracks (GstMatroskaDemux * demux, GstEbmlRead * ebml)
2376 GstFlowReturn ret = GST_FLOW_OK;
2379 DEBUG_ELEMENT_START (demux, ebml, "Tracks");
2381 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2382 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
2386 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
2387 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
2391 /* one track within the "all-tracks" header */
2392 case GST_MATROSKA_ID_TRACKENTRY:
2393 ret = gst_matroska_demux_add_stream (demux, ebml);
2397 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
2402 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
2404 demux->tracks_parsed = TRUE;
2410 * Read signed/unsigned "EBML" numbers.
2411 * Return: number of bytes processed.
2415 gst_matroska_ebmlnum_uint (guint8 * data, guint size, guint64 * num)
2417 gint len_mask = 0x80, read = 1, n = 1, num_ffs = 0;
2425 while (read <= 8 && !(total & len_mask)) {
2432 if ((total &= (len_mask - 1)) == len_mask - 1)
2437 if (data[n] == 0xff)
2439 total = (total << 8) | data[n];
2443 if (read == num_ffs && total != 0)
2452 gst_matroska_ebmlnum_sint (guint8 * data, guint size, gint64 * num)
2457 /* read as unsigned number first */
2458 if ((res = gst_matroska_ebmlnum_uint (data, size, &unum)) < 0)
2462 if (unum == G_MAXUINT64)
2465 *num = unum - ((1 << ((7 * res) - 1)) - 1);
2471 * Mostly used for subtitles. We add void filler data for each
2472 * lagging stream to make sure we don't deadlock.
2476 gst_matroska_demux_sync_streams (GstMatroskaDemux * demux)
2480 GST_OBJECT_LOCK (demux);
2482 GST_LOG_OBJECT (demux, "Sync to %" GST_TIME_FORMAT,
2483 GST_TIME_ARGS (demux->common.segment.position));
2485 g_assert (demux->common.num_streams == demux->common.src->len);
2486 for (stream_nr = 0; stream_nr < demux->common.src->len; stream_nr++) {
2487 GstMatroskaTrackContext *context;
2489 context = g_ptr_array_index (demux->common.src, stream_nr);
2491 GST_LOG_OBJECT (demux,
2492 "Checking for resync on stream %d (%" GST_TIME_FORMAT ")", stream_nr,
2493 GST_TIME_ARGS (context->pos));
2495 if (G_LIKELY (context->type != GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
2496 GST_LOG_OBJECT (demux, "Skipping sync on non-subtitle stream");
2500 /* does it lag? 0.5 seconds is a random threshold...
2501 * lag need only be considered if we have advanced into requested segment */
2502 if (GST_CLOCK_TIME_IS_VALID (context->pos) &&
2503 GST_CLOCK_TIME_IS_VALID (demux->common.segment.position) &&
2504 demux->common.segment.position > demux->common.segment.start &&
2505 context->pos + (GST_SECOND / 2) < demux->common.segment.position) {
2508 guint64 start = context->pos;
2509 guint64 stop = demux->common.segment.position - (GST_SECOND / 2);
2511 GST_DEBUG_OBJECT (demux,
2512 "Synchronizing stream %d with other by advancing time from %"
2513 GST_TIME_FORMAT " to %" GST_TIME_FORMAT, stream_nr,
2514 GST_TIME_ARGS (start), GST_TIME_ARGS (stop));
2516 context->pos = stop;
2518 event = gst_event_new_gap (start, stop - start);
2519 GST_OBJECT_UNLOCK (demux);
2520 gst_pad_push_event (context->pad, event);
2521 GST_OBJECT_LOCK (demux);
2525 GST_OBJECT_UNLOCK (demux);
2528 static GstFlowReturn
2529 gst_matroska_demux_push_stream_headers (GstMatroskaDemux * demux,
2530 GstMatroskaTrackContext * stream)
2532 GstFlowReturn ret = GST_FLOW_OK;
2535 num = gst_buffer_list_length (stream->stream_headers);
2536 for (i = 0; i < num; ++i) {
2539 buf = gst_buffer_list_get (stream->stream_headers, i);
2540 buf = gst_buffer_copy (buf);
2542 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
2544 if (stream->set_discont) {
2545 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
2546 stream->set_discont = FALSE;
2548 GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DISCONT);
2551 /* push out all headers in one go and use last flow return */
2552 ret = gst_pad_push (stream->pad, buf);
2555 /* don't need these any longer */
2556 gst_buffer_list_unref (stream->stream_headers);
2557 stream->stream_headers = NULL;
2560 ret = gst_flow_combiner_update_flow (demux->flowcombiner, ret);
2566 gst_matroska_demux_push_dvd_clut_change_event (GstMatroskaDemux * demux,
2567 GstMatroskaTrackContext * stream)
2571 g_assert (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB));
2573 if (!stream->codec_priv)
2576 /* ideally, VobSub private data should be parsed and stored more convenient
2577 * elsewhere, but for now, only interested in a small part */
2579 /* make sure we have terminating 0 */
2580 buf = g_strndup (stream->codec_priv, stream->codec_priv_size);
2582 /* just locate and parse palette part */
2583 start = strstr (buf, "palette:");
2588 guint8 r, g, b, y, u, v;
2591 while (g_ascii_isspace (*start))
2593 for (i = 0; i < 16; i++) {
2594 if (sscanf (start, "%06x", &col) != 1)
2597 while ((*start == ',') || g_ascii_isspace (*start))
2599 /* sigh, need to convert this from vobsub pseudo-RGB to YUV */
2600 r = (col >> 16) & 0xff;
2601 g = (col >> 8) & 0xff;
2603 y = CLAMP ((0.1494 * r + 0.6061 * g + 0.2445 * b) * 219 / 255 + 16, 0,
2605 u = CLAMP (0.6066 * r - 0.4322 * g - 0.1744 * b + 128, 0, 255);
2606 v = CLAMP (-0.08435 * r - 0.3422 * g + 0.4266 * b + 128, 0, 255);
2607 clut[i] = (y << 16) | (u << 8) | v;
2610 /* got them all without problems; build and send event */
2614 s = gst_structure_new ("application/x-gst-dvd", "event", G_TYPE_STRING,
2615 "dvd-spu-clut-change", "clut00", G_TYPE_INT, clut[0], "clut01",
2616 G_TYPE_INT, clut[1], "clut02", G_TYPE_INT, clut[2], "clut03",
2617 G_TYPE_INT, clut[3], "clut04", G_TYPE_INT, clut[4], "clut05",
2618 G_TYPE_INT, clut[5], "clut06", G_TYPE_INT, clut[6], "clut07",
2619 G_TYPE_INT, clut[7], "clut08", G_TYPE_INT, clut[8], "clut09",
2620 G_TYPE_INT, clut[9], "clut10", G_TYPE_INT, clut[10], "clut11",
2621 G_TYPE_INT, clut[11], "clut12", G_TYPE_INT, clut[12], "clut13",
2622 G_TYPE_INT, clut[13], "clut14", G_TYPE_INT, clut[14], "clut15",
2623 G_TYPE_INT, clut[15], NULL);
2625 gst_pad_push_event (stream->pad,
2626 gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM_STICKY, s));
2633 gst_matroska_demux_push_codec_data_all (GstMatroskaDemux * demux)
2637 GST_OBJECT_LOCK (demux);
2639 g_assert (demux->common.num_streams == demux->common.src->len);
2640 for (stream_nr = 0; stream_nr < demux->common.src->len; stream_nr++) {
2641 GstMatroskaTrackContext *stream;
2643 stream = g_ptr_array_index (demux->common.src, stream_nr);
2645 if (stream->send_stream_headers) {
2646 if (stream->stream_headers != NULL) {
2647 gst_matroska_demux_push_stream_headers (demux, stream);
2649 /* FIXME: perhaps we can just disable and skip this stream then */
2650 GST_ELEMENT_ERROR (demux, STREAM, DECODE, (NULL),
2651 ("Failed to extract stream headers from codec private data"));
2653 stream->send_stream_headers = FALSE;
2656 if (stream->send_dvd_event) {
2657 gst_matroska_demux_push_dvd_clut_change_event (demux, stream);
2658 /* FIXME: should we send this event again after (flushing) seek ? */
2659 stream->send_dvd_event = FALSE;
2663 GST_OBJECT_UNLOCK (demux);
2666 static GstFlowReturn
2667 gst_matroska_demux_add_mpeg_seq_header (GstElement * element,
2668 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2671 guint seq_header_len;
2672 guint32 header, tmp;
2674 if (stream->codec_state) {
2675 seq_header = stream->codec_state;
2676 seq_header_len = stream->codec_state_size;
2677 } else if (stream->codec_priv) {
2678 seq_header = stream->codec_priv;
2679 seq_header_len = stream->codec_priv_size;
2684 /* Sequence header only needed for keyframes */
2685 if (GST_BUFFER_FLAG_IS_SET (*buf, GST_BUFFER_FLAG_DELTA_UNIT))
2688 if (gst_buffer_get_size (*buf) < 4)
2691 gst_buffer_extract (*buf, 0, &tmp, sizeof (guint32));
2692 header = GUINT32_FROM_BE (tmp);
2694 /* Sequence start code, if not found prepend */
2695 if (header != 0x000001b3) {
2698 GST_DEBUG_OBJECT (element, "Prepending MPEG sequence header");
2700 newbuf = gst_buffer_new_wrapped (g_memdup (seq_header, seq_header_len),
2703 gst_buffer_copy_into (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
2704 GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_MEMORY, 0,
2705 gst_buffer_get_size (*buf));
2707 gst_buffer_unref (*buf);
2714 static GstFlowReturn
2715 gst_matroska_demux_add_wvpk_header (GstElement * element,
2716 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2718 GstMatroskaTrackAudioContext *audiocontext =
2719 (GstMatroskaTrackAudioContext *) stream;
2720 GstBuffer *newbuf = NULL;
2721 GstMapInfo map, outmap;
2722 guint8 *buf_data, *data;
2730 wvh.version = GST_READ_UINT16_LE (stream->codec_priv);
2733 wvh.total_samples = -1;
2734 wvh.block_index = audiocontext->wvpk_block_index;
2736 if (audiocontext->channels <= 2) {
2737 guint32 block_samples, tmp;
2738 gsize size = gst_buffer_get_size (*buf);
2740 gst_buffer_extract (*buf, 0, &tmp, sizeof (guint32));
2741 block_samples = GUINT32_FROM_LE (tmp);
2742 /* we need to reconstruct the header of the wavpack block */
2744 /* -20 because ck_size is the size of the wavpack block -8
2745 * and lace_size is the size of the wavpack block + 12
2746 * (the three guint32 of the header that already are in the buffer) */
2747 wvh.ck_size = size + sizeof (Wavpack4Header) - 20;
2749 /* block_samples, flags and crc are already in the buffer */
2750 newbuf = gst_buffer_new_allocate (NULL, sizeof (Wavpack4Header) - 12, NULL);
2752 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2758 GST_WRITE_UINT32_LE (data + 4, wvh.ck_size);
2759 GST_WRITE_UINT16_LE (data + 8, wvh.version);
2760 GST_WRITE_UINT8 (data + 10, wvh.track_no);
2761 GST_WRITE_UINT8 (data + 11, wvh.index_no);
2762 GST_WRITE_UINT32_LE (data + 12, wvh.total_samples);
2763 GST_WRITE_UINT32_LE (data + 16, wvh.block_index);
2765 /* Append data from buf: */
2766 gst_buffer_copy_into (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
2767 GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_MEMORY, 0, size);
2769 gst_buffer_unref (*buf);
2771 audiocontext->wvpk_block_index += block_samples;
2773 guint8 *outdata = NULL;
2775 gsize buf_size, size, out_size = 0;
2776 guint32 block_samples, flags, crc, blocksize;
2778 gst_buffer_map (*buf, &map, GST_MAP_READ);
2779 buf_data = map.data;
2780 buf_size = map.size;
2783 GST_ERROR_OBJECT (element, "Too small wavpack buffer");
2784 gst_buffer_unmap (*buf, &map);
2785 return GST_FLOW_ERROR;
2791 block_samples = GST_READ_UINT32_LE (data);
2796 flags = GST_READ_UINT32_LE (data);
2799 crc = GST_READ_UINT32_LE (data);
2802 blocksize = GST_READ_UINT32_LE (data);
2806 if (blocksize == 0 || size < blocksize)
2809 g_assert ((newbuf == NULL) == (outdata == NULL));
2811 if (newbuf == NULL) {
2812 out_size = sizeof (Wavpack4Header) + blocksize;
2813 newbuf = gst_buffer_new_allocate (NULL, out_size, NULL);
2815 gst_buffer_copy_into (newbuf, *buf,
2816 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS, 0, -1);
2819 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2820 outdata = outmap.data;
2822 gst_buffer_unmap (newbuf, &outmap);
2823 out_size += sizeof (Wavpack4Header) + blocksize;
2824 gst_buffer_set_size (newbuf, out_size);
2825 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2826 outdata = outmap.data;
2829 outdata[outpos] = 'w';
2830 outdata[outpos + 1] = 'v';
2831 outdata[outpos + 2] = 'p';
2832 outdata[outpos + 3] = 'k';
2835 GST_WRITE_UINT32_LE (outdata + outpos,
2836 blocksize + sizeof (Wavpack4Header) - 8);
2837 GST_WRITE_UINT16_LE (outdata + outpos + 4, wvh.version);
2838 GST_WRITE_UINT8 (outdata + outpos + 6, wvh.track_no);
2839 GST_WRITE_UINT8 (outdata + outpos + 7, wvh.index_no);
2840 GST_WRITE_UINT32_LE (outdata + outpos + 8, wvh.total_samples);
2841 GST_WRITE_UINT32_LE (outdata + outpos + 12, wvh.block_index);
2842 GST_WRITE_UINT32_LE (outdata + outpos + 16, block_samples);
2843 GST_WRITE_UINT32_LE (outdata + outpos + 20, flags);
2844 GST_WRITE_UINT32_LE (outdata + outpos + 24, crc);
2847 memmove (outdata + outpos, data, blocksize);
2848 outpos += blocksize;
2852 gst_buffer_unmap (*buf, &map);
2853 gst_buffer_unref (*buf);
2856 gst_buffer_unmap (newbuf, &outmap);
2859 audiocontext->wvpk_block_index += block_samples;
2865 /* @text must be null-terminated */
2867 gst_matroska_demux_subtitle_chunk_has_tag (GstElement * element,
2872 g_return_val_if_fail (text != NULL, FALSE);
2874 /* yes, this might all lead to false positives ... */
2875 tag = (gchar *) text;
2876 while ((tag = strchr (tag, '<'))) {
2878 if (*tag != '\0' && *(tag + 1) == '>') {
2879 /* some common convenience ones */
2880 /* maybe any character will do here ? */
2893 if (strstr (text, "<span"))
2899 static GstFlowReturn
2900 gst_matroska_demux_check_subtitle_buffer (GstElement * element,
2901 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2903 GstMatroskaTrackSubtitleContext *sub_stream;
2904 const gchar *encoding;
2909 gboolean needs_unmap = TRUE;
2911 sub_stream = (GstMatroskaTrackSubtitleContext *) stream;
2913 if (!gst_buffer_get_size (*buf) || !gst_buffer_map (*buf, &map, GST_MAP_READ))
2916 /* Need \0-terminator at the end */
2917 if (map.data[map.size - 1] != '\0') {
2918 newbuf = gst_buffer_new_and_alloc (map.size + 1);
2920 /* Copy old buffer and add a 0 at the end */
2921 gst_buffer_fill (newbuf, 0, map.data, map.size);
2922 gst_buffer_memset (newbuf, map.size, 0, 1);
2923 gst_buffer_unmap (*buf, &map);
2925 gst_buffer_copy_into (newbuf, *buf,
2926 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS |
2927 GST_BUFFER_COPY_META, 0, -1);
2928 gst_buffer_unref (*buf);
2930 gst_buffer_map (*buf, &map, GST_MAP_READ);
2933 if (!sub_stream->invalid_utf8) {
2934 if (g_utf8_validate ((gchar *) map.data, map.size - 1, NULL)) {
2937 GST_WARNING_OBJECT (element, "subtitle stream %" G_GUINT64_FORMAT
2938 " is not valid UTF-8, this is broken according to the matroska"
2939 " specification", stream->num);
2940 sub_stream->invalid_utf8 = TRUE;
2943 /* file with broken non-UTF8 subtitle, do the best we can do to fix it */
2944 encoding = g_getenv ("GST_SUBTITLE_ENCODING");
2945 if (encoding == NULL || *encoding == '\0') {
2946 /* if local encoding is UTF-8 and no encoding specified
2947 * via the environment variable, assume ISO-8859-15 */
2948 if (g_get_charset (&encoding)) {
2949 encoding = "ISO-8859-15";
2954 g_convert_with_fallback ((gchar *) map.data, map.size, "UTF-8", encoding,
2955 (char *) "*", NULL, NULL, &err);
2958 GST_LOG_OBJECT (element, "could not convert string from '%s' to UTF-8: %s",
2959 encoding, err->message);
2963 /* invalid input encoding, fall back to ISO-8859-15 (always succeeds) */
2964 encoding = "ISO-8859-15";
2966 g_convert_with_fallback ((gchar *) map.data, map.size, "UTF-8",
2967 encoding, (char *) "*", NULL, NULL, NULL);
2970 GST_LOG_OBJECT (element, "converted subtitle text from %s to UTF-8 %s",
2971 encoding, (err) ? "(using ISO-8859-15 as fallback)" : "");
2974 utf8 = g_strdup ("invalid subtitle");
2976 newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
2977 gst_buffer_unmap (*buf, &map);
2978 gst_buffer_copy_into (newbuf, *buf,
2979 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_META,
2981 gst_buffer_unref (*buf);
2984 gst_buffer_map (*buf, &map, GST_MAP_READ);
2988 if (sub_stream->check_markup) {
2989 /* caps claim markup text, so we need to escape text,
2990 * except if text is already markup and then needs no further escaping */
2991 sub_stream->seen_markup_tag = sub_stream->seen_markup_tag ||
2992 gst_matroska_demux_subtitle_chunk_has_tag (element, (gchar *) map.data);
2994 if (!sub_stream->seen_markup_tag) {
2995 utf8 = g_markup_escape_text ((gchar *) map.data, map.size);
2997 newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
2998 gst_buffer_unmap (*buf, &map);
2999 gst_buffer_copy_into (newbuf, *buf,
3000 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS |
3001 GST_BUFFER_COPY_META, 0, -1);
3002 gst_buffer_unref (*buf);
3005 needs_unmap = FALSE;
3010 gst_buffer_unmap (*buf, &map);
3015 static GstFlowReturn
3016 gst_matroska_demux_check_aac (GstElement * element,
3017 GstMatroskaTrackContext * stream, GstBuffer ** buf)
3022 gst_buffer_extract (*buf, 0, data, 2);
3023 size = gst_buffer_get_size (*buf);
3025 if (size > 2 && data[0] == 0xff && (data[1] >> 4 == 0x0f)) {
3028 /* tss, ADTS data, remove codec_data
3029 * still assume it is at least parsed */
3030 stream->caps = gst_caps_make_writable (stream->caps);
3031 s = gst_caps_get_structure (stream->caps, 0);
3033 gst_structure_remove_field (s, "codec_data");
3034 gst_pad_set_caps (stream->pad, stream->caps);
3035 GST_DEBUG_OBJECT (element, "ADTS AAC audio data; removing codec-data, "
3036 "new caps: %" GST_PTR_FORMAT, stream->caps);
3039 /* disable subsequent checking */
3040 stream->postprocess_frame = NULL;
3046 gst_matroska_demux_align_buffer (GstMatroskaDemux * demux,
3047 GstBuffer * buffer, gsize alignment)
3051 gst_buffer_map (buffer, &map, GST_MAP_READ);
3053 if (map.size < sizeof (guintptr)) {
3054 gst_buffer_unmap (buffer, &map);
3058 if (((guintptr) map.data) & (alignment - 1)) {
3059 GstBuffer *new_buffer;
3060 GstAllocationParams params = { 0, alignment - 1, 0, 0, };
3062 new_buffer = gst_buffer_new_allocate (NULL,
3063 gst_buffer_get_size (buffer), ¶ms);
3065 /* Copy data "by hand", so ensure alignment is kept: */
3066 gst_buffer_fill (new_buffer, 0, map.data, map.size);
3068 gst_buffer_copy_into (new_buffer, buffer, GST_BUFFER_COPY_METADATA, 0, -1);
3069 GST_DEBUG_OBJECT (demux,
3070 "We want output aligned on %" G_GSIZE_FORMAT ", reallocated",
3073 gst_buffer_unmap (buffer, &map);
3074 gst_buffer_unref (buffer);
3079 gst_buffer_unmap (buffer, &map);
3083 static GstFlowReturn
3084 gst_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux,
3085 GstEbmlRead * ebml, guint64 cluster_time, guint64 cluster_offset,
3086 gboolean is_simpleblock)
3088 GstMatroskaTrackContext *stream = NULL;
3089 GstFlowReturn ret = GST_FLOW_OK;
3090 gboolean readblock = FALSE;
3092 guint64 block_duration = -1;
3093 GstBuffer *buf = NULL;
3095 gint stream_num = -1, n, laces = 0;
3097 gint *lace_size = NULL;
3100 gint64 referenceblock = 0;
3102 GstClockTime buffer_timestamp;
3104 offset = gst_ebml_read_get_offset (ebml);
3106 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3107 if (!is_simpleblock) {
3108 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK) {
3112 id = GST_MATROSKA_ID_SIMPLEBLOCK;
3116 /* one block inside the group. Note, block parsing is one
3117 * of the harder things, so this code is a bit complicated.
3118 * See http://www.matroska.org/ for documentation. */
3119 case GST_MATROSKA_ID_SIMPLEBLOCK:
3120 case GST_MATROSKA_ID_BLOCK:
3126 gst_buffer_unmap (buf, &map);
3127 gst_buffer_unref (buf);
3130 if ((ret = gst_ebml_read_buffer (ebml, &id, &buf)) != GST_FLOW_OK)
3133 gst_buffer_map (buf, &map, GST_MAP_READ);
3137 /* first byte(s): blocknum */
3138 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
3143 /* fetch stream from num */
3144 stream_num = gst_matroska_read_common_stream_from_num (&demux->common,
3146 if (G_UNLIKELY (size < 3)) {
3147 GST_WARNING_OBJECT (demux, "Invalid size %u", size);
3148 /* non-fatal, try next block(group) */
3151 } else if (G_UNLIKELY (stream_num < 0 ||
3152 stream_num >= demux->common.num_streams)) {
3153 /* let's not give up on a stray invalid track number */
3154 GST_WARNING_OBJECT (demux,
3155 "Invalid stream %d for track number %" G_GUINT64_FORMAT
3156 "; ignoring block", stream_num, num);
3160 stream = g_ptr_array_index (demux->common.src, stream_num);
3162 /* time (relative to cluster time) */
3163 time = ((gint16) GST_READ_UINT16_BE (data));
3166 flags = GST_READ_UINT8 (data);
3170 GST_LOG_OBJECT (demux, "time %" G_GUINT64_FORMAT ", flags %d", time,
3173 switch ((flags & 0x06) >> 1) {
3174 case 0x0: /* no lacing */
3176 lace_size = g_new (gint, 1);
3177 lace_size[0] = size;
3180 case 0x1: /* xiph lacing */
3181 case 0x2: /* fixed-size lacing */
3182 case 0x3: /* EBML lacing */
3184 goto invalid_lacing;
3185 laces = GST_READ_UINT8 (data) + 1;
3188 lace_size = g_new0 (gint, laces);
3190 switch ((flags & 0x06) >> 1) {
3191 case 0x1: /* xiph lacing */ {
3192 guint temp, total = 0;
3194 for (n = 0; ret == GST_FLOW_OK && n < laces - 1; n++) {
3197 goto invalid_lacing;
3198 temp = GST_READ_UINT8 (data);
3199 lace_size[n] += temp;
3205 total += lace_size[n];
3207 lace_size[n] = size - total;
3211 case 0x2: /* fixed-size lacing */
3212 for (n = 0; n < laces; n++)
3213 lace_size[n] = size / laces;
3216 case 0x3: /* EBML lacing */ {
3219 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
3223 total = lace_size[0] = num;
3224 for (n = 1; ret == GST_FLOW_OK && n < laces - 1; n++) {
3228 if ((r = gst_matroska_ebmlnum_sint (data, size, &snum)) < 0)
3232 lace_size[n] = lace_size[n - 1] + snum;
3233 total += lace_size[n];
3236 lace_size[n] = size - total;
3243 if (ret != GST_FLOW_OK)
3250 case GST_MATROSKA_ID_BLOCKDURATION:{
3251 ret = gst_ebml_read_uint (ebml, &id, &block_duration);
3252 GST_DEBUG_OBJECT (demux, "BlockDuration: %" G_GUINT64_FORMAT,
3257 case GST_MATROSKA_ID_REFERENCEBLOCK:{
3258 ret = gst_ebml_read_sint (ebml, &id, &referenceblock);
3259 GST_DEBUG_OBJECT (demux, "ReferenceBlock: %" G_GINT64_FORMAT,
3264 case GST_MATROSKA_ID_CODECSTATE:{
3266 guint64 data_len = 0;
3269 gst_ebml_read_binary (ebml, &id, &data,
3270 &data_len)) != GST_FLOW_OK)
3273 if (G_UNLIKELY (stream == NULL)) {
3274 GST_WARNING_OBJECT (demux,
3275 "Unexpected CodecState subelement - ignoring");
3279 g_free (stream->codec_state);
3280 stream->codec_state = data;
3281 stream->codec_state_size = data_len;
3283 /* Decode if necessary */
3284 if (stream->encodings && stream->encodings->len > 0
3285 && stream->codec_state && stream->codec_state_size > 0) {
3286 if (!gst_matroska_decode_data (stream->encodings,
3287 &stream->codec_state, &stream->codec_state_size,
3288 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
3289 GST_WARNING_OBJECT (demux, "Decoding codec state failed");
3293 GST_DEBUG_OBJECT (demux, "CodecState of %" G_GSIZE_FORMAT " bytes",
3294 stream->codec_state_size);
3299 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3303 case GST_MATROSKA_ID_BLOCKVIRTUAL:
3304 case GST_MATROSKA_ID_BLOCKADDITIONS:
3305 case GST_MATROSKA_ID_REFERENCEPRIORITY:
3306 case GST_MATROSKA_ID_REFERENCEVIRTUAL:
3307 case GST_MATROSKA_ID_SLICES:
3308 GST_DEBUG_OBJECT (demux,
3309 "Skipping BlockGroup subelement 0x%x - ignoring", id);
3310 ret = gst_ebml_read_skip (ebml);
3318 /* reading a number or so could have failed */
3319 if (ret != GST_FLOW_OK)
3322 if (ret == GST_FLOW_OK && readblock) {
3323 gboolean invisible_frame = FALSE;
3324 gboolean delta_unit = FALSE;
3325 guint64 duration = 0;
3326 gint64 lace_time = 0;
3328 stream = g_ptr_array_index (demux->common.src, stream_num);
3330 if (cluster_time != GST_CLOCK_TIME_NONE) {
3331 /* FIXME: What to do with negative timestamps? Give timestamp 0 or -1?
3332 * Drop unless the lace contains timestamp 0? */
3333 if (time < 0 && (-time) > cluster_time) {
3336 if (stream->timecodescale == 1.0)
3337 lace_time = (cluster_time + time) * demux->common.time_scale;
3340 gst_util_guint64_to_gdouble ((cluster_time + time) *
3341 demux->common.time_scale) * stream->timecodescale;
3344 lace_time = GST_CLOCK_TIME_NONE;
3347 /* need to refresh segment info ASAP */
3348 if (GST_CLOCK_TIME_IS_VALID (lace_time) && demux->need_segment) {
3349 GstSegment *segment = &demux->common.segment;
3351 GstEvent *segment_event;
3353 if (!GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
3354 demux->stream_start_time = lace_time;
3355 GST_DEBUG_OBJECT (demux,
3356 "Setting stream start time to %" GST_TIME_FORMAT,
3357 GST_TIME_ARGS (lace_time));
3359 clace_time = MAX (lace_time, demux->stream_start_time);
3360 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.position) &&
3361 demux->common.segment.position != 0) {
3362 GST_DEBUG_OBJECT (demux,
3363 "using stored seek position %" GST_TIME_FORMAT,
3364 GST_TIME_ARGS (demux->common.segment.position));
3365 clace_time = demux->common.segment.position + demux->stream_start_time;
3366 segment->position = GST_CLOCK_TIME_NONE;
3368 segment->start = clace_time;
3369 segment->stop = GST_CLOCK_TIME_NONE;
3370 segment->time = segment->start - demux->stream_start_time;
3371 segment->position = segment->start - demux->stream_start_time;
3372 GST_DEBUG_OBJECT (demux,
3373 "generated segment starting at %" GST_TIME_FORMAT ": %"
3374 GST_SEGMENT_FORMAT, GST_TIME_ARGS (lace_time), segment);
3375 /* now convey our segment notion downstream */
3376 segment_event = gst_event_new_segment (segment);
3377 if (demux->segment_seqnum)
3378 gst_event_set_seqnum (segment_event, demux->segment_seqnum);
3379 gst_matroska_demux_send_event (demux, segment_event);
3380 demux->need_segment = FALSE;
3381 demux->segment_seqnum = 0;
3384 /* send pending codec data headers for all streams,
3385 * before we perform sync across all streams */
3386 gst_matroska_demux_push_codec_data_all (demux);
3388 if (block_duration != -1) {
3389 if (stream->timecodescale == 1.0)
3390 duration = gst_util_uint64_scale (block_duration,
3391 demux->common.time_scale, 1);
3394 gst_util_gdouble_to_guint64 (gst_util_guint64_to_gdouble
3395 (gst_util_uint64_scale (block_duration, demux->common.time_scale,
3396 1)) * stream->timecodescale);
3397 } else if (stream->default_duration) {
3398 duration = stream->default_duration * laces;
3400 /* else duration is diff between timecode of this and next block */
3402 /* For SimpleBlock, look at the keyframe bit in flags. Otherwise,
3403 a ReferenceBlock implies that this is not a keyframe. In either
3404 case, it only makes sense for video streams. */
3405 if (stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
3406 if ((is_simpleblock && !(flags & 0x80)) || referenceblock) {
3408 invisible_frame = ((flags & 0x08)) &&
3409 (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8) ||
3410 !strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP9));
3414 for (n = 0; n < laces; n++) {
3417 if (G_UNLIKELY (lace_size[n] > size)) {
3418 GST_WARNING_OBJECT (demux, "Invalid lace size");
3422 /* QoS for video track with an index. the assumption is that
3423 index entries point to keyframes, but if that is not true we
3424 will instad skip until the next keyframe. */
3425 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
3426 stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
3427 stream->index_table && demux->common.segment.rate > 0.0) {
3428 GstMatroskaTrackVideoContext *videocontext =
3429 (GstMatroskaTrackVideoContext *) stream;
3430 GstClockTime earliest_time;
3431 GstClockTime earliest_stream_time;
3433 GST_OBJECT_LOCK (demux);
3434 earliest_time = videocontext->earliest_time;
3435 GST_OBJECT_UNLOCK (demux);
3436 earliest_stream_time = gst_segment_to_position (&demux->common.segment,
3437 GST_FORMAT_TIME, earliest_time);
3439 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
3440 GST_CLOCK_TIME_IS_VALID (earliest_stream_time) &&
3441 lace_time <= earliest_stream_time) {
3442 /* find index entry (keyframe) <= earliest_stream_time */
3443 GstMatroskaIndex *entry =
3444 gst_util_array_binary_search (stream->index_table->data,
3445 stream->index_table->len, sizeof (GstMatroskaIndex),
3446 (GCompareDataFunc) gst_matroska_index_seek_find,
3447 GST_SEARCH_MODE_BEFORE, &earliest_stream_time, NULL);
3449 /* if that entry (keyframe) is after the current the current
3450 buffer, we can skip pushing (and thus decoding) all
3451 buffers until that keyframe. */
3452 if (entry && GST_CLOCK_TIME_IS_VALID (entry->time) &&
3453 entry->time > lace_time) {
3454 GST_LOG_OBJECT (demux, "Skipping lace before late keyframe");
3455 stream->set_discont = TRUE;
3461 sub = gst_buffer_copy_region (buf, GST_BUFFER_COPY_ALL,
3462 gst_buffer_get_size (buf) - size, lace_size[n]);
3463 GST_DEBUG_OBJECT (demux, "created subbuffer %p", sub);
3466 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
3468 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
3470 if (invisible_frame)
3471 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DECODE_ONLY);
3473 if (stream->encodings != NULL && stream->encodings->len > 0)
3474 sub = gst_matroska_decode_buffer (stream, sub);
3477 GST_WARNING_OBJECT (demux, "Decoding buffer failed");
3481 buffer_timestamp = gst_matroska_track_get_buffer_timestamp (stream, sub);
3483 if (!stream->dts_only)
3484 GST_BUFFER_PTS (sub) = lace_time;
3486 GST_BUFFER_DTS (sub) = lace_time;
3488 if (GST_CLOCK_TIME_IS_VALID (lace_time)) {
3489 GstClockTime last_stop_end;
3491 /* Check if this stream is after segment stop */
3492 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop) &&
3493 lace_time >= demux->common.segment.stop) {
3494 GST_DEBUG_OBJECT (demux,
3495 "Stream %d after segment stop %" GST_TIME_FORMAT, stream->index,
3496 GST_TIME_ARGS (demux->common.segment.stop));
3497 gst_buffer_unref (sub);
3500 if (offset >= stream->to_offset
3501 || (GST_CLOCK_TIME_IS_VALID (demux->to_time)
3502 && lace_time > demux->to_time)) {
3503 GST_DEBUG_OBJECT (demux, "Stream %d after playback section",
3505 gst_buffer_unref (sub);
3509 /* handle gaps, e.g. non-zero start-time, or an cue index entry
3510 * that landed us with timestamps not quite intended */
3511 GST_OBJECT_LOCK (demux);
3512 if (demux->max_gap_time &&
3513 GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) &&
3514 demux->common.segment.rate > 0.0) {
3515 GstClockTimeDiff diff;
3517 /* only send segments with increasing start times,
3518 * otherwise if these go back and forth downstream (sinks) increase
3519 * accumulated time and running_time */
3520 diff = GST_CLOCK_DIFF (demux->last_stop_end, lace_time);
3521 if (diff > 0 && diff > demux->max_gap_time
3522 && lace_time > demux->common.segment.start
3523 && (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop)
3524 || lace_time < demux->common.segment.stop)) {
3526 GST_DEBUG_OBJECT (demux,
3527 "Gap of %" G_GINT64_FORMAT " ns detected in"
3528 "stream %d (%" GST_TIME_FORMAT " -> %" GST_TIME_FORMAT "). "
3529 "Sending updated SEGMENT events", diff,
3530 stream->index, GST_TIME_ARGS (stream->pos),
3531 GST_TIME_ARGS (lace_time));
3533 event = gst_event_new_gap (demux->last_stop_end, diff);
3534 GST_OBJECT_UNLOCK (demux);
3535 gst_pad_push_event (stream->pad, event);
3536 GST_OBJECT_LOCK (demux);
3540 if (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.position)
3541 || demux->common.segment.position < lace_time) {
3542 demux->common.segment.position = lace_time;
3544 GST_OBJECT_UNLOCK (demux);
3546 last_stop_end = lace_time;
3548 GST_BUFFER_DURATION (sub) = duration / laces;
3549 last_stop_end += GST_BUFFER_DURATION (sub);
3552 if (!GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) ||
3553 demux->last_stop_end < last_stop_end)
3554 demux->last_stop_end = last_stop_end;
3556 GST_OBJECT_LOCK (demux);
3557 if (demux->common.segment.duration == -1 ||
3558 demux->stream_start_time + demux->common.segment.duration <
3560 demux->common.segment.duration =
3561 last_stop_end - demux->stream_start_time;
3562 GST_OBJECT_UNLOCK (demux);
3563 if (!demux->invalid_duration) {
3564 gst_element_post_message (GST_ELEMENT_CAST (demux),
3565 gst_message_new_duration_changed (GST_OBJECT_CAST (demux)));
3566 demux->invalid_duration = TRUE;
3569 GST_OBJECT_UNLOCK (demux);
3573 stream->pos = lace_time;
3575 gst_matroska_demux_sync_streams (demux);
3577 if (stream->set_discont) {
3578 GST_DEBUG_OBJECT (demux, "marking DISCONT");
3579 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DISCONT);
3580 stream->set_discont = FALSE;
3582 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DISCONT);
3585 /* reverse playback book-keeping */
3586 if (!GST_CLOCK_TIME_IS_VALID (stream->from_time))
3587 stream->from_time = lace_time;
3588 if (stream->from_offset == -1)
3589 stream->from_offset = offset;
3591 GST_DEBUG_OBJECT (demux,
3592 "Pushing lace %d, data of size %" G_GSIZE_FORMAT
3593 " for stream %d, time=%" GST_TIME_FORMAT " and duration=%"
3594 GST_TIME_FORMAT, n, gst_buffer_get_size (sub), stream_num,
3595 GST_TIME_ARGS (buffer_timestamp),
3596 GST_TIME_ARGS (GST_BUFFER_DURATION (sub)));
3599 if (demux->common.element_index) {
3600 if (stream->index_writer_id == -1)
3601 gst_index_get_writer_id (demux->common.element_index,
3602 GST_OBJECT (stream->pad), &stream->index_writer_id);
3604 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
3605 G_GUINT64_FORMAT " for writer id %d",
3606 GST_TIME_ARGS (buffer_timestamp), cluster_offset,
3607 stream->index_writer_id);
3608 gst_index_add_association (demux->common.element_index,
3609 stream->index_writer_id, GST_BUFFER_FLAG_IS_SET (sub,
3610 GST_BUFFER_FLAG_DELTA_UNIT) ? 0 : GST_ASSOCIATION_FLAG_KEY_UNIT,
3611 GST_FORMAT_TIME, buffer_timestamp, GST_FORMAT_BYTES, cluster_offset,
3616 /* Postprocess the buffers depending on the codec used */
3617 if (stream->postprocess_frame) {
3618 GST_LOG_OBJECT (demux, "running post process");
3619 ret = stream->postprocess_frame (GST_ELEMENT (demux), stream, &sub);
3622 /* At this point, we have a sub-buffer pointing at data within a larger
3623 buffer. This data might not be aligned with anything. If the data is
3624 raw samples though, we want it aligned to the raw type (eg, 4 bytes
3625 for 32 bit samples, etc), or bad things will happen downstream as
3626 elements typically assume minimal alignment.
3627 Therefore, create an aligned copy if necessary. */
3628 g_assert (stream->alignment <= G_MEM_ALIGN);
3629 sub = gst_matroska_demux_align_buffer (demux, sub, stream->alignment);
3631 if (GST_BUFFER_PTS_IS_VALID (sub)) {
3632 stream->pos = GST_BUFFER_PTS (sub);
3633 if (GST_BUFFER_DURATION_IS_VALID (sub))
3634 stream->pos += GST_BUFFER_DURATION (sub);
3635 } else if (GST_BUFFER_DTS_IS_VALID (sub)) {
3636 stream->pos = GST_BUFFER_DTS (sub);
3637 if (GST_BUFFER_DURATION_IS_VALID (sub))
3638 stream->pos += GST_BUFFER_DURATION (sub);
3641 ret = gst_pad_push (stream->pad, sub);
3643 if (demux->common.segment.rate < 0) {
3644 if (lace_time > demux->common.segment.stop && ret == GST_FLOW_EOS) {
3645 /* In reverse playback we can get a GST_FLOW_EOS when
3646 * we are at the end of the segment, so we just need to jump
3647 * back to the previous section. */
3648 GST_DEBUG_OBJECT (demux, "downstream has reached end of segment");
3653 ret = gst_flow_combiner_update_flow (demux->flowcombiner, ret);
3656 size -= lace_size[n];
3657 if (lace_time != GST_CLOCK_TIME_NONE && duration)
3658 lace_time += duration / laces;
3660 lace_time = GST_CLOCK_TIME_NONE;
3666 gst_buffer_unmap (buf, &map);
3667 gst_buffer_unref (buf);
3679 ret = gst_flow_combiner_update_flow (demux->flowcombiner, ret);
3684 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Invalid lacing size"));
3685 /* non-fatal, try next block(group) */
3691 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Data error"));
3692 /* non-fatal, try next block(group) */
3698 /* return FALSE if block(group) should be skipped (due to a seek) */
3699 static inline gboolean
3700 gst_matroska_demux_seek_block (GstMatroskaDemux * demux)
3702 if (G_UNLIKELY (demux->seek_block)) {
3703 if (!(--demux->seek_block)) {
3706 GST_LOG_OBJECT (demux, "should skip block due to seek");
3714 static GstFlowReturn
3715 gst_matroska_demux_parse_contents_seekentry (GstMatroskaDemux * demux,
3719 guint64 seek_pos = (guint64) - 1;
3720 guint32 seek_id = 0;
3723 DEBUG_ELEMENT_START (demux, ebml, "Seek");
3725 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3726 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
3730 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3731 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3735 case GST_MATROSKA_ID_SEEKID:
3739 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
3742 GST_DEBUG_OBJECT (demux, "SeekID: %" G_GUINT64_FORMAT, t);
3747 case GST_MATROSKA_ID_SEEKPOSITION:
3751 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
3754 if (t > G_MAXINT64) {
3755 GST_WARNING_OBJECT (demux,
3756 "Too large SeekPosition %" G_GUINT64_FORMAT, t);
3760 GST_DEBUG_OBJECT (demux, "SeekPosition: %" G_GUINT64_FORMAT, t);
3766 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3772 if (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)
3775 if (!seek_id || seek_pos == (guint64) - 1) {
3776 GST_WARNING_OBJECT (demux, "Incomplete seekhead entry (0x%x/%"
3777 G_GUINT64_FORMAT ")", seek_id, seek_pos);
3782 case GST_MATROSKA_ID_SEEKHEAD:
3785 case GST_MATROSKA_ID_CUES:
3786 case GST_MATROSKA_ID_TAGS:
3787 case GST_MATROSKA_ID_TRACKS:
3788 case GST_MATROSKA_ID_SEGMENTINFO:
3789 case GST_MATROSKA_ID_ATTACHMENTS:
3790 case GST_MATROSKA_ID_CHAPTERS:
3792 guint64 before_pos, length;
3796 length = gst_matroska_read_common_get_length (&demux->common);
3797 before_pos = demux->common.offset;
3799 if (length == (guint64) - 1) {
3800 GST_DEBUG_OBJECT (demux, "no upstream length, skipping SeakHead entry");
3804 /* check for validity */
3805 if (seek_pos + demux->common.ebml_segment_start + 12 >= length) {
3806 GST_WARNING_OBJECT (demux,
3807 "SeekHead reference lies outside file!" " (%"
3808 G_GUINT64_FORMAT "+%" G_GUINT64_FORMAT "+12 >= %"
3809 G_GUINT64_FORMAT ")", seek_pos, demux->common.ebml_segment_start,
3814 /* only pick up index location when streaming */
3815 if (demux->streaming) {
3816 if (seek_id == GST_MATROSKA_ID_CUES) {
3817 demux->index_offset = seek_pos + demux->common.ebml_segment_start;
3818 GST_DEBUG_OBJECT (demux, "Cues located at offset %" G_GUINT64_FORMAT,
3819 demux->index_offset);
3825 demux->common.offset = seek_pos + demux->common.ebml_segment_start;
3828 if ((ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
3829 GST_ELEMENT_CAST (demux), &id, &length, &needed)) !=
3833 if (id != seek_id) {
3834 GST_WARNING_OBJECT (demux,
3835 "We looked for ID=0x%x but got ID=0x%x (pos=%" G_GUINT64_FORMAT ")",
3836 seek_id, id, seek_pos + demux->common.ebml_segment_start);
3839 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
3844 demux->common.offset = before_pos;
3848 case GST_MATROSKA_ID_CLUSTER:
3850 guint64 pos = seek_pos + demux->common.ebml_segment_start;
3852 GST_LOG_OBJECT (demux, "Cluster position");
3853 if (G_UNLIKELY (!demux->clusters))
3854 demux->clusters = g_array_sized_new (TRUE, TRUE, sizeof (guint64), 100);
3855 g_array_append_val (demux->clusters, pos);
3860 GST_DEBUG_OBJECT (demux, "Ignoring Seek entry for ID=0x%x", seek_id);
3863 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
3868 static GstFlowReturn
3869 gst_matroska_demux_parse_contents (GstMatroskaDemux * demux, GstEbmlRead * ebml)
3871 GstFlowReturn ret = GST_FLOW_OK;
3874 DEBUG_ELEMENT_START (demux, ebml, "SeekHead");
3876 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3877 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
3881 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3882 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3886 case GST_MATROSKA_ID_SEEKENTRY:
3888 ret = gst_matroska_demux_parse_contents_seekentry (demux, ebml);
3889 /* Ignore EOS and errors here */
3890 if (ret != GST_FLOW_OK) {
3891 GST_DEBUG_OBJECT (demux, "Ignoring %s", gst_flow_get_name (ret));
3898 ret = gst_matroska_read_common_parse_skip (&demux->common,
3899 ebml, "SeekHead", id);
3904 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
3906 /* Sort clusters by position for easier searching */
3907 if (demux->clusters)
3908 g_array_sort (demux->clusters, (GCompareFunc) gst_matroska_cluster_compare);
3913 #define GST_FLOW_OVERFLOW GST_FLOW_CUSTOM_ERROR
3915 #define MAX_BLOCK_SIZE (15 * 1024 * 1024)
3917 static inline GstFlowReturn
3918 gst_matroska_demux_check_read_size (GstMatroskaDemux * demux, guint64 bytes)
3920 if (G_UNLIKELY (bytes > MAX_BLOCK_SIZE)) {
3921 /* only a few blocks are expected/allowed to be large,
3922 * and will be recursed into, whereas others will be read and must fit */
3923 if (demux->streaming) {
3924 /* fatal in streaming case, as we can't step over easily */
3925 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
3926 ("reading large block of size %" G_GUINT64_FORMAT " not supported; "
3927 "file might be corrupt.", bytes));
3928 return GST_FLOW_ERROR;
3930 /* indicate higher level to quietly give up */
3931 GST_DEBUG_OBJECT (demux,
3932 "too large block of size %" G_GUINT64_FORMAT, bytes);
3933 return GST_FLOW_ERROR;
3940 /* returns TRUE if we truely are in error state, and should give up */
3941 static inline GstFlowReturn
3942 gst_matroska_demux_check_parse_error (GstMatroskaDemux * demux)
3944 if (!demux->streaming && demux->next_cluster_offset > 0) {
3945 /* just repositioning to where next cluster should be and try from there */
3946 GST_WARNING_OBJECT (demux, "parse error, trying next cluster expected at %"
3947 G_GUINT64_FORMAT, demux->next_cluster_offset);
3948 demux->common.offset = demux->next_cluster_offset;
3949 demux->next_cluster_offset = 0;
3955 /* sigh, one last attempt above and beyond call of duty ...;
3956 * search for cluster mark following current pos */
3957 pos = demux->common.offset;
3958 GST_WARNING_OBJECT (demux, "parse error, looking for next cluster");
3959 if ((ret = gst_matroska_demux_search_cluster (demux, &pos)) != GST_FLOW_OK) {
3960 /* did not work, give up */
3963 GST_DEBUG_OBJECT (demux, "... found at %" G_GUINT64_FORMAT, pos);
3964 /* try that position */
3965 demux->common.offset = pos;
3971 static inline GstFlowReturn
3972 gst_matroska_demux_flush (GstMatroskaDemux * demux, guint flush)
3974 GST_LOG_OBJECT (demux, "skipping %d bytes", flush);
3975 demux->common.offset += flush;
3976 if (demux->streaming) {
3979 /* hard to skip large blocks when streaming */
3980 ret = gst_matroska_demux_check_read_size (demux, flush);
3981 if (ret != GST_FLOW_OK)
3983 if (flush <= gst_adapter_available (demux->common.adapter))
3984 gst_adapter_flush (demux->common.adapter, flush);
3986 return GST_FLOW_EOS;
3991 /* initializes @ebml with @bytes from input stream at current offset.
3992 * Returns EOS if insufficient available,
3993 * ERROR if too much was attempted to read. */
3994 static inline GstFlowReturn
3995 gst_matroska_demux_take (GstMatroskaDemux * demux, guint64 bytes,
3998 GstBuffer *buffer = NULL;
3999 GstFlowReturn ret = GST_FLOW_OK;
4001 GST_LOG_OBJECT (demux, "taking %" G_GUINT64_FORMAT " bytes for parsing",
4003 ret = gst_matroska_demux_check_read_size (demux, bytes);
4004 if (G_UNLIKELY (ret != GST_FLOW_OK)) {
4005 if (!demux->streaming) {
4006 /* in pull mode, we can skip */
4007 if ((ret = gst_matroska_demux_flush (demux, bytes)) == GST_FLOW_OK)
4008 ret = GST_FLOW_OVERFLOW;
4010 /* otherwise fatal */
4011 ret = GST_FLOW_ERROR;
4015 if (demux->streaming) {
4016 if (gst_adapter_available (demux->common.adapter) >= bytes)
4017 buffer = gst_adapter_take_buffer (demux->common.adapter, bytes);
4021 ret = gst_matroska_read_common_peek_bytes (&demux->common,
4022 demux->common.offset, bytes, &buffer, NULL);
4023 if (G_LIKELY (buffer)) {
4024 gst_ebml_read_init (ebml, GST_ELEMENT_CAST (demux), buffer,
4025 demux->common.offset);
4026 demux->common.offset += bytes;
4033 gst_matroska_demux_check_seekability (GstMatroskaDemux * demux)
4036 gboolean seekable = FALSE;
4037 gint64 start = -1, stop = -1;
4039 query = gst_query_new_seeking (GST_FORMAT_BYTES);
4040 if (!gst_pad_peer_query (demux->common.sinkpad, query)) {
4041 GST_DEBUG_OBJECT (demux, "seeking query failed");
4045 gst_query_parse_seeking (query, NULL, &seekable, &start, &stop);
4047 /* try harder to query upstream size if we didn't get it the first time */
4048 if (seekable && stop == -1) {
4049 GST_DEBUG_OBJECT (demux, "doing duration query to fix up unset stop");
4050 gst_pad_peer_query_duration (demux->common.sinkpad, GST_FORMAT_BYTES,
4054 /* if upstream doesn't know the size, it's likely that it's not seekable in
4055 * practice even if it technically may be seekable */
4056 if (seekable && (start != 0 || stop <= start)) {
4057 GST_DEBUG_OBJECT (demux, "seekable but unknown start/stop -> disable");
4062 GST_INFO_OBJECT (demux, "seekable: %d (%" G_GUINT64_FORMAT " - %"
4063 G_GUINT64_FORMAT ")", seekable, start, stop);
4064 demux->seekable = seekable;
4066 gst_query_unref (query);
4069 static GstFlowReturn
4070 gst_matroska_demux_find_tracks (GstMatroskaDemux * demux)
4076 GstFlowReturn ret = GST_FLOW_OK;
4078 GST_WARNING_OBJECT (demux,
4079 "Found Cluster element before Tracks, searching Tracks");
4082 before_pos = demux->common.offset;
4084 /* Search Tracks element */
4086 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4087 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4088 if (ret != GST_FLOW_OK)
4091 if (id != GST_MATROSKA_ID_TRACKS) {
4092 /* we may be skipping large cluster here, so forego size check etc */
4093 /* ... but we can't skip undefined size; force error */
4094 if (length == G_MAXUINT64) {
4095 ret = gst_matroska_demux_check_read_size (demux, length);
4098 demux->common.offset += needed;
4099 demux->common.offset += length;
4104 /* will lead to track parsing ... */
4105 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4110 demux->common.offset = before_pos;
4115 #define GST_READ_CHECK(stmt) \
4117 if (G_UNLIKELY ((ret = (stmt)) != GST_FLOW_OK)) { \
4118 if (ret == GST_FLOW_OVERFLOW) { \
4119 ret = GST_FLOW_OK; \
4125 static GstFlowReturn
4126 gst_matroska_demux_parse_id (GstMatroskaDemux * demux, guint32 id,
4127 guint64 length, guint needed)
4129 GstEbmlRead ebml = { 0, };
4130 GstFlowReturn ret = GST_FLOW_OK;
4133 GST_LOG_OBJECT (demux, "Parsing Element id 0x%x, "
4134 "size %" G_GUINT64_FORMAT ", prefix %d", id, length, needed);
4136 /* if we plan to read and parse this element, we need prefix (id + length)
4137 * and the contents */
4138 /* mind about overflow wrap-around when dealing with undefined size */
4140 if (G_LIKELY (length != G_MAXUINT64))
4143 switch (demux->common.state) {
4144 case GST_MATROSKA_READ_STATE_START:
4146 case GST_EBML_ID_HEADER:
4147 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4148 ret = gst_matroska_read_common_parse_header (&demux->common, &ebml);
4149 if (ret != GST_FLOW_OK)
4151 demux->common.state = GST_MATROSKA_READ_STATE_SEGMENT;
4152 gst_matroska_demux_check_seekability (demux);
4155 goto invalid_header;
4159 case GST_MATROSKA_READ_STATE_SEGMENT:
4161 case GST_MATROSKA_ID_SEGMENT:
4162 /* eat segment prefix */
4163 GST_READ_CHECK (gst_matroska_demux_flush (demux, needed));
4164 GST_DEBUG_OBJECT (demux,
4165 "Found Segment start at offset %" G_GUINT64_FORMAT " with size %"
4166 G_GUINT64_FORMAT, demux->common.offset, length);
4167 /* seeks are from the beginning of the segment,
4168 * after the segment ID/length */
4169 demux->common.ebml_segment_start = demux->common.offset;
4171 length = G_MAXUINT64;
4172 demux->common.ebml_segment_length = length;
4173 demux->common.state = GST_MATROSKA_READ_STATE_HEADER;
4176 GST_WARNING_OBJECT (demux,
4177 "Expected a Segment ID (0x%x), but received 0x%x!",
4178 GST_MATROSKA_ID_SEGMENT, id);
4179 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4183 case GST_MATROSKA_READ_STATE_SCANNING:
4184 if (id != GST_MATROSKA_ID_CLUSTER &&
4185 id != GST_MATROSKA_ID_CLUSTERTIMECODE)
4188 case GST_MATROSKA_READ_STATE_HEADER:
4189 case GST_MATROSKA_READ_STATE_DATA:
4190 case GST_MATROSKA_READ_STATE_SEEK:
4192 case GST_MATROSKA_ID_SEGMENTINFO:
4193 if (!demux->common.segmentinfo_parsed) {
4194 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4195 ret = gst_matroska_read_common_parse_info (&demux->common,
4196 GST_ELEMENT_CAST (demux), &ebml);
4197 if (ret == GST_FLOW_OK)
4198 gst_matroska_demux_send_tags (demux);
4200 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4203 case GST_MATROSKA_ID_TRACKS:
4204 if (!demux->tracks_parsed) {
4205 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4206 ret = gst_matroska_demux_parse_tracks (demux, &ebml);
4208 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4211 case GST_MATROSKA_ID_CLUSTER:
4212 if (G_UNLIKELY (!demux->tracks_parsed)) {
4213 if (demux->streaming) {
4214 GST_DEBUG_OBJECT (demux, "Cluster before Track");
4215 goto not_streamable;
4217 ret = gst_matroska_demux_find_tracks (demux);
4218 if (!demux->tracks_parsed)
4222 if (G_UNLIKELY (demux->common.state
4223 == GST_MATROSKA_READ_STATE_HEADER)) {
4224 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
4225 demux->first_cluster_offset = demux->common.offset;
4226 GST_DEBUG_OBJECT (demux, "signaling no more pads");
4227 gst_element_no_more_pads (GST_ELEMENT (demux));
4228 /* send initial segment - we wait till we know the first
4229 incoming timestamp, so we can properly set the start of
4231 demux->need_segment = TRUE;
4233 demux->cluster_time = GST_CLOCK_TIME_NONE;
4234 demux->cluster_offset = demux->common.offset;
4235 if (G_UNLIKELY (!demux->seek_first && demux->seek_block)) {
4236 GST_DEBUG_OBJECT (demux, "seek target block %" G_GUINT64_FORMAT
4237 " not found in Cluster, trying next Cluster's first block instead",
4239 demux->seek_block = 0;
4241 demux->seek_first = FALSE;
4242 /* record next cluster for recovery */
4243 if (read != G_MAXUINT64)
4244 demux->next_cluster_offset = demux->cluster_offset + read;
4245 /* eat cluster prefix */
4246 gst_matroska_demux_flush (demux, needed);
4248 case GST_MATROSKA_ID_CLUSTERTIMECODE:
4252 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4253 if ((ret = gst_ebml_read_uint (&ebml, &id, &num)) != GST_FLOW_OK)
4255 GST_DEBUG_OBJECT (demux, "ClusterTimeCode: %" G_GUINT64_FORMAT, num);
4256 demux->cluster_time = num;
4258 if (demux->common.element_index) {
4259 if (demux->common.element_index_writer_id == -1)
4260 gst_index_get_writer_id (demux->common.element_index,
4261 GST_OBJECT (demux), &demux->common.element_index_writer_id);
4262 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
4263 G_GUINT64_FORMAT " for writer id %d",
4264 GST_TIME_ARGS (demux->cluster_time), demux->cluster_offset,
4265 demux->common.element_index_writer_id);
4266 gst_index_add_association (demux->common.element_index,
4267 demux->common.element_index_writer_id,
4268 GST_ASSOCIATION_FLAG_KEY_UNIT,
4269 GST_FORMAT_TIME, demux->cluster_time,
4270 GST_FORMAT_BYTES, demux->cluster_offset, NULL);
4275 case GST_MATROSKA_ID_BLOCKGROUP:
4276 if (!gst_matroska_demux_seek_block (demux))
4278 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4279 DEBUG_ELEMENT_START (demux, &ebml, "BlockGroup");
4280 if ((ret = gst_ebml_read_master (&ebml, &id)) == GST_FLOW_OK) {
4281 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4282 &ebml, demux->cluster_time, demux->cluster_offset, FALSE);
4284 DEBUG_ELEMENT_STOP (demux, &ebml, "BlockGroup", ret);
4286 case GST_MATROSKA_ID_SIMPLEBLOCK:
4287 if (!gst_matroska_demux_seek_block (demux))
4289 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4290 DEBUG_ELEMENT_START (demux, &ebml, "SimpleBlock");
4291 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4292 &ebml, demux->cluster_time, demux->cluster_offset, TRUE);
4293 DEBUG_ELEMENT_STOP (demux, &ebml, "SimpleBlock", ret);
4295 case GST_MATROSKA_ID_ATTACHMENTS:
4296 if (!demux->common.attachments_parsed) {
4297 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4298 ret = gst_matroska_read_common_parse_attachments (&demux->common,
4299 GST_ELEMENT_CAST (demux), &ebml);
4300 if (ret == GST_FLOW_OK)
4301 gst_matroska_demux_send_tags (demux);
4303 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4306 case GST_MATROSKA_ID_TAGS:
4307 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4308 ret = gst_matroska_read_common_parse_metadata (&demux->common,
4309 GST_ELEMENT_CAST (demux), &ebml);
4310 if (ret == GST_FLOW_OK)
4311 gst_matroska_demux_send_tags (demux);
4313 case GST_MATROSKA_ID_CHAPTERS:
4314 if (!demux->common.chapters_parsed) {
4315 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4317 gst_matroska_read_common_parse_chapters (&demux->common, &ebml);
4319 if (demux->common.toc) {
4320 gst_matroska_demux_send_event (demux,
4321 gst_event_new_toc (demux->common.toc, FALSE));
4324 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4326 case GST_MATROSKA_ID_SEEKHEAD:
4327 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4328 ret = gst_matroska_demux_parse_contents (demux, &ebml);
4330 case GST_MATROSKA_ID_CUES:
4331 if (demux->common.index_parsed) {
4332 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4335 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4336 ret = gst_matroska_read_common_parse_index (&demux->common, &ebml);
4337 /* only push based; delayed index building */
4338 if (ret == GST_FLOW_OK
4339 && demux->common.state == GST_MATROSKA_READ_STATE_SEEK) {
4342 GST_OBJECT_LOCK (demux);
4343 event = demux->seek_event;
4344 demux->seek_event = NULL;
4345 GST_OBJECT_UNLOCK (demux);
4348 /* unlikely to fail, since we managed to seek to this point */
4349 if (!gst_matroska_demux_handle_seek_event (demux, NULL, event))
4351 /* resume data handling, main thread clear to seek again */
4352 GST_OBJECT_LOCK (demux);
4353 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
4354 GST_OBJECT_UNLOCK (demux);
4357 case GST_MATROSKA_ID_POSITION:
4358 case GST_MATROSKA_ID_PREVSIZE:
4359 case GST_MATROSKA_ID_ENCRYPTEDBLOCK:
4360 case GST_MATROSKA_ID_SILENTTRACKS:
4361 GST_DEBUG_OBJECT (demux,
4362 "Skipping Cluster subelement 0x%x - ignoring", id);
4366 GST_DEBUG_OBJECT (demux, "skipping Element 0x%x", id);
4367 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4373 if (ret == GST_FLOW_PARSE)
4377 gst_ebml_read_clear (&ebml);
4383 /* simply exit, maybe not enough data yet */
4384 /* no ebml to clear if read error */
4389 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4390 ("Failed to parse Element 0x%x", id));
4391 ret = GST_FLOW_ERROR;
4396 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4397 ("File layout does not permit streaming"));
4398 ret = GST_FLOW_ERROR;
4403 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4404 ("No Tracks element found"));
4405 ret = GST_FLOW_ERROR;
4410 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Invalid header"));
4411 ret = GST_FLOW_ERROR;
4416 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Failed to seek"));
4417 ret = GST_FLOW_ERROR;
4423 gst_matroska_demux_loop (GstPad * pad)
4425 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (pad));
4431 /* If we have to close a segment, send a new segment to do this now */
4432 if (G_LIKELY (demux->common.state == GST_MATROSKA_READ_STATE_DATA)) {
4433 if (G_UNLIKELY (demux->new_segment)) {
4434 gst_matroska_demux_send_event (demux, demux->new_segment);
4435 demux->new_segment = NULL;
4439 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4440 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4441 if (ret == GST_FLOW_EOS) {
4443 } else if (ret == GST_FLOW_FLUSHING) {
4445 } else if (ret != GST_FLOW_OK) {
4446 ret = gst_matroska_demux_check_parse_error (demux);
4448 /* Only handle EOS as no error if we're outside the segment already */
4449 if (ret == GST_FLOW_EOS && (demux->common.ebml_segment_length != G_MAXUINT64
4450 && demux->common.offset >=
4451 demux->common.ebml_segment_start +
4452 demux->common.ebml_segment_length))
4454 else if (ret != GST_FLOW_OK)
4460 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
4461 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
4464 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4465 if (ret == GST_FLOW_EOS)
4467 if (ret != GST_FLOW_OK)
4470 /* check if we're at the end of a configured segment */
4471 if (G_LIKELY (demux->common.src->len)) {
4474 g_assert (demux->common.num_streams == demux->common.src->len);
4475 for (i = 0; i < demux->common.src->len; i++) {
4476 GstMatroskaTrackContext *context = g_ptr_array_index (demux->common.src,
4478 GST_DEBUG_OBJECT (context->pad, "pos %" GST_TIME_FORMAT,
4479 GST_TIME_ARGS (context->pos));
4480 if (context->eos == FALSE)
4484 GST_INFO_OBJECT (demux, "All streams are EOS");
4490 if (G_UNLIKELY (demux->cached_length == G_MAXUINT64 ||
4491 demux->common.offset >= demux->cached_length)) {
4492 demux->cached_length = gst_matroska_read_common_get_length (&demux->common);
4493 if (demux->common.offset == demux->cached_length) {
4494 GST_LOG_OBJECT (demux, "Reached end of stream");
4505 if (demux->common.segment.rate < 0.0) {
4506 ret = gst_matroska_demux_seek_to_previous_keyframe (demux);
4507 if (ret == GST_FLOW_OK)
4514 const gchar *reason = gst_flow_get_name (ret);
4515 gboolean push_eos = FALSE;
4517 GST_LOG_OBJECT (demux, "pausing task, reason %s", reason);
4518 gst_pad_pause_task (demux->common.sinkpad);
4520 if (ret == GST_FLOW_EOS) {
4521 /* perform EOS logic */
4523 /* If we were in the headers, make sure we send no-more-pads.
4524 This will ensure decodebin2 does not get stuck thinking
4525 the chain is not complete yet, and waiting indefinitely. */
4526 if (G_UNLIKELY (demux->common.state == GST_MATROSKA_READ_STATE_HEADER)) {
4527 if (demux->common.src->len == 0) {
4528 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
4529 ("No pads created"));
4531 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL),
4532 ("Failed to finish reading headers"));
4534 gst_element_no_more_pads (GST_ELEMENT (demux));
4537 if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
4540 /* for segment playback we need to post when (in stream time)
4541 * we stopped, this is either stop (when set) or the duration. */
4542 if ((stop = demux->common.segment.stop) == -1)
4543 stop = demux->last_stop_end;
4545 GST_LOG_OBJECT (demux, "Sending segment done, at end of segment");
4546 gst_element_post_message (GST_ELEMENT (demux),
4547 gst_message_new_segment_done (GST_OBJECT (demux), GST_FORMAT_TIME,
4549 gst_matroska_demux_send_event (demux,
4550 gst_event_new_segment_done (GST_FORMAT_TIME, stop));
4554 } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS) {
4555 /* for fatal errors we post an error message */
4556 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
4557 ("stream stopped, reason %s", reason));
4561 /* send EOS, and prevent hanging if no streams yet */
4562 GST_LOG_OBJECT (demux, "Sending EOS, at end of stream");
4563 if (!gst_matroska_demux_send_event (demux, gst_event_new_eos ()) &&
4564 (ret == GST_FLOW_EOS)) {
4565 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4566 (NULL), ("got eos but no streams (yet)"));
4574 * Create and push a flushing seek event upstream
4577 perform_seek_to_offset (GstMatroskaDemux * demux, gdouble rate, guint64 offset,
4583 GST_DEBUG_OBJECT (demux, "Seeking to %" G_GUINT64_FORMAT, offset);
4586 gst_event_new_seek (rate, GST_FORMAT_BYTES,
4587 GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, GST_SEEK_TYPE_SET, offset,
4588 GST_SEEK_TYPE_NONE, -1);
4589 gst_event_set_seqnum (event, seqnum);
4591 res = gst_pad_push_event (demux->common.sinkpad, event);
4593 /* segment event will update offset */
4597 static GstFlowReturn
4598 gst_matroska_demux_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
4600 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4602 GstFlowReturn ret = GST_FLOW_OK;
4607 if (G_UNLIKELY (GST_BUFFER_IS_DISCONT (buffer))) {
4608 GST_DEBUG_OBJECT (demux, "got DISCONT");
4609 gst_adapter_clear (demux->common.adapter);
4610 GST_OBJECT_LOCK (demux);
4611 gst_matroska_read_common_reset_streams (&demux->common,
4612 GST_CLOCK_TIME_NONE, FALSE);
4613 GST_OBJECT_UNLOCK (demux);
4616 gst_adapter_push (demux->common.adapter, buffer);
4620 available = gst_adapter_available (demux->common.adapter);
4622 ret = gst_matroska_read_common_peek_id_length_push (&demux->common,
4623 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4624 if (G_UNLIKELY (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)) {
4625 if (demux->common.ebml_segment_length != G_MAXUINT64
4626 && demux->common.offset >=
4627 demux->common.ebml_segment_start + demux->common.ebml_segment_length)
4632 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
4633 "size %" G_GUINT64_FORMAT ", needed %d, available %d",
4634 demux->common.offset, id, length, needed, available);
4636 if (needed > available)
4639 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4640 if (ret == GST_FLOW_EOS) {
4641 /* need more data */
4643 } else if (ret != GST_FLOW_OK) {
4650 gst_matroska_demux_handle_sink_event (GstPad * pad, GstObject * parent,
4653 gboolean res = TRUE;
4654 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4656 GST_DEBUG_OBJECT (demux,
4657 "have event type %s: %p on sink pad", GST_EVENT_TYPE_NAME (event), event);
4659 switch (GST_EVENT_TYPE (event)) {
4660 case GST_EVENT_SEGMENT:
4662 const GstSegment *segment;
4664 /* some debug output */
4665 gst_event_parse_segment (event, &segment);
4666 /* FIXME: do we need to update segment base here (like accum in 0.10)? */
4667 GST_DEBUG_OBJECT (demux,
4668 "received format %d segment %" GST_SEGMENT_FORMAT, segment->format,
4671 if (demux->common.state < GST_MATROSKA_READ_STATE_DATA) {
4672 GST_DEBUG_OBJECT (demux, "still starting");
4676 /* we only expect a BYTE segment, e.g. following a seek */
4677 if (segment->format != GST_FORMAT_BYTES) {
4678 GST_DEBUG_OBJECT (demux, "unsupported segment format, ignoring");
4682 GST_DEBUG_OBJECT (demux, "clearing segment state");
4683 GST_OBJECT_LOCK (demux);
4684 /* clear current segment leftover */
4685 gst_adapter_clear (demux->common.adapter);
4686 /* and some streaming setup */
4687 demux->common.offset = segment->start;
4688 /* accumulate base based on current position */
4689 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.position))
4690 demux->common.segment.base +=
4691 (MAX (demux->common.segment.position, demux->stream_start_time)
4692 - demux->stream_start_time) / fabs (demux->common.segment.rate);
4693 /* do not know where we are;
4694 * need to come across a cluster and generate segment */
4695 demux->common.segment.position = GST_CLOCK_TIME_NONE;
4696 demux->cluster_time = GST_CLOCK_TIME_NONE;
4697 demux->cluster_offset = 0;
4698 demux->need_segment = TRUE;
4699 demux->segment_seqnum = gst_event_get_seqnum (event);
4700 /* but keep some of the upstream segment */
4701 demux->common.segment.rate = segment->rate;
4702 /* also check if need to keep some of the requested seek position */
4703 if (demux->seek_offset == segment->start) {
4704 GST_DEBUG_OBJECT (demux, "position matches requested seek");
4705 demux->common.segment.position = demux->requested_seek_time;
4707 GST_DEBUG_OBJECT (demux, "unexpected segment position");
4709 demux->requested_seek_time = GST_CLOCK_TIME_NONE;
4710 demux->seek_offset = -1;
4711 GST_OBJECT_UNLOCK (demux);
4713 /* chain will send initial segment after pads have been added,
4714 * or otherwise come up with one */
4715 GST_DEBUG_OBJECT (demux, "eating event");
4716 gst_event_unref (event);
4722 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
4723 gst_event_unref (event);
4724 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4725 (NULL), ("got eos and didn't receive a complete header object"));
4726 } else if (demux->common.num_streams == 0) {
4727 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4728 (NULL), ("got eos but no streams (yet)"));
4730 gst_matroska_demux_send_event (demux, event);
4734 case GST_EVENT_FLUSH_STOP:
4738 gst_adapter_clear (demux->common.adapter);
4739 GST_OBJECT_LOCK (demux);
4740 gst_matroska_read_common_reset_streams (&demux->common,
4741 GST_CLOCK_TIME_NONE, TRUE);
4742 dur = demux->common.segment.duration;
4743 gst_segment_init (&demux->common.segment, GST_FORMAT_TIME);
4744 demux->common.segment.duration = dur;
4745 demux->cluster_time = GST_CLOCK_TIME_NONE;
4746 demux->cluster_offset = 0;
4747 GST_OBJECT_UNLOCK (demux);
4751 res = gst_pad_event_default (pad, parent, event);
4759 gst_matroska_demux_sink_activate (GstPad * sinkpad, GstObject * parent)
4761 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4763 gboolean pull_mode = FALSE;
4765 query = gst_query_new_scheduling ();
4767 if (gst_pad_peer_query (sinkpad, query))
4768 pull_mode = gst_query_has_scheduling_mode_with_flags (query,
4769 GST_PAD_MODE_PULL, GST_SCHEDULING_FLAG_SEEKABLE);
4771 gst_query_unref (query);
4774 GST_DEBUG ("going to pull mode");
4775 demux->streaming = FALSE;
4776 return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PULL, TRUE);
4778 GST_DEBUG ("going to push (streaming) mode");
4779 demux->streaming = TRUE;
4780 return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PUSH, TRUE);
4785 gst_matroska_demux_sink_activate_mode (GstPad * sinkpad, GstObject * parent,
4786 GstPadMode mode, gboolean active)
4789 case GST_PAD_MODE_PULL:
4791 /* if we have a scheduler we can start the task */
4792 gst_pad_start_task (sinkpad, (GstTaskFunction) gst_matroska_demux_loop,
4795 gst_pad_stop_task (sinkpad);
4798 case GST_PAD_MODE_PUSH:
4806 gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext *
4807 videocontext, const gchar * codec_id, guint8 * data, guint size,
4808 gchar ** codec_name, guint32 * riff_fourcc)
4810 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) videocontext;
4811 GstCaps *caps = NULL;
4813 g_assert (videocontext != NULL);
4814 g_assert (codec_name != NULL);
4819 /* TODO: check if we have all codec types from matroska-ids.h
4820 * check if we have to do more special things with codec_private
4823 * GST_MATROSKA_CODEC_ID_VIDEO_QUICKTIME
4824 * GST_MATROSKA_CODEC_ID_VIDEO_SNOW
4827 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VFW_FOURCC)) {
4828 gst_riff_strf_vids *vids = NULL;
4831 GstBuffer *buf = NULL;
4833 vids = (gst_riff_strf_vids *) data;
4835 /* assure size is big enough */
4837 GST_WARNING ("Too small BITMAPINFOHEADER (%d bytes)", size);
4840 if (size < sizeof (gst_riff_strf_vids)) {
4841 vids = g_new (gst_riff_strf_vids, 1);
4842 memcpy (vids, data, size);
4845 context->dts_only = TRUE; /* VFW files only store DTS */
4847 /* little-endian -> byte-order */
4848 vids->size = GUINT32_FROM_LE (vids->size);
4849 vids->width = GUINT32_FROM_LE (vids->width);
4850 vids->height = GUINT32_FROM_LE (vids->height);
4851 vids->planes = GUINT16_FROM_LE (vids->planes);
4852 vids->bit_cnt = GUINT16_FROM_LE (vids->bit_cnt);
4853 vids->compression = GUINT32_FROM_LE (vids->compression);
4854 vids->image_size = GUINT32_FROM_LE (vids->image_size);
4855 vids->xpels_meter = GUINT32_FROM_LE (vids->xpels_meter);
4856 vids->ypels_meter = GUINT32_FROM_LE (vids->ypels_meter);
4857 vids->num_colors = GUINT32_FROM_LE (vids->num_colors);
4858 vids->imp_colors = GUINT32_FROM_LE (vids->imp_colors);
4860 if (size > sizeof (gst_riff_strf_vids)) { /* some extra_data */
4861 gsize offset = sizeof (gst_riff_strf_vids);
4864 gst_buffer_new_wrapped (g_memdup ((guint8 *) vids + offset,
4865 size - offset), size - offset);
4869 *riff_fourcc = vids->compression;
4871 caps = gst_riff_create_video_caps (vids->compression, NULL, vids,
4872 buf, NULL, codec_name);
4875 GST_WARNING ("Unhandled RIFF fourcc %" GST_FOURCC_FORMAT,
4876 GST_FOURCC_ARGS (vids->compression));
4880 gst_buffer_unref (buf);
4882 if (vids != (gst_riff_strf_vids *) data)
4885 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_UNCOMPRESSED)) {
4887 GstVideoFormat format;
4889 gst_video_info_init (&info);
4890 switch (videocontext->fourcc) {
4891 case GST_MAKE_FOURCC ('I', '4', '2', '0'):
4892 format = GST_VIDEO_FORMAT_I420;
4894 case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
4895 format = GST_VIDEO_FORMAT_YUY2;
4897 case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
4898 format = GST_VIDEO_FORMAT_YV12;
4900 case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
4901 format = GST_VIDEO_FORMAT_UYVY;
4903 case GST_MAKE_FOURCC ('A', 'Y', 'U', 'V'):
4904 format = GST_VIDEO_FORMAT_AYUV;
4906 case GST_MAKE_FOURCC ('Y', '8', '0', '0'):
4907 case GST_MAKE_FOURCC ('Y', '8', ' ', ' '):
4908 format = GST_VIDEO_FORMAT_GRAY8;
4910 case GST_MAKE_FOURCC ('R', 'G', 'B', 24):
4911 format = GST_VIDEO_FORMAT_RGB;
4913 case GST_MAKE_FOURCC ('B', 'G', 'R', 24):
4914 format = GST_VIDEO_FORMAT_BGR;
4917 GST_DEBUG ("Unknown fourcc %" GST_FOURCC_FORMAT,
4918 GST_FOURCC_ARGS (videocontext->fourcc));
4922 gst_video_info_set_format (&info, format, videocontext->pixel_width,
4923 videocontext->pixel_height);
4924 caps = gst_video_info_to_caps (&info);
4925 *codec_name = gst_pb_utils_get_codec_description (caps);
4926 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_SP)) {
4927 caps = gst_caps_new_simple ("video/x-divx",
4928 "divxversion", G_TYPE_INT, 4, NULL);
4929 *codec_name = g_strdup ("MPEG-4 simple profile");
4930 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP) ||
4931 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AP)) {
4932 caps = gst_caps_new_simple ("video/mpeg",
4933 "mpegversion", G_TYPE_INT, 4,
4934 "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
4938 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
4939 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
4940 gst_buffer_unref (priv);
4942 gst_codec_utils_mpeg4video_caps_set_level_and_profile (caps, data, size);
4944 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP))
4945 *codec_name = g_strdup ("MPEG-4 advanced simple profile");
4947 *codec_name = g_strdup ("MPEG-4 advanced profile");
4948 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MSMPEG4V3)) {
4950 caps = gst_caps_new_full (gst_structure_new ("video/x-divx",
4951 "divxversion", G_TYPE_INT, 3, NULL),
4952 gst_structure_new ("video/x-msmpeg",
4953 "msmpegversion", G_TYPE_INT, 43, NULL), NULL);
4955 caps = gst_caps_new_simple ("video/x-msmpeg",
4956 "msmpegversion", G_TYPE_INT, 43, NULL);
4957 *codec_name = g_strdup ("Microsoft MPEG-4 v.3");
4958 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1) ||
4959 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG2)) {
4962 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1))
4967 caps = gst_caps_new_simple ("video/mpeg",
4968 "systemstream", G_TYPE_BOOLEAN, FALSE,
4969 "mpegversion", G_TYPE_INT, mpegversion, NULL);
4970 *codec_name = g_strdup_printf ("MPEG-%d video", mpegversion);
4971 context->postprocess_frame = gst_matroska_demux_add_mpeg_seq_header;
4972 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MJPEG)) {
4973 caps = gst_caps_new_empty_simple ("image/jpeg");
4974 *codec_name = g_strdup ("Motion-JPEG");
4975 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AVC)) {
4976 caps = gst_caps_new_empty_simple ("video/x-h264");
4980 /* First byte is the version, second is the profile indication, and third
4981 * is the 5 contraint_set_flags and 3 reserved bits. Fourth byte is the
4982 * level indication. */
4983 gst_codec_utils_h264_caps_set_level_and_profile (caps, data + 1,
4986 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
4987 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
4988 gst_buffer_unref (priv);
4990 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "avc",
4991 "alignment", G_TYPE_STRING, "au", NULL);
4993 GST_WARNING ("No codec data found, assuming output is byte-stream");
4994 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
4997 *codec_name = g_strdup ("H264");
4998 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEGH_HEVC)) {
4999 caps = gst_caps_new_empty_simple ("video/x-h265");
5003 gst_codec_utils_h265_caps_set_level_tier_and_profile (caps, data + 1,
5006 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
5007 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5008 gst_buffer_unref (priv);
5010 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "hvc1",
5011 "alignment", G_TYPE_STRING, "au", NULL);
5013 GST_WARNING ("No codec data found, assuming output is byte-stream");
5014 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
5017 *codec_name = g_strdup ("HEVC");
5018 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1)) ||
5019 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2)) ||
5020 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3)) ||
5021 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))) {
5022 gint rmversion = -1;
5024 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1))
5026 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2))
5028 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3))
5030 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))
5033 caps = gst_caps_new_simple ("video/x-pn-realvideo",
5034 "rmversion", G_TYPE_INT, rmversion, NULL);
5035 GST_DEBUG ("data:%p, size:0x%x", data, size);
5036 /* We need to extract the extradata ! */
5037 if (data && (size >= 0x22)) {
5042 subformat = GST_READ_UINT32_BE (data + 0x1a);
5043 rformat = GST_READ_UINT32_BE (data + 0x1e);
5046 gst_buffer_new_wrapped (g_memdup (data + 0x1a, size - 0x1a),
5048 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, "format",
5049 G_TYPE_INT, rformat, "subformat", G_TYPE_INT, subformat, NULL);
5050 gst_buffer_unref (priv);
5053 *codec_name = g_strdup_printf ("RealVideo %d.0", rmversion);
5054 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_THEORA)) {
5055 caps = gst_caps_new_empty_simple ("video/x-theora");
5056 context->stream_headers =
5057 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
5058 context->codec_priv_size);
5059 /* FIXME: mark stream as broken and skip if there are no stream headers */
5060 context->send_stream_headers = TRUE;
5061 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_DIRAC)) {
5062 caps = gst_caps_new_empty_simple ("video/x-dirac");
5063 *codec_name = g_strdup_printf ("Dirac");
5064 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8)) {
5065 caps = gst_caps_new_empty_simple ("video/x-vp8");
5066 *codec_name = g_strdup_printf ("On2 VP8");
5067 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP9)) {
5068 caps = gst_caps_new_empty_simple ("video/x-vp9");
5069 *codec_name = g_strdup_printf ("On2 VP9");
5071 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
5077 GstStructure *structure;
5079 for (i = 0; i < gst_caps_get_size (caps); i++) {
5080 structure = gst_caps_get_structure (caps, i);
5082 /* FIXME: use the real unit here! */
5083 GST_DEBUG ("video size %dx%d, target display size %dx%d (any unit)",
5084 videocontext->pixel_width,
5085 videocontext->pixel_height,
5086 videocontext->display_width, videocontext->display_height);
5088 /* pixel width and height are the w and h of the video in pixels */
5089 if (videocontext->pixel_width > 0 && videocontext->pixel_height > 0) {
5090 gint w = videocontext->pixel_width;
5091 gint h = videocontext->pixel_height;
5093 gst_structure_set (structure,
5094 "width", G_TYPE_INT, w, "height", G_TYPE_INT, h, NULL);
5097 if (videocontext->display_width > 0 || videocontext->display_height > 0) {
5100 if (videocontext->display_width <= 0)
5101 videocontext->display_width = videocontext->pixel_width;
5102 if (videocontext->display_height <= 0)
5103 videocontext->display_height = videocontext->pixel_height;
5105 /* calculate the pixel aspect ratio using the display and pixel w/h */
5106 n = videocontext->display_width * videocontext->pixel_height;
5107 d = videocontext->display_height * videocontext->pixel_width;
5108 GST_DEBUG ("setting PAR to %d/%d", n, d);
5109 gst_structure_set (structure, "pixel-aspect-ratio",
5111 videocontext->display_width * videocontext->pixel_height,
5112 videocontext->display_height * videocontext->pixel_width, NULL);
5115 if (videocontext->default_fps > 0.0) {
5118 gst_util_double_to_fraction (videocontext->default_fps, &fps_n, &fps_d);
5120 GST_DEBUG ("using default fps %d/%d", fps_n, fps_d);
5122 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION, fps_n,
5124 } else if (context->default_duration > 0) {
5127 gst_video_guess_framerate (context->default_duration, &fps_n, &fps_d);
5129 GST_INFO ("using default duration %" G_GUINT64_FORMAT
5130 " framerate %d/%d", context->default_duration, fps_n, fps_d);
5132 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
5133 fps_n, fps_d, NULL);
5135 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
5139 if (videocontext->parent.flags & GST_MATROSKA_VIDEOTRACK_INTERLACED)
5140 gst_structure_set (structure, "interlace-mode", G_TYPE_STRING,
5144 caps = gst_caps_simplify (caps);
5151 * Some AAC specific code... *sigh*
5152 * FIXME: maybe we should use '15' and code the sample rate explicitly
5153 * if the sample rate doesn't match the predefined rates exactly? (tpm)
5157 aac_rate_idx (gint rate)
5161 else if (75132 <= rate)
5163 else if (55426 <= rate)
5165 else if (46009 <= rate)
5167 else if (37566 <= rate)
5169 else if (27713 <= rate)
5171 else if (23004 <= rate)
5173 else if (18783 <= rate)
5175 else if (13856 <= rate)
5177 else if (11502 <= rate)
5179 else if (9391 <= rate)
5186 aac_profile_idx (const gchar * codec_id)
5190 if (strlen (codec_id) <= 12)
5192 else if (!strncmp (&codec_id[12], "MAIN", 4))
5194 else if (!strncmp (&codec_id[12], "LC", 2))
5196 else if (!strncmp (&codec_id[12], "SSR", 3))
5205 round_up_pow2 (guint n)
5216 #define AAC_SYNC_EXTENSION_TYPE 0x02b7
5219 gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext *
5220 audiocontext, const gchar * codec_id, guint8 * data, guint size,
5221 gchar ** codec_name, guint16 * riff_audio_fmt)
5223 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) audiocontext;
5224 GstCaps *caps = NULL;
5226 g_assert (audiocontext != NULL);
5227 g_assert (codec_name != NULL);
5230 *riff_audio_fmt = 0;
5232 /* TODO: check if we have all codec types from matroska-ids.h
5233 * check if we have to do more special things with codec_private
5234 * check if we need bitdepth in different places too
5235 * implement channel position magic
5237 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID9
5238 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID10
5239 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDMC
5240 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDM2
5243 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1) ||
5244 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2) ||
5245 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L3)) {
5248 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1))
5250 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2))
5255 caps = gst_caps_new_simple ("audio/mpeg",
5256 "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, layer, NULL);
5257 *codec_name = g_strdup_printf ("MPEG-1 layer %d", layer);
5258 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE) ||
5259 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_LE)) {
5262 GstAudioFormat format;
5264 sign = (audiocontext->bitdepth != 8);
5265 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE))
5266 endianness = G_BIG_ENDIAN;
5268 endianness = G_LITTLE_ENDIAN;
5270 format = gst_audio_format_build_integer (sign, endianness,
5271 audiocontext->bitdepth, audiocontext->bitdepth);
5273 /* FIXME: Channel mask and reordering */
5274 caps = gst_caps_new_simple ("audio/x-raw",
5275 "format", G_TYPE_STRING, gst_audio_format_to_string (format),
5276 "layout", G_TYPE_STRING, "interleaved", NULL);
5278 *codec_name = g_strdup_printf ("Raw %d-bit PCM audio",
5279 audiocontext->bitdepth);
5280 context->alignment = GST_ROUND_UP_8 (audiocontext->bitdepth) / 8;
5281 context->alignment = round_up_pow2 (context->alignment);
5282 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_FLOAT)) {
5283 const gchar *format;
5284 if (audiocontext->bitdepth == 32)
5288 /* FIXME: Channel mask and reordering */
5289 caps = gst_caps_new_simple ("audio/x-raw",
5290 "format", G_TYPE_STRING, format,
5291 "layout", G_TYPE_STRING, "interleaved", NULL);
5292 *codec_name = g_strdup_printf ("Raw %d-bit floating-point audio",
5293 audiocontext->bitdepth);
5294 context->alignment = audiocontext->bitdepth / 8;
5295 context->alignment = round_up_pow2 (context->alignment);
5296 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AC3,
5297 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AC3))) {
5298 caps = gst_caps_new_simple ("audio/x-ac3",
5299 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5300 *codec_name = g_strdup ("AC-3 audio");
5301 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_EAC3,
5302 strlen (GST_MATROSKA_CODEC_ID_AUDIO_EAC3))) {
5303 caps = gst_caps_new_simple ("audio/x-eac3",
5304 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5305 *codec_name = g_strdup ("E-AC-3 audio");
5306 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TRUEHD,
5307 strlen (GST_MATROSKA_CODEC_ID_AUDIO_TRUEHD))) {
5308 caps = gst_caps_new_empty_simple ("audio/x-true-hd");
5309 *codec_name = g_strdup ("Dolby TrueHD");
5310 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_DTS)) {
5311 caps = gst_caps_new_empty_simple ("audio/x-dts");
5312 *codec_name = g_strdup ("DTS audio");
5313 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_VORBIS)) {
5314 caps = gst_caps_new_empty_simple ("audio/x-vorbis");
5315 context->stream_headers =
5316 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
5317 context->codec_priv_size);
5318 /* FIXME: mark stream as broken and skip if there are no stream headers */
5319 context->send_stream_headers = TRUE;
5320 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_FLAC)) {
5321 caps = gst_caps_new_empty_simple ("audio/x-flac");
5322 context->stream_headers =
5323 gst_matroska_parse_flac_stream_headers (context->codec_priv,
5324 context->codec_priv_size);
5325 /* FIXME: mark stream as broken and skip if there are no stream headers */
5326 context->send_stream_headers = TRUE;
5327 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_SPEEX)) {
5328 caps = gst_caps_new_empty_simple ("audio/x-speex");
5329 context->stream_headers =
5330 gst_matroska_parse_speex_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_OPUS)) {
5335 caps = gst_caps_new_empty_simple ("audio/x-opus");
5336 *codec_name = g_strdup ("Opus");
5337 context->stream_headers =
5338 gst_matroska_parse_opus_stream_headers (context->codec_priv,
5339 context->codec_priv_size);
5340 if (context->stream_headers) {
5341 /* There was a valid header. Multistream headers are more than
5342 * 19 bytes, as they include an extra channel mapping table. */
5343 gboolean multistream = (context->codec_priv_size > 19);
5344 gst_caps_set_simple (caps, "multistream", G_TYPE_BOOLEAN, multistream,
5347 /* FIXME: mark stream as broken and skip if there are no stream headers */
5348 context->send_stream_headers = TRUE;
5349 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_ACM)) {
5350 gst_riff_strf_auds auds;
5352 if (data && size >= 18) {
5353 GstBuffer *codec_data = NULL;
5355 /* little-endian -> byte-order */
5356 auds.format = GST_READ_UINT16_LE (data);
5357 auds.channels = GST_READ_UINT16_LE (data + 2);
5358 auds.rate = GST_READ_UINT32_LE (data + 4);
5359 auds.av_bps = GST_READ_UINT32_LE (data + 8);
5360 auds.blockalign = GST_READ_UINT16_LE (data + 12);
5361 auds.bits_per_sample = GST_READ_UINT16_LE (data + 16);
5363 /* 18 is the waveformatex size */
5365 codec_data = gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY,
5366 data + 18, size - 18, 0, size - 18, NULL, NULL);
5370 *riff_audio_fmt = auds.format;
5372 /* FIXME: Handle reorder map */
5373 caps = gst_riff_create_audio_caps (auds.format, NULL, &auds, NULL,
5374 codec_data, codec_name, NULL);
5376 gst_buffer_unref (codec_data);
5379 GST_WARNING ("Unhandled RIFF audio format 0x%02x", auds.format);
5382 GST_WARNING ("Invalid codec data size (%d expected, got %d)", 18, size);
5384 } else if (g_str_has_prefix (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC)) {
5385 GstBuffer *priv = NULL;
5387 gint rate_idx, profile;
5388 guint8 *data = NULL;
5390 /* unspecified AAC profile with opaque private codec data */
5391 if (strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC) == 0) {
5392 if (context->codec_priv_size >= 2) {
5393 guint obj_type, freq_index, explicit_freq_bytes = 0;
5395 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
5397 freq_index = (GST_READ_UINT16_BE (context->codec_priv) & 0x780) >> 7;
5398 obj_type = (GST_READ_UINT16_BE (context->codec_priv) & 0xF800) >> 11;
5399 if (freq_index == 15)
5400 explicit_freq_bytes = 3;
5401 GST_DEBUG ("obj_type = %u, freq_index = %u", obj_type, freq_index);
5402 priv = gst_buffer_new_wrapped (g_memdup (context->codec_priv,
5403 context->codec_priv_size), context->codec_priv_size);
5404 /* assume SBR if samplerate <= 24kHz */
5405 if (obj_type == 5 || (freq_index >= 6 && freq_index != 15) ||
5406 (context->codec_priv_size == (5 + explicit_freq_bytes))) {
5407 audiocontext->samplerate *= 2;
5410 GST_WARNING ("Opaque A_AAC codec ID, but no codec private data");
5411 /* this is pretty broken;
5412 * maybe we need to make up some default private,
5413 * or maybe ADTS data got dumped in.
5414 * Let's set up some private data now, and check actual data later */
5415 /* just try this and see what happens ... */
5416 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
5417 context->postprocess_frame = gst_matroska_demux_check_aac;
5421 /* make up decoder-specific data if it is not supplied */
5425 priv = gst_buffer_new_allocate (NULL, 5, NULL);
5426 gst_buffer_map (priv, &map, GST_MAP_WRITE);
5428 rate_idx = aac_rate_idx (audiocontext->samplerate);
5429 profile = aac_profile_idx (codec_id);
5431 data[0] = ((profile + 1) << 3) | ((rate_idx & 0xE) >> 1);
5432 data[1] = ((rate_idx & 0x1) << 7) | (audiocontext->channels << 3);
5434 if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2,
5435 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2))) {
5437 gst_buffer_unmap (priv, &map);
5438 gst_buffer_set_size (priv, 2);
5439 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4,
5440 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4))) {
5443 if (g_strrstr (codec_id, "SBR")) {
5444 /* HE-AAC (aka SBR AAC) */
5445 audiocontext->samplerate *= 2;
5446 rate_idx = aac_rate_idx (audiocontext->samplerate);
5447 data[2] = AAC_SYNC_EXTENSION_TYPE >> 3;
5448 data[3] = ((AAC_SYNC_EXTENSION_TYPE & 0x07) << 5) | 5;
5449 data[4] = (1 << 7) | (rate_idx << 3);
5450 gst_buffer_unmap (priv, &map);
5452 gst_buffer_unmap (priv, &map);
5453 gst_buffer_set_size (priv, 2);
5456 gst_buffer_unmap (priv, &map);
5457 gst_buffer_unref (priv);
5459 GST_ERROR ("Unknown AAC profile and no codec private data");
5464 caps = gst_caps_new_simple ("audio/mpeg",
5465 "mpegversion", G_TYPE_INT, mpegversion,
5466 "framed", G_TYPE_BOOLEAN, TRUE,
5467 "stream-format", G_TYPE_STRING, "raw", NULL);
5468 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5469 if (context->codec_priv && context->codec_priv_size > 0)
5470 gst_codec_utils_aac_caps_set_level_and_profile (caps,
5471 context->codec_priv, context->codec_priv_size);
5472 *codec_name = g_strdup_printf ("MPEG-%d AAC audio", mpegversion);
5473 gst_buffer_unref (priv);
5475 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TTA)) {
5476 caps = gst_caps_new_simple ("audio/x-tta",
5477 "width", G_TYPE_INT, audiocontext->bitdepth, NULL);
5478 *codec_name = g_strdup ("TTA audio");
5479 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_WAVPACK4)) {
5480 caps = gst_caps_new_simple ("audio/x-wavpack",
5481 "width", G_TYPE_INT, audiocontext->bitdepth,
5482 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5483 *codec_name = g_strdup ("Wavpack audio");
5484 context->postprocess_frame = gst_matroska_demux_add_wvpk_header;
5485 audiocontext->wvpk_block_index = 0;
5486 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4)) ||
5487 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_28_8)) ||
5488 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))) {
5489 gint raversion = -1;
5491 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4))
5493 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))
5498 caps = gst_caps_new_simple ("audio/x-pn-realaudio",
5499 "raversion", G_TYPE_INT, raversion, NULL);
5500 /* Extract extra information from caps, mapping varies based on codec */
5501 if (data && (size >= 0x50)) {
5508 guint extra_data_size;
5510 GST_ERROR ("real audio raversion:%d", raversion);
5511 if (raversion == 8) {
5513 flavor = GST_READ_UINT16_BE (data + 22);
5514 packet_size = GST_READ_UINT32_BE (data + 24);
5515 height = GST_READ_UINT16_BE (data + 40);
5516 leaf_size = GST_READ_UINT16_BE (data + 44);
5517 sample_width = GST_READ_UINT16_BE (data + 58);
5518 extra_data_size = GST_READ_UINT32_BE (data + 74);
5521 ("flavor:%d, packet_size:%d, height:%d, leaf_size:%d, sample_width:%d, extra_data_size:%d",
5522 flavor, packet_size, height, leaf_size, sample_width,
5524 gst_caps_set_simple (caps, "flavor", G_TYPE_INT, flavor, "packet_size",
5525 G_TYPE_INT, packet_size, "height", G_TYPE_INT, height, "leaf_size",
5526 G_TYPE_INT, leaf_size, "width", G_TYPE_INT, sample_width, NULL);
5528 if ((size - 78) >= extra_data_size) {
5529 priv = gst_buffer_new_wrapped (g_memdup (data + 78, extra_data_size),
5531 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5532 gst_buffer_unref (priv);
5537 *codec_name = g_strdup_printf ("RealAudio %d.0", raversion);
5538 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_SIPR)) {
5539 caps = gst_caps_new_empty_simple ("audio/x-sipro");
5540 *codec_name = g_strdup ("Sipro/ACELP.NET Voice Codec");
5541 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_RALF)) {
5542 caps = gst_caps_new_empty_simple ("audio/x-ralf-mpeg4-generic");
5543 *codec_name = g_strdup ("Real Audio Lossless");
5544 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_ATRC)) {
5545 caps = gst_caps_new_empty_simple ("audio/x-vnd.sony.atrac3");
5546 *codec_name = g_strdup ("Sony ATRAC3");
5548 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
5553 if (audiocontext->samplerate > 0 && audiocontext->channels > 0) {
5556 for (i = 0; i < gst_caps_get_size (caps); i++) {
5557 gst_structure_set (gst_caps_get_structure (caps, i),
5558 "channels", G_TYPE_INT, audiocontext->channels,
5559 "rate", G_TYPE_INT, audiocontext->samplerate, NULL);
5563 caps = gst_caps_simplify (caps);
5570 gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
5571 subtitlecontext, const gchar * codec_id, gpointer data, guint size)
5573 GstCaps *caps = NULL;
5574 GstMatroskaTrackContext *context =
5575 (GstMatroskaTrackContext *) subtitlecontext;
5577 /* for backwards compatibility */
5578 if (!g_ascii_strcasecmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASCII))
5579 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8;
5580 else if (!g_ascii_strcasecmp (codec_id, "S_SSA"))
5581 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_SSA;
5582 else if (!g_ascii_strcasecmp (codec_id, "S_ASS"))
5583 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_ASS;
5584 else if (!g_ascii_strcasecmp (codec_id, "S_USF"))
5585 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_USF;
5587 /* TODO: Add GST_MATROSKA_CODEC_ID_SUBTITLE_BMP support
5588 * Check if we have to do something with codec_private */
5589 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8)) {
5590 /* well, plain text simply does not have a lot of markup ... */
5591 caps = gst_caps_new_simple ("text/x-raw", "format", G_TYPE_STRING,
5592 "pango-markup", NULL);
5593 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5594 subtitlecontext->check_markup = TRUE;
5595 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_SSA)) {
5596 caps = gst_caps_new_empty_simple ("application/x-ssa");
5597 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5598 subtitlecontext->check_markup = FALSE;
5599 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASS)) {
5600 caps = gst_caps_new_empty_simple ("application/x-ass");
5601 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5602 subtitlecontext->check_markup = FALSE;
5603 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_USF)) {
5604 caps = gst_caps_new_empty_simple ("application/x-usf");
5605 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5606 subtitlecontext->check_markup = FALSE;
5607 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB)) {
5608 caps = gst_caps_new_empty_simple ("subpicture/x-dvd");
5609 ((GstMatroskaTrackContext *) subtitlecontext)->send_dvd_event = TRUE;
5610 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_HDMVPGS)) {
5611 caps = gst_caps_new_empty_simple ("subpicture/x-pgs");
5612 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_KATE)) {
5613 caps = gst_caps_new_empty_simple ("subtitle/x-kate");
5614 context->stream_headers =
5615 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
5616 context->codec_priv_size);
5617 /* FIXME: mark stream as broken and skip if there are no stream headers */
5618 context->send_stream_headers = TRUE;
5620 GST_DEBUG ("Unknown subtitle stream: codec_id='%s'", codec_id);
5621 caps = gst_caps_new_empty_simple ("application/x-subtitle-unknown");
5624 if (data != NULL && size > 0) {
5627 buf = gst_buffer_new_wrapped (g_memdup (data, size), size);
5628 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, buf, NULL);
5629 gst_buffer_unref (buf);
5637 gst_matroska_demux_set_index (GstElement * element, GstIndex * index)
5639 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5641 GST_OBJECT_LOCK (demux);
5642 if (demux->common.element_index)
5643 gst_object_unref (demux->common.element_index);
5644 demux->common.element_index = index ? gst_object_ref (index) : NULL;
5645 GST_OBJECT_UNLOCK (demux);
5646 GST_DEBUG_OBJECT (demux, "Set index %" GST_PTR_FORMAT,
5647 demux->common.element_index);
5651 gst_matroska_demux_get_index (GstElement * element)
5653 GstIndex *result = NULL;
5654 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5656 GST_OBJECT_LOCK (demux);
5657 if (demux->common.element_index)
5658 result = gst_object_ref (demux->common.element_index);
5659 GST_OBJECT_UNLOCK (demux);
5661 GST_DEBUG_OBJECT (demux, "Returning index %" GST_PTR_FORMAT, result);
5667 static GstStateChangeReturn
5668 gst_matroska_demux_change_state (GstElement * element,
5669 GstStateChange transition)
5671 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5672 GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
5674 /* handle upwards state changes here */
5675 switch (transition) {
5680 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
5682 /* handle downwards state changes */
5683 switch (transition) {
5684 case GST_STATE_CHANGE_PAUSED_TO_READY:
5685 gst_matroska_demux_reset (GST_ELEMENT (demux));
5695 gst_matroska_demux_set_property (GObject * object,
5696 guint prop_id, const GValue * value, GParamSpec * pspec)
5698 GstMatroskaDemux *demux;
5700 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
5701 demux = GST_MATROSKA_DEMUX (object);
5704 case ARG_MAX_GAP_TIME:
5705 GST_OBJECT_LOCK (demux);
5706 demux->max_gap_time = g_value_get_uint64 (value);
5707 GST_OBJECT_UNLOCK (demux);
5710 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
5716 gst_matroska_demux_get_property (GObject * object,
5717 guint prop_id, GValue * value, GParamSpec * pspec)
5719 GstMatroskaDemux *demux;
5721 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
5722 demux = GST_MATROSKA_DEMUX (object);
5725 case ARG_MAX_GAP_TIME:
5726 GST_OBJECT_LOCK (demux);
5727 g_value_set_uint64 (value, demux->max_gap_time);
5728 GST_OBJECT_UNLOCK (demux);
5731 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
5737 gst_matroska_demux_plugin_init (GstPlugin * plugin)
5741 /* parser helper separate debug */
5742 GST_DEBUG_CATEGORY_INIT (ebmlread_debug, "ebmlread",
5743 0, "EBML stream helper class");
5745 /* create an elementfactory for the matroska_demux element */
5746 if (!gst_element_register (plugin, "matroskademux",
5747 GST_RANK_PRIMARY, GST_TYPE_MATROSKA_DEMUX))