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 is_segment;
1400 gboolean ret = FALSE;
1403 g_return_val_if_fail (event != NULL, FALSE);
1405 GST_DEBUG_OBJECT (demux, "Sending event of type %s to all source pads",
1406 GST_EVENT_TYPE_NAME (event));
1408 is_segment = (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT);
1410 g_assert (demux->common.src->len == demux->common.num_streams);
1411 for (i = 0; i < demux->common.src->len; i++) {
1412 GstMatroskaTrackContext *stream;
1414 stream = g_ptr_array_index (demux->common.src, i);
1415 gst_event_ref (event);
1416 gst_pad_push_event (stream->pad, event);
1419 /* FIXME: send global tags before stream tags */
1420 if (G_UNLIKELY (is_segment && stream->pending_tags != NULL)) {
1421 GST_DEBUG_OBJECT (demux, "Sending pending_tags %p for pad %s:%s : %"
1422 GST_PTR_FORMAT, stream->pending_tags,
1423 GST_DEBUG_PAD_NAME (stream->pad), stream->pending_tags);
1424 gst_pad_push_event (stream->pad,
1425 gst_event_new_tag (stream->pending_tags));
1426 stream->pending_tags = NULL;
1430 if (G_UNLIKELY (is_segment && demux->common.global_tags != NULL)) {
1431 GstEvent *tag_event;
1432 gst_tag_list_add (demux->common.global_tags, GST_TAG_MERGE_REPLACE,
1433 GST_TAG_CONTAINER_FORMAT, "Matroska", NULL);
1434 GST_DEBUG_OBJECT (demux, "Sending global_tags %p : %" GST_PTR_FORMAT,
1435 demux->common.global_tags, demux->common.global_tags);
1437 tag_event = gst_event_new_tag (demux->common.global_tags);
1439 for (i = 0; i < demux->common.src->len; i++) {
1440 GstMatroskaTrackContext *stream;
1442 stream = g_ptr_array_index (demux->common.src, i);
1443 gst_pad_push_event (stream->pad, gst_event_ref (tag_event));
1446 gst_event_unref (tag_event);
1447 demux->common.global_tags = NULL;
1450 gst_event_unref (event);
1455 gst_matroska_demux_element_send_event (GstElement * element, GstEvent * event)
1457 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
1460 g_return_val_if_fail (event != NULL, FALSE);
1462 if (GST_EVENT_TYPE (event) == GST_EVENT_SEEK) {
1463 res = gst_matroska_demux_handle_seek_event (demux, NULL, event);
1465 GST_WARNING_OBJECT (demux, "Unhandled event of type %s",
1466 GST_EVENT_TYPE_NAME (event));
1469 gst_event_unref (event);
1474 gst_matroska_demux_move_to_entry (GstMatroskaDemux * demux,
1475 GstMatroskaIndex * entry, gboolean reset, gboolean update)
1479 GST_OBJECT_LOCK (demux);
1482 /* seek (relative to matroska segment) */
1483 /* position might be invalid; will error when streaming resumes ... */
1484 demux->common.offset = entry->pos + demux->common.ebml_segment_start;
1485 demux->next_cluster_offset = 0;
1487 GST_DEBUG_OBJECT (demux,
1488 "Seeked to offset %" G_GUINT64_FORMAT ", block %d, " "time %"
1489 GST_TIME_FORMAT, entry->pos + demux->common.ebml_segment_start,
1490 entry->block, GST_TIME_ARGS (entry->time));
1492 /* update the time */
1493 gst_matroska_read_common_reset_streams (&demux->common, entry->time, TRUE);
1494 demux->common.segment.position = entry->time;
1495 demux->seek_block = entry->block;
1496 demux->seek_first = TRUE;
1497 demux->last_stop_end = GST_CLOCK_TIME_NONE;
1500 for (i = 0; i < demux->common.src->len; i++) {
1501 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
1504 stream->to_offset = G_MAXINT64;
1506 if (stream->from_offset != -1)
1507 stream->to_offset = stream->from_offset;
1509 stream->from_offset = -1;
1510 stream->from_time = GST_CLOCK_TIME_NONE;
1513 GST_OBJECT_UNLOCK (demux);
1519 gst_matroska_cluster_compare (gint64 * i1, gint64 * i2)
1529 /* searches for a cluster start from @pos,
1530 * return GST_FLOW_OK and cluster position in @pos if found */
1531 static GstFlowReturn
1532 gst_matroska_demux_search_cluster (GstMatroskaDemux * demux, gint64 * pos)
1534 gint64 newpos = *pos;
1536 GstFlowReturn ret = GST_FLOW_OK;
1537 const guint chunk = 64 * 1024;
1538 GstBuffer *buf = NULL;
1540 gpointer data = NULL;
1545 gint64 oldpos, oldlength;
1547 orig_offset = demux->common.offset;
1549 GST_LOG_OBJECT (demux, "searching cluster following offset %" G_GINT64_FORMAT,
1552 if (demux->clusters) {
1555 cpos = gst_util_array_binary_search (demux->clusters->data,
1556 demux->clusters->len, sizeof (gint64),
1557 (GCompareDataFunc) gst_matroska_cluster_compare,
1558 GST_SEARCH_MODE_AFTER, pos, NULL);
1561 GST_DEBUG_OBJECT (demux,
1562 "cluster reported at offset %" G_GINT64_FORMAT, *cpos);
1563 demux->common.offset = *cpos;
1564 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1565 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1566 if (ret == GST_FLOW_OK && id == GST_MATROSKA_ID_CLUSTER) {
1573 /* read in at newpos and scan for ebml cluster id */
1574 oldpos = oldlength = -1;
1576 GstByteReader reader;
1580 gst_buffer_unmap (buf, &map);
1581 gst_buffer_unref (buf);
1584 ret = gst_pad_pull_range (demux->common.sinkpad, newpos, chunk, &buf);
1585 if (ret != GST_FLOW_OK)
1587 GST_DEBUG_OBJECT (demux,
1588 "read buffer size %" G_GSIZE_FORMAT " at offset %" G_GINT64_FORMAT,
1589 gst_buffer_get_size (buf), newpos);
1590 gst_buffer_map (buf, &map, GST_MAP_READ);
1593 if (oldpos == newpos && oldlength == map.size) {
1594 GST_ERROR_OBJECT (demux, "Stuck at same position");
1595 ret = GST_FLOW_ERROR;
1599 oldlength = map.size;
1602 gst_byte_reader_init (&reader, data, size);
1604 cluster_pos = gst_byte_reader_masked_scan_uint32 (&reader, 0xffffffff,
1605 GST_MATROSKA_ID_CLUSTER, 0, gst_byte_reader_get_remaining (&reader));
1606 if (cluster_pos >= 0) {
1607 newpos += cluster_pos;
1608 /* prepare resuming at next byte */
1609 if (!gst_byte_reader_skip (&reader, cluster_pos + 1)) {
1610 GST_DEBUG_OBJECT (demux, "Need more data -> continue");
1613 GST_DEBUG_OBJECT (demux,
1614 "found cluster ebml id at offset %" G_GINT64_FORMAT, newpos);
1615 /* extra checks whether we really sync'ed to a cluster:
1616 * - either it is the first and only cluster
1617 * - either there is a cluster after this one
1618 * - either cluster length is undefined
1620 /* ok if first cluster (there may not a subsequent one) */
1621 if (newpos == demux->first_cluster_offset) {
1622 GST_DEBUG_OBJECT (demux, "cluster is first cluster -> OK");
1625 demux->common.offset = newpos;
1626 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1627 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1628 if (ret != GST_FLOW_OK) {
1629 GST_DEBUG_OBJECT (demux, "need more data -> continue");
1632 g_assert (id == GST_MATROSKA_ID_CLUSTER);
1633 GST_DEBUG_OBJECT (demux, "cluster size %" G_GUINT64_FORMAT ", prefix %d",
1635 /* ok if undefined length or first cluster */
1636 if (length == GST_EBML_SIZE_UNKNOWN || length == G_MAXUINT64) {
1637 GST_DEBUG_OBJECT (demux, "cluster has undefined length -> OK");
1641 demux->common.offset += length + needed;
1642 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1643 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1644 if (ret != GST_FLOW_OK)
1646 GST_DEBUG_OBJECT (demux, "next element is %scluster",
1647 id == GST_MATROSKA_ID_CLUSTER ? "" : "not ");
1648 if (id == GST_MATROSKA_ID_CLUSTER)
1650 /* not ok, resume */
1653 /* partial cluster id may have been in tail of buffer */
1654 newpos += MAX (gst_byte_reader_get_remaining (&reader), 4) - 3;
1659 gst_buffer_unmap (buf, &map);
1660 gst_buffer_unref (buf);
1665 demux->common.offset = orig_offset;
1670 /* bisect and scan through file for cluster starting before @time,
1671 * returns fake index entry with corresponding info on cluster */
1672 static GstMatroskaIndex *
1673 gst_matroska_demux_search_pos (GstMatroskaDemux * demux, GstClockTime time)
1675 GstMatroskaIndex *entry = NULL;
1676 GstMatroskaReadState current_state;
1677 GstClockTime otime, prev_cluster_time, current_cluster_time, cluster_time;
1678 gint64 opos, newpos, startpos = 0, current_offset;
1679 gint64 prev_cluster_offset = -1, current_cluster_offset, cluster_offset;
1680 const guint chunk = 64 * 1024;
1686 /* (under)estimate new position, resync using cluster ebml id,
1687 * and scan forward to appropriate cluster
1688 * (and re-estimate if need to go backward) */
1690 prev_cluster_time = GST_CLOCK_TIME_NONE;
1692 /* store some current state */
1693 current_state = demux->common.state;
1694 g_return_val_if_fail (current_state == GST_MATROSKA_READ_STATE_DATA, NULL);
1696 current_cluster_offset = demux->cluster_offset;
1697 current_cluster_time = demux->cluster_time;
1698 current_offset = demux->common.offset;
1700 demux->common.state = GST_MATROSKA_READ_STATE_SCANNING;
1702 /* estimate using start and current position */
1703 GST_OBJECT_LOCK (demux);
1704 opos = demux->common.offset - demux->common.ebml_segment_start;
1705 otime = demux->common.segment.position;
1706 GST_OBJECT_UNLOCK (demux);
1709 time = MAX (time, demux->stream_start_time);
1711 /* avoid division by zero in first estimation below */
1712 if (otime <= demux->stream_start_time)
1716 GST_LOG_OBJECT (demux,
1717 "opos: %" G_GUINT64_FORMAT ", otime: %" GST_TIME_FORMAT ", %"
1718 GST_TIME_FORMAT " in stream time (start %" GST_TIME_FORMAT "), time %"
1719 GST_TIME_FORMAT, opos, GST_TIME_ARGS (otime),
1720 GST_TIME_ARGS (otime - demux->stream_start_time),
1721 GST_TIME_ARGS (demux->stream_start_time), GST_TIME_ARGS (time));
1723 if (otime <= demux->stream_start_time) {
1727 gst_util_uint64_scale (opos - demux->common.ebml_segment_start,
1728 time - demux->stream_start_time,
1729 otime - demux->stream_start_time) - chunk;
1733 /* favour undershoot */
1734 newpos = newpos * 90 / 100;
1735 newpos += demux->common.ebml_segment_start;
1737 GST_DEBUG_OBJECT (demux,
1738 "estimated offset for %" GST_TIME_FORMAT ": %" G_GINT64_FORMAT,
1739 GST_TIME_ARGS (time), newpos);
1741 /* and at least start scanning before previous scan start to avoid looping */
1742 startpos = startpos * 90 / 100;
1743 if (startpos && startpos < newpos)
1746 /* read in at newpos and scan for ebml cluster id */
1750 ret = gst_matroska_demux_search_cluster (demux, &newpos);
1751 if (ret == GST_FLOW_EOS) {
1752 /* heuristic HACK */
1753 newpos = startpos * 80 / 100;
1754 GST_DEBUG_OBJECT (demux, "EOS; "
1755 "new estimated offset for %" GST_TIME_FORMAT ": %" G_GINT64_FORMAT,
1756 GST_TIME_ARGS (time), newpos);
1759 } else if (ret != GST_FLOW_OK) {
1766 /* then start scanning and parsing for cluster time,
1767 * re-estimate if overshoot, otherwise next cluster and so on */
1768 demux->common.offset = newpos;
1769 demux->cluster_time = cluster_time = GST_CLOCK_TIME_NONE;
1771 guint64 cluster_size = 0;
1773 /* peek and parse some elements */
1774 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1775 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1776 if (ret != GST_FLOW_OK)
1778 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
1779 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
1781 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
1782 if (ret != GST_FLOW_OK)
1785 if (id == GST_MATROSKA_ID_CLUSTER) {
1786 cluster_time = GST_CLOCK_TIME_NONE;
1787 if (length == G_MAXUINT64)
1790 cluster_size = length + needed;
1792 if (demux->cluster_time != GST_CLOCK_TIME_NONE &&
1793 cluster_time == GST_CLOCK_TIME_NONE) {
1794 cluster_time = demux->cluster_time * demux->common.time_scale;
1795 cluster_offset = demux->cluster_offset;
1796 GST_DEBUG_OBJECT (demux, "found cluster at offset %" G_GINT64_FORMAT
1797 " with time %" GST_TIME_FORMAT, cluster_offset,
1798 GST_TIME_ARGS (cluster_time));
1799 if (cluster_time > time) {
1800 GST_DEBUG_OBJECT (demux, "overshot target");
1801 /* cluster overshoots */
1802 if (cluster_offset == demux->first_cluster_offset) {
1803 /* but no prev one */
1804 GST_DEBUG_OBJECT (demux, "but using first cluster anyway");
1805 prev_cluster_time = cluster_time;
1806 prev_cluster_offset = cluster_offset;
1809 if (prev_cluster_time != GST_CLOCK_TIME_NONE) {
1810 /* prev cluster did not overshoot, so prev cluster is target */
1813 /* re-estimate using this new position info */
1814 opos = cluster_offset;
1815 otime = cluster_time;
1819 /* cluster undershoots, goto next one */
1820 prev_cluster_time = cluster_time;
1821 prev_cluster_offset = cluster_offset;
1822 /* skip cluster if length is defined,
1823 * otherwise will be skippingly parsed into */
1825 GST_DEBUG_OBJECT (demux, "skipping to next cluster");
1826 demux->common.offset = cluster_offset + cluster_size;
1827 demux->cluster_time = GST_CLOCK_TIME_NONE;
1829 GST_DEBUG_OBJECT (demux, "parsing/skipping cluster elements");
1836 if (ret == GST_FLOW_EOS) {
1837 if (prev_cluster_time != GST_CLOCK_TIME_NONE)
1843 entry = g_new0 (GstMatroskaIndex, 1);
1844 entry->time = prev_cluster_time;
1845 entry->pos = prev_cluster_offset - demux->common.ebml_segment_start;
1846 GST_DEBUG_OBJECT (demux, "simulated index entry; time %" GST_TIME_FORMAT
1847 ", pos %" G_GUINT64_FORMAT, GST_TIME_ARGS (entry->time), entry->pos);
1851 /* restore some state */
1852 demux->cluster_offset = current_cluster_offset;
1853 demux->cluster_time = current_cluster_time;
1854 demux->common.offset = current_offset;
1855 demux->common.state = current_state;
1861 gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
1862 GstPad * pad, GstEvent * event)
1864 GstMatroskaIndex *entry = NULL;
1865 GstMatroskaIndex scan_entry;
1867 GstSeekType cur_type, stop_type;
1869 gboolean flush, keyunit, before, after, snap_next;
1872 GstMatroskaTrackContext *track = NULL;
1873 GstSegment seeksegment = { 0, };
1874 gboolean update = TRUE;
1875 gboolean pad_locked = FALSE;
1877 GstSearchMode snap_dir;
1879 g_return_val_if_fail (event != NULL, FALSE);
1882 track = gst_pad_get_element_private (pad);
1884 GST_DEBUG_OBJECT (demux, "Have seek %" GST_PTR_FORMAT, event);
1886 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
1888 seqnum = gst_event_get_seqnum (event);
1890 /* we can only seek on time */
1891 if (format != GST_FORMAT_TIME) {
1892 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
1896 /* copy segment, we need this because we still need the old
1897 * segment when we close the current segment. */
1898 memcpy (&seeksegment, &demux->common.segment, sizeof (GstSegment));
1900 /* pull mode without index means that the actual duration is not known,
1901 * we might be playing a file that's still being recorded
1902 * so, invalidate our current duration, which is only a moving target,
1903 * and should not be used to clamp anything */
1904 if (!demux->streaming && !demux->common.index && demux->invalid_duration) {
1905 seeksegment.duration = GST_CLOCK_TIME_NONE;
1908 GST_DEBUG_OBJECT (demux, "configuring seek");
1909 /* Subtract stream_start_time so we always seek on a segment
1911 if (GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
1912 seeksegment.start -= demux->stream_start_time;
1913 seeksegment.position -= demux->stream_start_time;
1914 if (GST_CLOCK_TIME_IS_VALID (seeksegment.stop))
1915 seeksegment.stop -= demux->stream_start_time;
1917 seeksegment.stop = seeksegment.duration;
1920 gst_segment_do_seek (&seeksegment, rate, format, flags,
1921 cur_type, cur, stop_type, stop, &update);
1923 /* Restore the clip timestamp offset */
1924 if (GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
1925 seeksegment.position += demux->stream_start_time;
1926 seeksegment.start += demux->stream_start_time;
1927 if (!GST_CLOCK_TIME_IS_VALID (seeksegment.stop))
1928 seeksegment.stop = seeksegment.duration;
1929 if (GST_CLOCK_TIME_IS_VALID (seeksegment.stop))
1930 seeksegment.stop += demux->stream_start_time;
1933 /* restore segment duration (if any effect),
1934 * would be determined again when parsing, but anyway ... */
1935 seeksegment.duration = demux->common.segment.duration;
1937 flush = ! !(flags & GST_SEEK_FLAG_FLUSH);
1938 keyunit = ! !(flags & GST_SEEK_FLAG_KEY_UNIT);
1939 after = ! !(flags & GST_SEEK_FLAG_SNAP_AFTER);
1940 before = ! !(flags & GST_SEEK_FLAG_SNAP_BEFORE);
1942 /* always do full update if flushing,
1943 * otherwise problems might arise downstream with missing keyframes etc */
1944 update = update || flush;
1946 GST_DEBUG_OBJECT (demux, "New segment %" GST_SEGMENT_FORMAT, &seeksegment);
1948 /* check sanity before we start flushing and all that */
1949 snap_next = after && !before;
1950 if (seeksegment.rate < 0)
1951 snap_dir = snap_next ? GST_SEARCH_MODE_BEFORE : GST_SEARCH_MODE_AFTER;
1953 snap_dir = snap_next ? GST_SEARCH_MODE_AFTER : GST_SEARCH_MODE_BEFORE;
1955 GST_OBJECT_LOCK (demux);
1956 track = gst_matroska_read_common_get_seek_track (&demux->common, track);
1957 if ((entry = gst_matroska_read_common_do_index_seek (&demux->common, track,
1958 seeksegment.position, &demux->seek_index, &demux->seek_entry,
1959 snap_dir)) == NULL) {
1960 /* pull mode without index can scan later on */
1961 if (demux->streaming) {
1962 GST_DEBUG_OBJECT (demux, "No matching seek entry in index");
1963 GST_OBJECT_UNLOCK (demux);
1965 } else if (rate < 0.0) {
1966 /* FIXME: We should build an index during playback or when scanning
1967 * that can be used here. The reverse playback code requires seek_index
1968 * and seek_entry to be set!
1970 GST_DEBUG_OBJECT (demux,
1971 "No matching seek entry in index, needed for reverse playback");
1972 GST_OBJECT_UNLOCK (demux);
1976 GST_DEBUG_OBJECT (demux, "Seek position looks sane");
1977 GST_OBJECT_UNLOCK (demux);
1980 /* only have to update some segment,
1981 * but also still have to honour flush and so on */
1982 GST_DEBUG_OBJECT (demux, "... no update");
1983 /* bad goto, bad ... */
1987 if (demux->streaming)
1992 GstEvent *flush_event = gst_event_new_flush_start ();
1993 gst_event_set_seqnum (flush_event, seqnum);
1994 GST_DEBUG_OBJECT (demux, "Starting flush");
1995 gst_pad_push_event (demux->common.sinkpad, gst_event_ref (flush_event));
1996 gst_matroska_demux_send_event (demux, flush_event);
1998 GST_DEBUG_OBJECT (demux, "Non-flushing seek, pausing task");
1999 gst_pad_pause_task (demux->common.sinkpad);
2003 GST_PAD_STREAM_LOCK (demux->common.sinkpad);
2008 /* now grab the stream lock so that streaming cannot continue, for
2009 * non flushing seeks when the element is in PAUSED this could block
2011 GST_DEBUG_OBJECT (demux, "Waiting for streaming to stop");
2012 GST_PAD_STREAM_LOCK (demux->common.sinkpad);
2015 /* pull mode without index can do some scanning */
2016 if (!demux->streaming && !entry) {
2017 GstEvent *flush_event;
2019 /* need to stop flushing upstream as we need it next */
2021 flush_event = gst_event_new_flush_stop (TRUE);
2022 gst_event_set_seqnum (flush_event, seqnum);
2023 gst_pad_push_event (demux->common.sinkpad, flush_event);
2025 entry = gst_matroska_demux_search_pos (demux, seeksegment.position);
2026 /* keep local copy */
2028 scan_entry = *entry;
2030 entry = &scan_entry;
2032 GST_DEBUG_OBJECT (demux, "Scan failed to find matching position");
2034 flush_event = gst_event_new_flush_stop (TRUE);
2035 gst_event_set_seqnum (flush_event, seqnum);
2036 gst_matroska_demux_send_event (demux, flush_event);
2044 GST_DEBUG_OBJECT (demux, "seek to key unit, adjusting segment start from %"
2045 GST_TIME_FORMAT " to %" GST_TIME_FORMAT,
2046 GST_TIME_ARGS (seeksegment.start), GST_TIME_ARGS (entry->time));
2047 seeksegment.start = MAX (entry->time, demux->stream_start_time);
2048 seeksegment.position = seeksegment.start;
2049 seeksegment.time = seeksegment.start - demux->stream_start_time;
2052 if (demux->streaming) {
2053 GST_OBJECT_LOCK (demux);
2054 /* track real position we should start at */
2055 GST_DEBUG_OBJECT (demux, "storing segment start");
2056 demux->requested_seek_time = seeksegment.position;
2057 demux->seek_offset = entry->pos + demux->common.ebml_segment_start;
2058 GST_OBJECT_UNLOCK (demux);
2059 /* need to seek to cluster start to pick up cluster time */
2060 /* upstream takes care of flushing and all that
2061 * ... and newsegment event handling takes care of the rest */
2062 return perform_seek_to_offset (demux, rate,
2063 entry->pos + demux->common.ebml_segment_start, seqnum);
2068 GstEvent *flush_event = gst_event_new_flush_stop (TRUE);
2069 gst_event_set_seqnum (flush_event, seqnum);
2070 GST_DEBUG_OBJECT (demux, "Stopping flush");
2071 gst_pad_push_event (demux->common.sinkpad, gst_event_ref (flush_event));
2072 gst_matroska_demux_send_event (demux, flush_event);
2075 GST_OBJECT_LOCK (demux);
2076 /* now update the real segment info */
2077 GST_DEBUG_OBJECT (demux, "Committing new seek segment");
2078 memcpy (&demux->common.segment, &seeksegment, sizeof (GstSegment));
2079 GST_OBJECT_UNLOCK (demux);
2081 /* update some (segment) state */
2082 if (!gst_matroska_demux_move_to_entry (demux, entry, TRUE, update))
2085 /* notify start of new segment */
2086 if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
2089 msg = gst_message_new_segment_start (GST_OBJECT (demux),
2090 GST_FORMAT_TIME, demux->common.segment.start);
2091 gst_message_set_seqnum (msg, seqnum);
2092 gst_element_post_message (GST_ELEMENT (demux), msg);
2095 GST_OBJECT_LOCK (demux);
2096 if (demux->new_segment)
2097 gst_event_unref (demux->new_segment);
2099 /* On port from 0.10, discarded !update (for segment.update) here, FIXME? */
2100 demux->new_segment = gst_event_new_segment (&demux->common.segment);
2101 gst_event_set_seqnum (demux->new_segment, seqnum);
2102 if (demux->common.segment.rate < 0 && demux->common.segment.stop == -1)
2103 demux->to_time = demux->common.segment.position;
2105 demux->to_time = GST_CLOCK_TIME_NONE;
2106 GST_OBJECT_UNLOCK (demux);
2108 /* restart our task since it might have been stopped when we did the
2110 gst_pad_start_task (demux->common.sinkpad,
2111 (GstTaskFunction) gst_matroska_demux_loop, demux->common.sinkpad, NULL);
2113 /* streaming can continue now */
2115 GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
2123 GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
2125 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Got a seek error"));
2131 * Handle whether we can perform the seek event or if we have to let the chain
2132 * function handle seeks to build the seek indexes first.
2135 gst_matroska_demux_handle_seek_push (GstMatroskaDemux * demux, GstPad * pad,
2139 GstSeekType cur_type, stop_type;
2144 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
2149 /* we can only seek on time */
2150 if (format != GST_FORMAT_TIME) {
2151 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
2155 if (stop_type != GST_SEEK_TYPE_NONE && stop != GST_CLOCK_TIME_NONE) {
2156 GST_DEBUG_OBJECT (demux, "Seek end-time not supported in streaming mode");
2160 if (!(flags & GST_SEEK_FLAG_FLUSH)) {
2161 GST_DEBUG_OBJECT (demux,
2162 "Non-flushing seek not supported in streaming mode");
2166 if (flags & GST_SEEK_FLAG_SEGMENT) {
2167 GST_DEBUG_OBJECT (demux, "Segment seek not supported in streaming mode");
2171 /* check for having parsed index already */
2172 if (!demux->common.index_parsed) {
2173 gboolean building_index;
2176 if (!demux->index_offset) {
2177 GST_DEBUG_OBJECT (demux, "no index (location); no seek in push mode");
2181 GST_OBJECT_LOCK (demux);
2182 /* handle the seek event in the chain function */
2183 demux->common.state = GST_MATROSKA_READ_STATE_SEEK;
2184 /* no more seek can be issued until state reset to _DATA */
2186 /* copy the event */
2187 if (demux->seek_event)
2188 gst_event_unref (demux->seek_event);
2189 demux->seek_event = gst_event_ref (event);
2191 /* set the building_index flag so that only one thread can setup the
2192 * structures for index seeking. */
2193 building_index = demux->building_index;
2194 if (!building_index) {
2195 demux->building_index = TRUE;
2196 offset = demux->index_offset;
2198 GST_OBJECT_UNLOCK (demux);
2200 if (!building_index) {
2201 /* seek to the first subindex or legacy index */
2202 GST_INFO_OBJECT (demux, "Seeking to Cues at %" G_GUINT64_FORMAT, offset);
2203 return perform_seek_to_offset (demux, rate, offset,
2204 gst_event_get_seqnum (event));
2207 /* well, we are handling it already */
2211 /* delegate to tweaked regular seek */
2212 return gst_matroska_demux_handle_seek_event (demux, pad, event);
2216 gst_matroska_demux_handle_src_event (GstPad * pad, GstObject * parent,
2219 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
2220 gboolean res = TRUE;
2222 switch (GST_EVENT_TYPE (event)) {
2223 case GST_EVENT_SEEK:
2224 /* no seeking until we are (safely) ready */
2225 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
2226 GST_DEBUG_OBJECT (demux, "not ready for seeking yet");
2229 if (!demux->streaming)
2230 res = gst_matroska_demux_handle_seek_event (demux, pad, event);
2232 res = gst_matroska_demux_handle_seek_push (demux, pad, event);
2233 gst_event_unref (event);
2238 GstMatroskaTrackContext *context = gst_pad_get_element_private (pad);
2239 if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
2240 GstMatroskaTrackVideoContext *videocontext =
2241 (GstMatroskaTrackVideoContext *) context;
2243 GstClockTimeDiff diff;
2244 GstClockTime timestamp;
2246 gst_event_parse_qos (event, NULL, &proportion, &diff, ×tamp);
2248 GST_OBJECT_LOCK (demux);
2249 videocontext->earliest_time = timestamp + diff;
2250 GST_OBJECT_UNLOCK (demux);
2253 gst_event_unref (event);
2257 case GST_EVENT_TOC_SELECT:
2260 GstTocEntry *entry = NULL;
2261 GstEvent *seek_event;
2264 if (!demux->common.toc) {
2265 GST_DEBUG_OBJECT (demux, "no TOC to select");
2268 gst_event_parse_toc_select (event, &uid);
2270 GST_OBJECT_LOCK (demux);
2271 entry = gst_toc_find_entry (demux->common.toc, uid);
2272 if (entry == NULL) {
2273 GST_OBJECT_UNLOCK (demux);
2274 GST_WARNING_OBJECT (demux, "no TOC entry with given UID: %s", uid);
2277 gst_toc_entry_get_start_stop_times (entry, &start_pos, NULL);
2278 GST_OBJECT_UNLOCK (demux);
2279 seek_event = gst_event_new_seek (1.0,
2281 GST_SEEK_FLAG_FLUSH,
2282 GST_SEEK_TYPE_SET, start_pos, GST_SEEK_TYPE_SET, -1);
2283 res = gst_matroska_demux_handle_seek_event (demux, pad, seek_event);
2284 gst_event_unref (seek_event);
2288 GST_WARNING_OBJECT (demux, "received empty TOC select event");
2292 gst_event_unref (event);
2296 /* events we don't need to handle */
2297 case GST_EVENT_NAVIGATION:
2298 gst_event_unref (event);
2302 case GST_EVENT_LATENCY:
2304 res = gst_pad_push_event (demux->common.sinkpad, event);
2311 static GstFlowReturn
2312 gst_matroska_demux_seek_to_previous_keyframe (GstMatroskaDemux * demux)
2314 GstFlowReturn ret = GST_FLOW_EOS;
2315 gboolean done = TRUE;
2318 g_return_val_if_fail (demux->seek_index, GST_FLOW_EOS);
2319 g_return_val_if_fail (demux->seek_entry < demux->seek_index->len,
2322 GST_DEBUG_OBJECT (demux, "locating previous keyframe");
2324 if (!demux->seek_entry) {
2325 GST_DEBUG_OBJECT (demux, "no earlier index entry");
2329 for (i = 0; i < demux->common.src->len; i++) {
2330 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
2332 GST_DEBUG_OBJECT (demux, "segment start %" GST_TIME_FORMAT
2333 ", stream %d at %" GST_TIME_FORMAT,
2334 GST_TIME_ARGS (demux->common.segment.start), stream->index,
2335 GST_TIME_ARGS (stream->from_time));
2336 if (GST_CLOCK_TIME_IS_VALID (stream->from_time)) {
2337 if (stream->from_time > demux->common.segment.start) {
2338 GST_DEBUG_OBJECT (demux, "stream %d not finished yet", stream->index);
2342 /* nothing pushed for this stream;
2343 * likely seek entry did not start at keyframe, so all was skipped.
2344 * So we need an earlier entry */
2350 GstMatroskaIndex *entry;
2352 entry = &g_array_index (demux->seek_index, GstMatroskaIndex,
2353 --demux->seek_entry);
2354 if (!gst_matroska_demux_move_to_entry (demux, entry, FALSE, TRUE))
2364 static GstFlowReturn
2365 gst_matroska_demux_parse_tracks (GstMatroskaDemux * demux, GstEbmlRead * ebml)
2367 GstFlowReturn ret = GST_FLOW_OK;
2370 DEBUG_ELEMENT_START (demux, ebml, "Tracks");
2372 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2373 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
2377 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
2378 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
2382 /* one track within the "all-tracks" header */
2383 case GST_MATROSKA_ID_TRACKENTRY:
2384 ret = gst_matroska_demux_add_stream (demux, ebml);
2388 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
2393 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
2395 demux->tracks_parsed = TRUE;
2401 * Read signed/unsigned "EBML" numbers.
2402 * Return: number of bytes processed.
2406 gst_matroska_ebmlnum_uint (guint8 * data, guint size, guint64 * num)
2408 gint len_mask = 0x80, read = 1, n = 1, num_ffs = 0;
2416 while (read <= 8 && !(total & len_mask)) {
2423 if ((total &= (len_mask - 1)) == len_mask - 1)
2428 if (data[n] == 0xff)
2430 total = (total << 8) | data[n];
2434 if (read == num_ffs && total != 0)
2443 gst_matroska_ebmlnum_sint (guint8 * data, guint size, gint64 * num)
2448 /* read as unsigned number first */
2449 if ((res = gst_matroska_ebmlnum_uint (data, size, &unum)) < 0)
2453 if (unum == G_MAXUINT64)
2456 *num = unum - ((1 << ((7 * res) - 1)) - 1);
2462 * Mostly used for subtitles. We add void filler data for each
2463 * lagging stream to make sure we don't deadlock.
2467 gst_matroska_demux_sync_streams (GstMatroskaDemux * demux)
2471 GST_OBJECT_LOCK (demux);
2473 GST_LOG_OBJECT (demux, "Sync to %" GST_TIME_FORMAT,
2474 GST_TIME_ARGS (demux->common.segment.position));
2476 g_assert (demux->common.num_streams == demux->common.src->len);
2477 for (stream_nr = 0; stream_nr < demux->common.src->len; stream_nr++) {
2478 GstMatroskaTrackContext *context;
2480 context = g_ptr_array_index (demux->common.src, stream_nr);
2482 GST_LOG_OBJECT (demux,
2483 "Checking for resync on stream %d (%" GST_TIME_FORMAT ")", stream_nr,
2484 GST_TIME_ARGS (context->pos));
2486 if (G_LIKELY (context->type != GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
2487 GST_LOG_OBJECT (demux, "Skipping sync on non-subtitle stream");
2491 /* does it lag? 0.5 seconds is a random threshold...
2492 * lag need only be considered if we have advanced into requested segment */
2493 if (GST_CLOCK_TIME_IS_VALID (context->pos) &&
2494 GST_CLOCK_TIME_IS_VALID (demux->common.segment.position) &&
2495 demux->common.segment.position > demux->common.segment.start &&
2496 context->pos + (GST_SECOND / 2) < demux->common.segment.position) {
2499 guint64 start = context->pos;
2500 guint64 stop = demux->common.segment.position - (GST_SECOND / 2);
2502 GST_DEBUG_OBJECT (demux,
2503 "Synchronizing stream %d with other by advancing time from %"
2504 GST_TIME_FORMAT " to %" GST_TIME_FORMAT, stream_nr,
2505 GST_TIME_ARGS (start), GST_TIME_ARGS (stop));
2507 context->pos = stop;
2509 event = gst_event_new_gap (start, stop - start);
2510 GST_OBJECT_UNLOCK (demux);
2511 gst_pad_push_event (context->pad, event);
2512 GST_OBJECT_LOCK (demux);
2516 GST_OBJECT_UNLOCK (demux);
2519 static GstFlowReturn
2520 gst_matroska_demux_push_stream_headers (GstMatroskaDemux * demux,
2521 GstMatroskaTrackContext * stream)
2523 GstFlowReturn ret = GST_FLOW_OK;
2526 num = gst_buffer_list_length (stream->stream_headers);
2527 for (i = 0; i < num; ++i) {
2530 buf = gst_buffer_list_get (stream->stream_headers, i);
2531 buf = gst_buffer_copy (buf);
2533 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
2535 if (stream->set_discont) {
2536 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
2537 stream->set_discont = FALSE;
2539 GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DISCONT);
2542 /* push out all headers in one go and use last flow return */
2543 ret = gst_pad_push (stream->pad, buf);
2546 /* don't need these any longer */
2547 gst_buffer_list_unref (stream->stream_headers);
2548 stream->stream_headers = NULL;
2551 ret = gst_flow_combiner_update_flow (demux->flowcombiner, ret);
2557 gst_matroska_demux_push_dvd_clut_change_event (GstMatroskaDemux * demux,
2558 GstMatroskaTrackContext * stream)
2562 g_assert (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB));
2564 if (!stream->codec_priv)
2567 /* ideally, VobSub private data should be parsed and stored more convenient
2568 * elsewhere, but for now, only interested in a small part */
2570 /* make sure we have terminating 0 */
2571 buf = g_strndup (stream->codec_priv, stream->codec_priv_size);
2573 /* just locate and parse palette part */
2574 start = strstr (buf, "palette:");
2579 guint8 r, g, b, y, u, v;
2582 while (g_ascii_isspace (*start))
2584 for (i = 0; i < 16; i++) {
2585 if (sscanf (start, "%06x", &col) != 1)
2588 while ((*start == ',') || g_ascii_isspace (*start))
2590 /* sigh, need to convert this from vobsub pseudo-RGB to YUV */
2591 r = (col >> 16) & 0xff;
2592 g = (col >> 8) & 0xff;
2594 y = CLAMP ((0.1494 * r + 0.6061 * g + 0.2445 * b) * 219 / 255 + 16, 0,
2596 u = CLAMP (0.6066 * r - 0.4322 * g - 0.1744 * b + 128, 0, 255);
2597 v = CLAMP (-0.08435 * r - 0.3422 * g + 0.4266 * b + 128, 0, 255);
2598 clut[i] = (y << 16) | (u << 8) | v;
2601 /* got them all without problems; build and send event */
2605 s = gst_structure_new ("application/x-gst-dvd", "event", G_TYPE_STRING,
2606 "dvd-spu-clut-change", "clut00", G_TYPE_INT, clut[0], "clut01",
2607 G_TYPE_INT, clut[1], "clut02", G_TYPE_INT, clut[2], "clut03",
2608 G_TYPE_INT, clut[3], "clut04", G_TYPE_INT, clut[4], "clut05",
2609 G_TYPE_INT, clut[5], "clut06", G_TYPE_INT, clut[6], "clut07",
2610 G_TYPE_INT, clut[7], "clut08", G_TYPE_INT, clut[8], "clut09",
2611 G_TYPE_INT, clut[9], "clut10", G_TYPE_INT, clut[10], "clut11",
2612 G_TYPE_INT, clut[11], "clut12", G_TYPE_INT, clut[12], "clut13",
2613 G_TYPE_INT, clut[13], "clut14", G_TYPE_INT, clut[14], "clut15",
2614 G_TYPE_INT, clut[15], NULL);
2616 gst_pad_push_event (stream->pad,
2617 gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM_STICKY, s));
2624 gst_matroska_demux_push_codec_data_all (GstMatroskaDemux * demux)
2628 GST_OBJECT_LOCK (demux);
2630 g_assert (demux->common.num_streams == demux->common.src->len);
2631 for (stream_nr = 0; stream_nr < demux->common.src->len; stream_nr++) {
2632 GstMatroskaTrackContext *stream;
2634 stream = g_ptr_array_index (demux->common.src, stream_nr);
2636 if (stream->send_stream_headers) {
2637 if (stream->stream_headers != NULL) {
2638 gst_matroska_demux_push_stream_headers (demux, stream);
2640 /* FIXME: perhaps we can just disable and skip this stream then */
2641 GST_ELEMENT_ERROR (demux, STREAM, DECODE, (NULL),
2642 ("Failed to extract stream headers from codec private data"));
2644 stream->send_stream_headers = FALSE;
2647 if (stream->send_dvd_event) {
2648 gst_matroska_demux_push_dvd_clut_change_event (demux, stream);
2649 /* FIXME: should we send this event again after (flushing) seek ? */
2650 stream->send_dvd_event = FALSE;
2654 GST_OBJECT_UNLOCK (demux);
2657 static GstFlowReturn
2658 gst_matroska_demux_add_mpeg_seq_header (GstElement * element,
2659 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2662 guint seq_header_len;
2663 guint32 header, tmp;
2665 if (stream->codec_state) {
2666 seq_header = stream->codec_state;
2667 seq_header_len = stream->codec_state_size;
2668 } else if (stream->codec_priv) {
2669 seq_header = stream->codec_priv;
2670 seq_header_len = stream->codec_priv_size;
2675 /* Sequence header only needed for keyframes */
2676 if (GST_BUFFER_FLAG_IS_SET (*buf, GST_BUFFER_FLAG_DELTA_UNIT))
2679 if (gst_buffer_get_size (*buf) < 4)
2682 gst_buffer_extract (*buf, 0, &tmp, sizeof (guint32));
2683 header = GUINT32_FROM_BE (tmp);
2685 /* Sequence start code, if not found prepend */
2686 if (header != 0x000001b3) {
2689 GST_DEBUG_OBJECT (element, "Prepending MPEG sequence header");
2691 newbuf = gst_buffer_new_wrapped (g_memdup (seq_header, seq_header_len),
2694 gst_buffer_copy_into (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
2695 GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_MEMORY, 0,
2696 gst_buffer_get_size (*buf));
2698 gst_buffer_unref (*buf);
2705 static GstFlowReturn
2706 gst_matroska_demux_add_wvpk_header (GstElement * element,
2707 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2709 GstMatroskaTrackAudioContext *audiocontext =
2710 (GstMatroskaTrackAudioContext *) stream;
2711 GstBuffer *newbuf = NULL;
2712 GstMapInfo map, outmap;
2713 guint8 *buf_data, *data;
2721 wvh.version = GST_READ_UINT16_LE (stream->codec_priv);
2724 wvh.total_samples = -1;
2725 wvh.block_index = audiocontext->wvpk_block_index;
2727 if (audiocontext->channels <= 2) {
2728 guint32 block_samples, tmp;
2729 gsize size = gst_buffer_get_size (*buf);
2731 gst_buffer_extract (*buf, 0, &tmp, sizeof (guint32));
2732 block_samples = GUINT32_FROM_LE (tmp);
2733 /* we need to reconstruct the header of the wavpack block */
2735 /* -20 because ck_size is the size of the wavpack block -8
2736 * and lace_size is the size of the wavpack block + 12
2737 * (the three guint32 of the header that already are in the buffer) */
2738 wvh.ck_size = size + sizeof (Wavpack4Header) - 20;
2740 /* block_samples, flags and crc are already in the buffer */
2741 newbuf = gst_buffer_new_allocate (NULL, sizeof (Wavpack4Header) - 12, NULL);
2743 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2749 GST_WRITE_UINT32_LE (data + 4, wvh.ck_size);
2750 GST_WRITE_UINT16_LE (data + 8, wvh.version);
2751 GST_WRITE_UINT8 (data + 10, wvh.track_no);
2752 GST_WRITE_UINT8 (data + 11, wvh.index_no);
2753 GST_WRITE_UINT32_LE (data + 12, wvh.total_samples);
2754 GST_WRITE_UINT32_LE (data + 16, wvh.block_index);
2756 /* Append data from buf: */
2757 gst_buffer_copy_into (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
2758 GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_MEMORY, 0, size);
2760 gst_buffer_unref (*buf);
2762 audiocontext->wvpk_block_index += block_samples;
2764 guint8 *outdata = NULL;
2766 gsize buf_size, size, out_size = 0;
2767 guint32 block_samples, flags, crc, blocksize;
2769 gst_buffer_map (*buf, &map, GST_MAP_READ);
2770 buf_data = map.data;
2771 buf_size = map.size;
2774 GST_ERROR_OBJECT (element, "Too small wavpack buffer");
2775 gst_buffer_unmap (*buf, &map);
2776 return GST_FLOW_ERROR;
2782 block_samples = GST_READ_UINT32_LE (data);
2787 flags = GST_READ_UINT32_LE (data);
2790 crc = GST_READ_UINT32_LE (data);
2793 blocksize = GST_READ_UINT32_LE (data);
2797 if (blocksize == 0 || size < blocksize)
2800 g_assert ((newbuf == NULL) == (outdata == NULL));
2802 if (newbuf == NULL) {
2803 out_size = sizeof (Wavpack4Header) + blocksize;
2804 newbuf = gst_buffer_new_allocate (NULL, out_size, NULL);
2806 gst_buffer_copy_into (newbuf, *buf,
2807 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS, 0, -1);
2810 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2811 outdata = outmap.data;
2813 gst_buffer_unmap (newbuf, &outmap);
2814 out_size += sizeof (Wavpack4Header) + blocksize;
2815 gst_buffer_set_size (newbuf, out_size);
2816 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2817 outdata = outmap.data;
2820 outdata[outpos] = 'w';
2821 outdata[outpos + 1] = 'v';
2822 outdata[outpos + 2] = 'p';
2823 outdata[outpos + 3] = 'k';
2826 GST_WRITE_UINT32_LE (outdata + outpos,
2827 blocksize + sizeof (Wavpack4Header) - 8);
2828 GST_WRITE_UINT16_LE (outdata + outpos + 4, wvh.version);
2829 GST_WRITE_UINT8 (outdata + outpos + 6, wvh.track_no);
2830 GST_WRITE_UINT8 (outdata + outpos + 7, wvh.index_no);
2831 GST_WRITE_UINT32_LE (outdata + outpos + 8, wvh.total_samples);
2832 GST_WRITE_UINT32_LE (outdata + outpos + 12, wvh.block_index);
2833 GST_WRITE_UINT32_LE (outdata + outpos + 16, block_samples);
2834 GST_WRITE_UINT32_LE (outdata + outpos + 20, flags);
2835 GST_WRITE_UINT32_LE (outdata + outpos + 24, crc);
2838 memmove (outdata + outpos, data, blocksize);
2839 outpos += blocksize;
2843 gst_buffer_unmap (*buf, &map);
2844 gst_buffer_unref (*buf);
2847 gst_buffer_unmap (newbuf, &outmap);
2850 audiocontext->wvpk_block_index += block_samples;
2856 /* @text must be null-terminated */
2858 gst_matroska_demux_subtitle_chunk_has_tag (GstElement * element,
2863 g_return_val_if_fail (text != NULL, FALSE);
2865 /* yes, this might all lead to false positives ... */
2866 tag = (gchar *) text;
2867 while ((tag = strchr (tag, '<'))) {
2869 if (*tag != '\0' && *(tag + 1) == '>') {
2870 /* some common convenience ones */
2871 /* maybe any character will do here ? */
2884 if (strstr (text, "<span"))
2890 static GstFlowReturn
2891 gst_matroska_demux_check_subtitle_buffer (GstElement * element,
2892 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2894 GstMatroskaTrackSubtitleContext *sub_stream;
2895 const gchar *encoding;
2900 gboolean needs_unmap = TRUE;
2902 sub_stream = (GstMatroskaTrackSubtitleContext *) stream;
2904 if (!gst_buffer_get_size (*buf) || !gst_buffer_map (*buf, &map, GST_MAP_READ))
2907 /* Need \0-terminator at the end */
2908 if (map.data[map.size - 1] != '\0') {
2909 newbuf = gst_buffer_new_and_alloc (map.size + 1);
2911 /* Copy old buffer and add a 0 at the end */
2912 gst_buffer_fill (newbuf, 0, map.data, map.size);
2913 gst_buffer_memset (newbuf, map.size, 0, 1);
2914 gst_buffer_unmap (*buf, &map);
2916 gst_buffer_copy_into (newbuf, *buf,
2917 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS |
2918 GST_BUFFER_COPY_META, 0, -1);
2919 gst_buffer_unref (*buf);
2921 gst_buffer_map (*buf, &map, GST_MAP_READ);
2924 if (!sub_stream->invalid_utf8) {
2925 if (g_utf8_validate ((gchar *) map.data, map.size - 1, NULL)) {
2928 GST_WARNING_OBJECT (element, "subtitle stream %" G_GUINT64_FORMAT
2929 " is not valid UTF-8, this is broken according to the matroska"
2930 " specification", stream->num);
2931 sub_stream->invalid_utf8 = TRUE;
2934 /* file with broken non-UTF8 subtitle, do the best we can do to fix it */
2935 encoding = g_getenv ("GST_SUBTITLE_ENCODING");
2936 if (encoding == NULL || *encoding == '\0') {
2937 /* if local encoding is UTF-8 and no encoding specified
2938 * via the environment variable, assume ISO-8859-15 */
2939 if (g_get_charset (&encoding)) {
2940 encoding = "ISO-8859-15";
2945 g_convert_with_fallback ((gchar *) map.data, map.size, "UTF-8", encoding,
2946 (char *) "*", NULL, NULL, &err);
2949 GST_LOG_OBJECT (element, "could not convert string from '%s' to UTF-8: %s",
2950 encoding, err->message);
2954 /* invalid input encoding, fall back to ISO-8859-15 (always succeeds) */
2955 encoding = "ISO-8859-15";
2957 g_convert_with_fallback ((gchar *) map.data, map.size, "UTF-8",
2958 encoding, (char *) "*", NULL, NULL, NULL);
2961 GST_LOG_OBJECT (element, "converted subtitle text from %s to UTF-8 %s",
2962 encoding, (err) ? "(using ISO-8859-15 as fallback)" : "");
2965 utf8 = g_strdup ("invalid subtitle");
2967 newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
2968 gst_buffer_unmap (*buf, &map);
2969 gst_buffer_copy_into (newbuf, *buf,
2970 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_META,
2972 gst_buffer_unref (*buf);
2975 gst_buffer_map (*buf, &map, GST_MAP_READ);
2979 if (sub_stream->check_markup) {
2980 /* caps claim markup text, so we need to escape text,
2981 * except if text is already markup and then needs no further escaping */
2982 sub_stream->seen_markup_tag = sub_stream->seen_markup_tag ||
2983 gst_matroska_demux_subtitle_chunk_has_tag (element, (gchar *) map.data);
2985 if (!sub_stream->seen_markup_tag) {
2986 utf8 = g_markup_escape_text ((gchar *) map.data, map.size);
2988 newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
2989 gst_buffer_unmap (*buf, &map);
2990 gst_buffer_copy_into (newbuf, *buf,
2991 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS |
2992 GST_BUFFER_COPY_META, 0, -1);
2993 gst_buffer_unref (*buf);
2996 needs_unmap = FALSE;
3001 gst_buffer_unmap (*buf, &map);
3006 static GstFlowReturn
3007 gst_matroska_demux_check_aac (GstElement * element,
3008 GstMatroskaTrackContext * stream, GstBuffer ** buf)
3013 gst_buffer_extract (*buf, 0, data, 2);
3014 size = gst_buffer_get_size (*buf);
3016 if (size > 2 && data[0] == 0xff && (data[1] >> 4 == 0x0f)) {
3019 /* tss, ADTS data, remove codec_data
3020 * still assume it is at least parsed */
3021 stream->caps = gst_caps_make_writable (stream->caps);
3022 s = gst_caps_get_structure (stream->caps, 0);
3024 gst_structure_remove_field (s, "codec_data");
3025 gst_pad_set_caps (stream->pad, stream->caps);
3026 GST_DEBUG_OBJECT (element, "ADTS AAC audio data; removing codec-data, "
3027 "new caps: %" GST_PTR_FORMAT, stream->caps);
3030 /* disable subsequent checking */
3031 stream->postprocess_frame = NULL;
3037 gst_matroska_demux_align_buffer (GstMatroskaDemux * demux,
3038 GstBuffer * buffer, gsize alignment)
3042 gst_buffer_map (buffer, &map, GST_MAP_READ);
3044 if (map.size < sizeof (guintptr)) {
3045 gst_buffer_unmap (buffer, &map);
3049 if (((guintptr) map.data) & (alignment - 1)) {
3050 GstBuffer *new_buffer;
3051 GstAllocationParams params = { 0, alignment - 1, 0, 0, };
3053 new_buffer = gst_buffer_new_allocate (NULL,
3054 gst_buffer_get_size (buffer), ¶ms);
3056 /* Copy data "by hand", so ensure alignment is kept: */
3057 gst_buffer_fill (new_buffer, 0, map.data, map.size);
3059 gst_buffer_copy_into (new_buffer, buffer, GST_BUFFER_COPY_METADATA, 0, -1);
3060 GST_DEBUG_OBJECT (demux,
3061 "We want output aligned on %" G_GSIZE_FORMAT ", reallocated",
3064 gst_buffer_unmap (buffer, &map);
3065 gst_buffer_unref (buffer);
3070 gst_buffer_unmap (buffer, &map);
3074 static GstFlowReturn
3075 gst_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux,
3076 GstEbmlRead * ebml, guint64 cluster_time, guint64 cluster_offset,
3077 gboolean is_simpleblock)
3079 GstMatroskaTrackContext *stream = NULL;
3080 GstFlowReturn ret = GST_FLOW_OK;
3081 gboolean readblock = FALSE;
3083 guint64 block_duration = -1;
3084 GstBuffer *buf = NULL;
3086 gint stream_num = -1, n, laces = 0;
3088 gint *lace_size = NULL;
3091 gint64 referenceblock = 0;
3093 GstClockTime buffer_timestamp;
3095 offset = gst_ebml_read_get_offset (ebml);
3097 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3098 if (!is_simpleblock) {
3099 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK) {
3103 id = GST_MATROSKA_ID_SIMPLEBLOCK;
3107 /* one block inside the group. Note, block parsing is one
3108 * of the harder things, so this code is a bit complicated.
3109 * See http://www.matroska.org/ for documentation. */
3110 case GST_MATROSKA_ID_SIMPLEBLOCK:
3111 case GST_MATROSKA_ID_BLOCK:
3117 gst_buffer_unmap (buf, &map);
3118 gst_buffer_unref (buf);
3121 if ((ret = gst_ebml_read_buffer (ebml, &id, &buf)) != GST_FLOW_OK)
3124 gst_buffer_map (buf, &map, GST_MAP_READ);
3128 /* first byte(s): blocknum */
3129 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
3134 /* fetch stream from num */
3135 stream_num = gst_matroska_read_common_stream_from_num (&demux->common,
3137 if (G_UNLIKELY (size < 3)) {
3138 GST_WARNING_OBJECT (demux, "Invalid size %u", size);
3139 /* non-fatal, try next block(group) */
3142 } else if (G_UNLIKELY (stream_num < 0 ||
3143 stream_num >= demux->common.num_streams)) {
3144 /* let's not give up on a stray invalid track number */
3145 GST_WARNING_OBJECT (demux,
3146 "Invalid stream %d for track number %" G_GUINT64_FORMAT
3147 "; ignoring block", stream_num, num);
3151 stream = g_ptr_array_index (demux->common.src, stream_num);
3153 /* time (relative to cluster time) */
3154 time = ((gint16) GST_READ_UINT16_BE (data));
3157 flags = GST_READ_UINT8 (data);
3161 GST_LOG_OBJECT (demux, "time %" G_GUINT64_FORMAT ", flags %d", time,
3164 switch ((flags & 0x06) >> 1) {
3165 case 0x0: /* no lacing */
3167 lace_size = g_new (gint, 1);
3168 lace_size[0] = size;
3171 case 0x1: /* xiph lacing */
3172 case 0x2: /* fixed-size lacing */
3173 case 0x3: /* EBML lacing */
3175 goto invalid_lacing;
3176 laces = GST_READ_UINT8 (data) + 1;
3179 lace_size = g_new0 (gint, laces);
3181 switch ((flags & 0x06) >> 1) {
3182 case 0x1: /* xiph lacing */ {
3183 guint temp, total = 0;
3185 for (n = 0; ret == GST_FLOW_OK && n < laces - 1; n++) {
3188 goto invalid_lacing;
3189 temp = GST_READ_UINT8 (data);
3190 lace_size[n] += temp;
3196 total += lace_size[n];
3198 lace_size[n] = size - total;
3202 case 0x2: /* fixed-size lacing */
3203 for (n = 0; n < laces; n++)
3204 lace_size[n] = size / laces;
3207 case 0x3: /* EBML lacing */ {
3210 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
3214 total = lace_size[0] = num;
3215 for (n = 1; ret == GST_FLOW_OK && n < laces - 1; n++) {
3219 if ((r = gst_matroska_ebmlnum_sint (data, size, &snum)) < 0)
3223 lace_size[n] = lace_size[n - 1] + snum;
3224 total += lace_size[n];
3227 lace_size[n] = size - total;
3234 if (ret != GST_FLOW_OK)
3241 case GST_MATROSKA_ID_BLOCKDURATION:{
3242 ret = gst_ebml_read_uint (ebml, &id, &block_duration);
3243 GST_DEBUG_OBJECT (demux, "BlockDuration: %" G_GUINT64_FORMAT,
3248 case GST_MATROSKA_ID_REFERENCEBLOCK:{
3249 ret = gst_ebml_read_sint (ebml, &id, &referenceblock);
3250 GST_DEBUG_OBJECT (demux, "ReferenceBlock: %" G_GINT64_FORMAT,
3255 case GST_MATROSKA_ID_CODECSTATE:{
3257 guint64 data_len = 0;
3260 gst_ebml_read_binary (ebml, &id, &data,
3261 &data_len)) != GST_FLOW_OK)
3264 if (G_UNLIKELY (stream == NULL)) {
3265 GST_WARNING_OBJECT (demux,
3266 "Unexpected CodecState subelement - ignoring");
3270 g_free (stream->codec_state);
3271 stream->codec_state = data;
3272 stream->codec_state_size = data_len;
3274 /* Decode if necessary */
3275 if (stream->encodings && stream->encodings->len > 0
3276 && stream->codec_state && stream->codec_state_size > 0) {
3277 if (!gst_matroska_decode_data (stream->encodings,
3278 &stream->codec_state, &stream->codec_state_size,
3279 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
3280 GST_WARNING_OBJECT (demux, "Decoding codec state failed");
3284 GST_DEBUG_OBJECT (demux, "CodecState of %" G_GSIZE_FORMAT " bytes",
3285 stream->codec_state_size);
3290 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3294 case GST_MATROSKA_ID_BLOCKVIRTUAL:
3295 case GST_MATROSKA_ID_BLOCKADDITIONS:
3296 case GST_MATROSKA_ID_REFERENCEPRIORITY:
3297 case GST_MATROSKA_ID_REFERENCEVIRTUAL:
3298 case GST_MATROSKA_ID_SLICES:
3299 GST_DEBUG_OBJECT (demux,
3300 "Skipping BlockGroup subelement 0x%x - ignoring", id);
3301 ret = gst_ebml_read_skip (ebml);
3309 /* reading a number or so could have failed */
3310 if (ret != GST_FLOW_OK)
3313 if (ret == GST_FLOW_OK && readblock) {
3314 gboolean invisible_frame = FALSE;
3315 gboolean delta_unit = FALSE;
3316 guint64 duration = 0;
3317 gint64 lace_time = 0;
3319 stream = g_ptr_array_index (demux->common.src, stream_num);
3321 if (cluster_time != GST_CLOCK_TIME_NONE) {
3322 /* FIXME: What to do with negative timestamps? Give timestamp 0 or -1?
3323 * Drop unless the lace contains timestamp 0? */
3324 if (time < 0 && (-time) > cluster_time) {
3327 if (stream->timecodescale == 1.0)
3328 lace_time = (cluster_time + time) * demux->common.time_scale;
3331 gst_util_guint64_to_gdouble ((cluster_time + time) *
3332 demux->common.time_scale) * stream->timecodescale;
3335 lace_time = GST_CLOCK_TIME_NONE;
3338 /* need to refresh segment info ASAP */
3339 if (GST_CLOCK_TIME_IS_VALID (lace_time) && demux->need_segment) {
3340 GstSegment *segment = &demux->common.segment;
3342 GstEvent *segment_event;
3344 if (!GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
3345 demux->stream_start_time = lace_time;
3346 GST_DEBUG_OBJECT (demux,
3347 "Setting stream start time to %" GST_TIME_FORMAT,
3348 GST_TIME_ARGS (lace_time));
3350 clace_time = MAX (lace_time, demux->stream_start_time);
3351 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.position) &&
3352 demux->common.segment.position != 0) {
3353 GST_DEBUG_OBJECT (demux,
3354 "using stored seek position %" GST_TIME_FORMAT,
3355 GST_TIME_ARGS (demux->common.segment.position));
3356 clace_time = demux->common.segment.position + demux->stream_start_time;
3357 segment->position = GST_CLOCK_TIME_NONE;
3359 segment->start = clace_time;
3360 segment->stop = GST_CLOCK_TIME_NONE;
3361 segment->time = segment->start - demux->stream_start_time;
3362 segment->position = segment->start - demux->stream_start_time;
3363 GST_DEBUG_OBJECT (demux,
3364 "generated segment starting at %" GST_TIME_FORMAT ": %"
3365 GST_SEGMENT_FORMAT, GST_TIME_ARGS (lace_time), segment);
3366 /* now convey our segment notion downstream */
3367 segment_event = gst_event_new_segment (segment);
3368 if (demux->segment_seqnum)
3369 gst_event_set_seqnum (segment_event, demux->segment_seqnum);
3370 gst_matroska_demux_send_event (demux, segment_event);
3371 demux->need_segment = FALSE;
3372 demux->segment_seqnum = 0;
3375 /* send pending codec data headers for all streams,
3376 * before we perform sync across all streams */
3377 gst_matroska_demux_push_codec_data_all (demux);
3379 if (block_duration != -1) {
3380 if (stream->timecodescale == 1.0)
3381 duration = gst_util_uint64_scale (block_duration,
3382 demux->common.time_scale, 1);
3385 gst_util_gdouble_to_guint64 (gst_util_guint64_to_gdouble
3386 (gst_util_uint64_scale (block_duration, demux->common.time_scale,
3387 1)) * stream->timecodescale);
3388 } else if (stream->default_duration) {
3389 duration = stream->default_duration * laces;
3391 /* else duration is diff between timecode of this and next block */
3393 /* For SimpleBlock, look at the keyframe bit in flags. Otherwise,
3394 a ReferenceBlock implies that this is not a keyframe. In either
3395 case, it only makes sense for video streams. */
3396 if (stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
3397 if ((is_simpleblock && !(flags & 0x80)) || referenceblock) {
3399 invisible_frame = ((flags & 0x08)) &&
3400 (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8) ||
3401 !strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP9));
3405 for (n = 0; n < laces; n++) {
3408 if (G_UNLIKELY (lace_size[n] > size)) {
3409 GST_WARNING_OBJECT (demux, "Invalid lace size");
3413 /* QoS for video track with an index. the assumption is that
3414 index entries point to keyframes, but if that is not true we
3415 will instad skip until the next keyframe. */
3416 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
3417 stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
3418 stream->index_table && demux->common.segment.rate > 0.0) {
3419 GstMatroskaTrackVideoContext *videocontext =
3420 (GstMatroskaTrackVideoContext *) stream;
3421 GstClockTime earliest_time;
3422 GstClockTime earliest_stream_time;
3424 GST_OBJECT_LOCK (demux);
3425 earliest_time = videocontext->earliest_time;
3426 GST_OBJECT_UNLOCK (demux);
3427 earliest_stream_time = gst_segment_to_position (&demux->common.segment,
3428 GST_FORMAT_TIME, earliest_time);
3430 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
3431 GST_CLOCK_TIME_IS_VALID (earliest_stream_time) &&
3432 lace_time <= earliest_stream_time) {
3433 /* find index entry (keyframe) <= earliest_stream_time */
3434 GstMatroskaIndex *entry =
3435 gst_util_array_binary_search (stream->index_table->data,
3436 stream->index_table->len, sizeof (GstMatroskaIndex),
3437 (GCompareDataFunc) gst_matroska_index_seek_find,
3438 GST_SEARCH_MODE_BEFORE, &earliest_stream_time, NULL);
3440 /* if that entry (keyframe) is after the current the current
3441 buffer, we can skip pushing (and thus decoding) all
3442 buffers until that keyframe. */
3443 if (entry && GST_CLOCK_TIME_IS_VALID (entry->time) &&
3444 entry->time > lace_time) {
3445 GST_LOG_OBJECT (demux, "Skipping lace before late keyframe");
3446 stream->set_discont = TRUE;
3452 sub = gst_buffer_copy_region (buf, GST_BUFFER_COPY_ALL,
3453 gst_buffer_get_size (buf) - size, lace_size[n]);
3454 GST_DEBUG_OBJECT (demux, "created subbuffer %p", sub);
3457 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
3459 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
3461 if (invisible_frame)
3462 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DECODE_ONLY);
3464 if (stream->encodings != NULL && stream->encodings->len > 0)
3465 sub = gst_matroska_decode_buffer (stream, sub);
3468 GST_WARNING_OBJECT (demux, "Decoding buffer failed");
3472 buffer_timestamp = gst_matroska_track_get_buffer_timestamp (stream, sub);
3474 if (!stream->dts_only)
3475 GST_BUFFER_PTS (sub) = lace_time;
3477 GST_BUFFER_DTS (sub) = lace_time;
3479 if (GST_CLOCK_TIME_IS_VALID (lace_time)) {
3480 GstClockTime last_stop_end;
3482 /* Check if this stream is after segment stop */
3483 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop) &&
3484 lace_time >= demux->common.segment.stop) {
3485 GST_DEBUG_OBJECT (demux,
3486 "Stream %d after segment stop %" GST_TIME_FORMAT, stream->index,
3487 GST_TIME_ARGS (demux->common.segment.stop));
3488 gst_buffer_unref (sub);
3491 if (offset >= stream->to_offset
3492 || (GST_CLOCK_TIME_IS_VALID (demux->to_time)
3493 && lace_time > demux->to_time)) {
3494 GST_DEBUG_OBJECT (demux, "Stream %d after playback section",
3496 gst_buffer_unref (sub);
3500 /* handle gaps, e.g. non-zero start-time, or an cue index entry
3501 * that landed us with timestamps not quite intended */
3502 GST_OBJECT_LOCK (demux);
3503 if (demux->max_gap_time &&
3504 GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) &&
3505 demux->common.segment.rate > 0.0) {
3506 GstClockTimeDiff diff;
3508 /* only send segments with increasing start times,
3509 * otherwise if these go back and forth downstream (sinks) increase
3510 * accumulated time and running_time */
3511 diff = GST_CLOCK_DIFF (demux->last_stop_end, lace_time);
3512 if (diff > 0 && diff > demux->max_gap_time
3513 && lace_time > demux->common.segment.start
3514 && (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop)
3515 || lace_time < demux->common.segment.stop)) {
3517 GST_DEBUG_OBJECT (demux,
3518 "Gap of %" G_GINT64_FORMAT " ns detected in"
3519 "stream %d (%" GST_TIME_FORMAT " -> %" GST_TIME_FORMAT "). "
3520 "Sending updated SEGMENT events", diff,
3521 stream->index, GST_TIME_ARGS (stream->pos),
3522 GST_TIME_ARGS (lace_time));
3524 event = gst_event_new_gap (demux->last_stop_end, diff);
3525 GST_OBJECT_UNLOCK (demux);
3526 gst_pad_push_event (stream->pad, event);
3527 GST_OBJECT_LOCK (demux);
3531 if (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.position)
3532 || demux->common.segment.position < lace_time) {
3533 demux->common.segment.position = lace_time;
3535 GST_OBJECT_UNLOCK (demux);
3537 last_stop_end = lace_time;
3539 GST_BUFFER_DURATION (sub) = duration / laces;
3540 last_stop_end += GST_BUFFER_DURATION (sub);
3543 if (!GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) ||
3544 demux->last_stop_end < last_stop_end)
3545 demux->last_stop_end = last_stop_end;
3547 GST_OBJECT_LOCK (demux);
3548 if (demux->common.segment.duration == -1 ||
3549 demux->stream_start_time + demux->common.segment.duration <
3551 demux->common.segment.duration =
3552 last_stop_end - demux->stream_start_time;
3553 GST_OBJECT_UNLOCK (demux);
3554 if (!demux->invalid_duration) {
3555 gst_element_post_message (GST_ELEMENT_CAST (demux),
3556 gst_message_new_duration_changed (GST_OBJECT_CAST (demux)));
3557 demux->invalid_duration = TRUE;
3560 GST_OBJECT_UNLOCK (demux);
3564 stream->pos = lace_time;
3566 gst_matroska_demux_sync_streams (demux);
3568 if (stream->set_discont) {
3569 GST_DEBUG_OBJECT (demux, "marking DISCONT");
3570 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DISCONT);
3571 stream->set_discont = FALSE;
3573 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DISCONT);
3576 /* reverse playback book-keeping */
3577 if (!GST_CLOCK_TIME_IS_VALID (stream->from_time))
3578 stream->from_time = lace_time;
3579 if (stream->from_offset == -1)
3580 stream->from_offset = offset;
3582 GST_DEBUG_OBJECT (demux,
3583 "Pushing lace %d, data of size %" G_GSIZE_FORMAT
3584 " for stream %d, time=%" GST_TIME_FORMAT " and duration=%"
3585 GST_TIME_FORMAT, n, gst_buffer_get_size (sub), stream_num,
3586 GST_TIME_ARGS (buffer_timestamp),
3587 GST_TIME_ARGS (GST_BUFFER_DURATION (sub)));
3590 if (demux->common.element_index) {
3591 if (stream->index_writer_id == -1)
3592 gst_index_get_writer_id (demux->common.element_index,
3593 GST_OBJECT (stream->pad), &stream->index_writer_id);
3595 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
3596 G_GUINT64_FORMAT " for writer id %d",
3597 GST_TIME_ARGS (buffer_timestamp), cluster_offset,
3598 stream->index_writer_id);
3599 gst_index_add_association (demux->common.element_index,
3600 stream->index_writer_id, GST_BUFFER_FLAG_IS_SET (sub,
3601 GST_BUFFER_FLAG_DELTA_UNIT) ? 0 : GST_ASSOCIATION_FLAG_KEY_UNIT,
3602 GST_FORMAT_TIME, buffer_timestamp, GST_FORMAT_BYTES, cluster_offset,
3607 /* Postprocess the buffers depending on the codec used */
3608 if (stream->postprocess_frame) {
3609 GST_LOG_OBJECT (demux, "running post process");
3610 ret = stream->postprocess_frame (GST_ELEMENT (demux), stream, &sub);
3613 /* At this point, we have a sub-buffer pointing at data within a larger
3614 buffer. This data might not be aligned with anything. If the data is
3615 raw samples though, we want it aligned to the raw type (eg, 4 bytes
3616 for 32 bit samples, etc), or bad things will happen downstream as
3617 elements typically assume minimal alignment.
3618 Therefore, create an aligned copy if necessary. */
3619 g_assert (stream->alignment <= G_MEM_ALIGN);
3620 sub = gst_matroska_demux_align_buffer (demux, sub, stream->alignment);
3622 if (GST_BUFFER_PTS_IS_VALID (sub)) {
3623 stream->pos = GST_BUFFER_PTS (sub);
3624 if (GST_BUFFER_DURATION_IS_VALID (sub))
3625 stream->pos += GST_BUFFER_DURATION (sub);
3626 } else if (GST_BUFFER_DTS_IS_VALID (sub)) {
3627 stream->pos = GST_BUFFER_DTS (sub);
3628 if (GST_BUFFER_DURATION_IS_VALID (sub))
3629 stream->pos += GST_BUFFER_DURATION (sub);
3632 ret = gst_pad_push (stream->pad, sub);
3634 if (demux->common.segment.rate < 0) {
3635 if (lace_time > demux->common.segment.stop && ret == GST_FLOW_EOS) {
3636 /* In reverse playback we can get a GST_FLOW_EOS when
3637 * we are at the end of the segment, so we just need to jump
3638 * back to the previous section. */
3639 GST_DEBUG_OBJECT (demux, "downstream has reached end of segment");
3644 ret = gst_flow_combiner_update_flow (demux->flowcombiner, ret);
3647 size -= lace_size[n];
3648 if (lace_time != GST_CLOCK_TIME_NONE && duration)
3649 lace_time += duration / laces;
3651 lace_time = GST_CLOCK_TIME_NONE;
3657 gst_buffer_unmap (buf, &map);
3658 gst_buffer_unref (buf);
3670 ret = gst_flow_combiner_update_flow (demux->flowcombiner, ret);
3675 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Invalid lacing size"));
3676 /* non-fatal, try next block(group) */
3682 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Data error"));
3683 /* non-fatal, try next block(group) */
3689 /* return FALSE if block(group) should be skipped (due to a seek) */
3690 static inline gboolean
3691 gst_matroska_demux_seek_block (GstMatroskaDemux * demux)
3693 if (G_UNLIKELY (demux->seek_block)) {
3694 if (!(--demux->seek_block)) {
3697 GST_LOG_OBJECT (demux, "should skip block due to seek");
3705 static GstFlowReturn
3706 gst_matroska_demux_parse_contents_seekentry (GstMatroskaDemux * demux,
3710 guint64 seek_pos = (guint64) - 1;
3711 guint32 seek_id = 0;
3714 DEBUG_ELEMENT_START (demux, ebml, "Seek");
3716 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3717 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
3721 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3722 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3726 case GST_MATROSKA_ID_SEEKID:
3730 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
3733 GST_DEBUG_OBJECT (demux, "SeekID: %" G_GUINT64_FORMAT, t);
3738 case GST_MATROSKA_ID_SEEKPOSITION:
3742 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
3745 if (t > G_MAXINT64) {
3746 GST_WARNING_OBJECT (demux,
3747 "Too large SeekPosition %" G_GUINT64_FORMAT, t);
3751 GST_DEBUG_OBJECT (demux, "SeekPosition: %" G_GUINT64_FORMAT, t);
3757 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3763 if (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)
3766 if (!seek_id || seek_pos == (guint64) - 1) {
3767 GST_WARNING_OBJECT (demux, "Incomplete seekhead entry (0x%x/%"
3768 G_GUINT64_FORMAT ")", seek_id, seek_pos);
3773 case GST_MATROSKA_ID_SEEKHEAD:
3776 case GST_MATROSKA_ID_CUES:
3777 case GST_MATROSKA_ID_TAGS:
3778 case GST_MATROSKA_ID_TRACKS:
3779 case GST_MATROSKA_ID_SEGMENTINFO:
3780 case GST_MATROSKA_ID_ATTACHMENTS:
3781 case GST_MATROSKA_ID_CHAPTERS:
3783 guint64 before_pos, length;
3787 length = gst_matroska_read_common_get_length (&demux->common);
3788 before_pos = demux->common.offset;
3790 if (length == (guint64) - 1) {
3791 GST_DEBUG_OBJECT (demux, "no upstream length, skipping SeakHead entry");
3795 /* check for validity */
3796 if (seek_pos + demux->common.ebml_segment_start + 12 >= length) {
3797 GST_WARNING_OBJECT (demux,
3798 "SeekHead reference lies outside file!" " (%"
3799 G_GUINT64_FORMAT "+%" G_GUINT64_FORMAT "+12 >= %"
3800 G_GUINT64_FORMAT ")", seek_pos, demux->common.ebml_segment_start,
3805 /* only pick up index location when streaming */
3806 if (demux->streaming) {
3807 if (seek_id == GST_MATROSKA_ID_CUES) {
3808 demux->index_offset = seek_pos + demux->common.ebml_segment_start;
3809 GST_DEBUG_OBJECT (demux, "Cues located at offset %" G_GUINT64_FORMAT,
3810 demux->index_offset);
3816 demux->common.offset = seek_pos + demux->common.ebml_segment_start;
3819 if ((ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
3820 GST_ELEMENT_CAST (demux), &id, &length, &needed)) !=
3824 if (id != seek_id) {
3825 GST_WARNING_OBJECT (demux,
3826 "We looked for ID=0x%x but got ID=0x%x (pos=%" G_GUINT64_FORMAT ")",
3827 seek_id, id, seek_pos + demux->common.ebml_segment_start);
3830 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
3835 demux->common.offset = before_pos;
3839 case GST_MATROSKA_ID_CLUSTER:
3841 guint64 pos = seek_pos + demux->common.ebml_segment_start;
3843 GST_LOG_OBJECT (demux, "Cluster position");
3844 if (G_UNLIKELY (!demux->clusters))
3845 demux->clusters = g_array_sized_new (TRUE, TRUE, sizeof (guint64), 100);
3846 g_array_append_val (demux->clusters, pos);
3851 GST_DEBUG_OBJECT (demux, "Ignoring Seek entry for ID=0x%x", seek_id);
3854 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
3859 static GstFlowReturn
3860 gst_matroska_demux_parse_contents (GstMatroskaDemux * demux, GstEbmlRead * ebml)
3862 GstFlowReturn ret = GST_FLOW_OK;
3865 DEBUG_ELEMENT_START (demux, ebml, "SeekHead");
3867 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3868 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
3872 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3873 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3877 case GST_MATROSKA_ID_SEEKENTRY:
3879 ret = gst_matroska_demux_parse_contents_seekentry (demux, ebml);
3880 /* Ignore EOS and errors here */
3881 if (ret != GST_FLOW_OK) {
3882 GST_DEBUG_OBJECT (demux, "Ignoring %s", gst_flow_get_name (ret));
3889 ret = gst_matroska_read_common_parse_skip (&demux->common,
3890 ebml, "SeekHead", id);
3895 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
3897 /* Sort clusters by position for easier searching */
3898 if (demux->clusters)
3899 g_array_sort (demux->clusters, (GCompareFunc) gst_matroska_cluster_compare);
3904 #define GST_FLOW_OVERFLOW GST_FLOW_CUSTOM_ERROR
3906 #define MAX_BLOCK_SIZE (15 * 1024 * 1024)
3908 static inline GstFlowReturn
3909 gst_matroska_demux_check_read_size (GstMatroskaDemux * demux, guint64 bytes)
3911 if (G_UNLIKELY (bytes > MAX_BLOCK_SIZE)) {
3912 /* only a few blocks are expected/allowed to be large,
3913 * and will be recursed into, whereas others will be read and must fit */
3914 if (demux->streaming) {
3915 /* fatal in streaming case, as we can't step over easily */
3916 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
3917 ("reading large block of size %" G_GUINT64_FORMAT " not supported; "
3918 "file might be corrupt.", bytes));
3919 return GST_FLOW_ERROR;
3921 /* indicate higher level to quietly give up */
3922 GST_DEBUG_OBJECT (demux,
3923 "too large block of size %" G_GUINT64_FORMAT, bytes);
3924 return GST_FLOW_ERROR;
3931 /* returns TRUE if we truely are in error state, and should give up */
3932 static inline GstFlowReturn
3933 gst_matroska_demux_check_parse_error (GstMatroskaDemux * demux)
3935 if (!demux->streaming && demux->next_cluster_offset > 0) {
3936 /* just repositioning to where next cluster should be and try from there */
3937 GST_WARNING_OBJECT (demux, "parse error, trying next cluster expected at %"
3938 G_GUINT64_FORMAT, demux->next_cluster_offset);
3939 demux->common.offset = demux->next_cluster_offset;
3940 demux->next_cluster_offset = 0;
3946 /* sigh, one last attempt above and beyond call of duty ...;
3947 * search for cluster mark following current pos */
3948 pos = demux->common.offset;
3949 GST_WARNING_OBJECT (demux, "parse error, looking for next cluster");
3950 if ((ret = gst_matroska_demux_search_cluster (demux, &pos)) != GST_FLOW_OK) {
3951 /* did not work, give up */
3954 GST_DEBUG_OBJECT (demux, "... found at %" G_GUINT64_FORMAT, pos);
3955 /* try that position */
3956 demux->common.offset = pos;
3962 static inline GstFlowReturn
3963 gst_matroska_demux_flush (GstMatroskaDemux * demux, guint flush)
3965 GST_LOG_OBJECT (demux, "skipping %d bytes", flush);
3966 demux->common.offset += flush;
3967 if (demux->streaming) {
3970 /* hard to skip large blocks when streaming */
3971 ret = gst_matroska_demux_check_read_size (demux, flush);
3972 if (ret != GST_FLOW_OK)
3974 if (flush <= gst_adapter_available (demux->common.adapter))
3975 gst_adapter_flush (demux->common.adapter, flush);
3977 return GST_FLOW_EOS;
3982 /* initializes @ebml with @bytes from input stream at current offset.
3983 * Returns EOS if insufficient available,
3984 * ERROR if too much was attempted to read. */
3985 static inline GstFlowReturn
3986 gst_matroska_demux_take (GstMatroskaDemux * demux, guint64 bytes,
3989 GstBuffer *buffer = NULL;
3990 GstFlowReturn ret = GST_FLOW_OK;
3992 GST_LOG_OBJECT (demux, "taking %" G_GUINT64_FORMAT " bytes for parsing",
3994 ret = gst_matroska_demux_check_read_size (demux, bytes);
3995 if (G_UNLIKELY (ret != GST_FLOW_OK)) {
3996 if (!demux->streaming) {
3997 /* in pull mode, we can skip */
3998 if ((ret = gst_matroska_demux_flush (demux, bytes)) == GST_FLOW_OK)
3999 ret = GST_FLOW_OVERFLOW;
4001 /* otherwise fatal */
4002 ret = GST_FLOW_ERROR;
4006 if (demux->streaming) {
4007 if (gst_adapter_available (demux->common.adapter) >= bytes)
4008 buffer = gst_adapter_take_buffer (demux->common.adapter, bytes);
4012 ret = gst_matroska_read_common_peek_bytes (&demux->common,
4013 demux->common.offset, bytes, &buffer, NULL);
4014 if (G_LIKELY (buffer)) {
4015 gst_ebml_read_init (ebml, GST_ELEMENT_CAST (demux), buffer,
4016 demux->common.offset);
4017 demux->common.offset += bytes;
4024 gst_matroska_demux_check_seekability (GstMatroskaDemux * demux)
4027 gboolean seekable = FALSE;
4028 gint64 start = -1, stop = -1;
4030 query = gst_query_new_seeking (GST_FORMAT_BYTES);
4031 if (!gst_pad_peer_query (demux->common.sinkpad, query)) {
4032 GST_DEBUG_OBJECT (demux, "seeking query failed");
4036 gst_query_parse_seeking (query, NULL, &seekable, &start, &stop);
4038 /* try harder to query upstream size if we didn't get it the first time */
4039 if (seekable && stop == -1) {
4040 GST_DEBUG_OBJECT (demux, "doing duration query to fix up unset stop");
4041 gst_pad_peer_query_duration (demux->common.sinkpad, GST_FORMAT_BYTES,
4045 /* if upstream doesn't know the size, it's likely that it's not seekable in
4046 * practice even if it technically may be seekable */
4047 if (seekable && (start != 0 || stop <= start)) {
4048 GST_DEBUG_OBJECT (demux, "seekable but unknown start/stop -> disable");
4053 GST_INFO_OBJECT (demux, "seekable: %d (%" G_GUINT64_FORMAT " - %"
4054 G_GUINT64_FORMAT ")", seekable, start, stop);
4055 demux->seekable = seekable;
4057 gst_query_unref (query);
4060 static GstFlowReturn
4061 gst_matroska_demux_find_tracks (GstMatroskaDemux * demux)
4067 GstFlowReturn ret = GST_FLOW_OK;
4069 GST_WARNING_OBJECT (demux,
4070 "Found Cluster element before Tracks, searching Tracks");
4073 before_pos = demux->common.offset;
4075 /* Search Tracks element */
4077 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4078 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4079 if (ret != GST_FLOW_OK)
4082 if (id != GST_MATROSKA_ID_TRACKS) {
4083 /* we may be skipping large cluster here, so forego size check etc */
4084 /* ... but we can't skip undefined size; force error */
4085 if (length == G_MAXUINT64) {
4086 ret = gst_matroska_demux_check_read_size (demux, length);
4089 demux->common.offset += needed;
4090 demux->common.offset += length;
4095 /* will lead to track parsing ... */
4096 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4101 demux->common.offset = before_pos;
4106 #define GST_READ_CHECK(stmt) \
4108 if (G_UNLIKELY ((ret = (stmt)) != GST_FLOW_OK)) { \
4109 if (ret == GST_FLOW_OVERFLOW) { \
4110 ret = GST_FLOW_OK; \
4116 static GstFlowReturn
4117 gst_matroska_demux_parse_id (GstMatroskaDemux * demux, guint32 id,
4118 guint64 length, guint needed)
4120 GstEbmlRead ebml = { 0, };
4121 GstFlowReturn ret = GST_FLOW_OK;
4124 GST_LOG_OBJECT (demux, "Parsing Element id 0x%x, "
4125 "size %" G_GUINT64_FORMAT ", prefix %d", id, length, needed);
4127 /* if we plan to read and parse this element, we need prefix (id + length)
4128 * and the contents */
4129 /* mind about overflow wrap-around when dealing with undefined size */
4131 if (G_LIKELY (length != G_MAXUINT64))
4134 switch (demux->common.state) {
4135 case GST_MATROSKA_READ_STATE_START:
4137 case GST_EBML_ID_HEADER:
4138 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4139 ret = gst_matroska_read_common_parse_header (&demux->common, &ebml);
4140 if (ret != GST_FLOW_OK)
4142 demux->common.state = GST_MATROSKA_READ_STATE_SEGMENT;
4143 gst_matroska_demux_check_seekability (demux);
4146 goto invalid_header;
4150 case GST_MATROSKA_READ_STATE_SEGMENT:
4152 case GST_MATROSKA_ID_SEGMENT:
4153 /* eat segment prefix */
4154 GST_READ_CHECK (gst_matroska_demux_flush (demux, needed));
4155 GST_DEBUG_OBJECT (demux,
4156 "Found Segment start at offset %" G_GUINT64_FORMAT " with size %"
4157 G_GUINT64_FORMAT, demux->common.offset, length);
4158 /* seeks are from the beginning of the segment,
4159 * after the segment ID/length */
4160 demux->common.ebml_segment_start = demux->common.offset;
4162 length = G_MAXUINT64;
4163 demux->common.ebml_segment_length = length;
4164 demux->common.state = GST_MATROSKA_READ_STATE_HEADER;
4167 GST_WARNING_OBJECT (demux,
4168 "Expected a Segment ID (0x%x), but received 0x%x!",
4169 GST_MATROSKA_ID_SEGMENT, id);
4170 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4174 case GST_MATROSKA_READ_STATE_SCANNING:
4175 if (id != GST_MATROSKA_ID_CLUSTER &&
4176 id != GST_MATROSKA_ID_CLUSTERTIMECODE)
4179 case GST_MATROSKA_READ_STATE_HEADER:
4180 case GST_MATROSKA_READ_STATE_DATA:
4181 case GST_MATROSKA_READ_STATE_SEEK:
4183 case GST_MATROSKA_ID_SEGMENTINFO:
4184 if (!demux->common.segmentinfo_parsed) {
4185 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4186 ret = gst_matroska_read_common_parse_info (&demux->common,
4187 GST_ELEMENT_CAST (demux), &ebml);
4189 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4192 case GST_MATROSKA_ID_TRACKS:
4193 if (!demux->tracks_parsed) {
4194 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4195 ret = gst_matroska_demux_parse_tracks (demux, &ebml);
4197 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4200 case GST_MATROSKA_ID_CLUSTER:
4201 if (G_UNLIKELY (!demux->tracks_parsed)) {
4202 if (demux->streaming) {
4203 GST_DEBUG_OBJECT (demux, "Cluster before Track");
4204 goto not_streamable;
4206 ret = gst_matroska_demux_find_tracks (demux);
4207 if (!demux->tracks_parsed)
4211 if (G_UNLIKELY (demux->common.state
4212 == GST_MATROSKA_READ_STATE_HEADER)) {
4213 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
4214 demux->first_cluster_offset = demux->common.offset;
4215 GST_DEBUG_OBJECT (demux, "signaling no more pads");
4216 gst_element_no_more_pads (GST_ELEMENT (demux));
4217 /* send initial segment - we wait till we know the first
4218 incoming timestamp, so we can properly set the start of
4220 demux->need_segment = TRUE;
4222 demux->cluster_time = GST_CLOCK_TIME_NONE;
4223 demux->cluster_offset = demux->common.offset;
4224 if (G_UNLIKELY (!demux->seek_first && demux->seek_block)) {
4225 GST_DEBUG_OBJECT (demux, "seek target block %" G_GUINT64_FORMAT
4226 " not found in Cluster, trying next Cluster's first block instead",
4228 demux->seek_block = 0;
4230 demux->seek_first = FALSE;
4231 /* record next cluster for recovery */
4232 if (read != G_MAXUINT64)
4233 demux->next_cluster_offset = demux->cluster_offset + read;
4234 /* eat cluster prefix */
4235 gst_matroska_demux_flush (demux, needed);
4237 case GST_MATROSKA_ID_CLUSTERTIMECODE:
4241 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4242 if ((ret = gst_ebml_read_uint (&ebml, &id, &num)) != GST_FLOW_OK)
4244 GST_DEBUG_OBJECT (demux, "ClusterTimeCode: %" G_GUINT64_FORMAT, num);
4245 demux->cluster_time = num;
4247 if (demux->common.element_index) {
4248 if (demux->common.element_index_writer_id == -1)
4249 gst_index_get_writer_id (demux->common.element_index,
4250 GST_OBJECT (demux), &demux->common.element_index_writer_id);
4251 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
4252 G_GUINT64_FORMAT " for writer id %d",
4253 GST_TIME_ARGS (demux->cluster_time), demux->cluster_offset,
4254 demux->common.element_index_writer_id);
4255 gst_index_add_association (demux->common.element_index,
4256 demux->common.element_index_writer_id,
4257 GST_ASSOCIATION_FLAG_KEY_UNIT,
4258 GST_FORMAT_TIME, demux->cluster_time,
4259 GST_FORMAT_BYTES, demux->cluster_offset, NULL);
4264 case GST_MATROSKA_ID_BLOCKGROUP:
4265 if (!gst_matroska_demux_seek_block (demux))
4267 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4268 DEBUG_ELEMENT_START (demux, &ebml, "BlockGroup");
4269 if ((ret = gst_ebml_read_master (&ebml, &id)) == GST_FLOW_OK) {
4270 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4271 &ebml, demux->cluster_time, demux->cluster_offset, FALSE);
4273 DEBUG_ELEMENT_STOP (demux, &ebml, "BlockGroup", ret);
4275 case GST_MATROSKA_ID_SIMPLEBLOCK:
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, "SimpleBlock");
4280 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4281 &ebml, demux->cluster_time, demux->cluster_offset, TRUE);
4282 DEBUG_ELEMENT_STOP (demux, &ebml, "SimpleBlock", ret);
4284 case GST_MATROSKA_ID_ATTACHMENTS:
4285 if (!demux->common.attachments_parsed) {
4286 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4287 ret = gst_matroska_read_common_parse_attachments (&demux->common,
4288 GST_ELEMENT_CAST (demux), &ebml);
4290 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4293 case GST_MATROSKA_ID_TAGS:
4294 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4295 ret = gst_matroska_read_common_parse_metadata (&demux->common,
4296 GST_ELEMENT_CAST (demux), &ebml);
4298 case GST_MATROSKA_ID_CHAPTERS:
4299 if (!demux->common.chapters_parsed) {
4300 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4302 gst_matroska_read_common_parse_chapters (&demux->common, &ebml);
4304 if (demux->common.toc) {
4305 gst_matroska_demux_send_event (demux,
4306 gst_event_new_toc (demux->common.toc, FALSE));
4309 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4311 case GST_MATROSKA_ID_SEEKHEAD:
4312 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4313 ret = gst_matroska_demux_parse_contents (demux, &ebml);
4315 case GST_MATROSKA_ID_CUES:
4316 if (demux->common.index_parsed) {
4317 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4320 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4321 ret = gst_matroska_read_common_parse_index (&demux->common, &ebml);
4322 /* only push based; delayed index building */
4323 if (ret == GST_FLOW_OK
4324 && demux->common.state == GST_MATROSKA_READ_STATE_SEEK) {
4327 GST_OBJECT_LOCK (demux);
4328 event = demux->seek_event;
4329 demux->seek_event = NULL;
4330 GST_OBJECT_UNLOCK (demux);
4333 /* unlikely to fail, since we managed to seek to this point */
4334 if (!gst_matroska_demux_handle_seek_event (demux, NULL, event))
4336 /* resume data handling, main thread clear to seek again */
4337 GST_OBJECT_LOCK (demux);
4338 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
4339 GST_OBJECT_UNLOCK (demux);
4342 case GST_MATROSKA_ID_POSITION:
4343 case GST_MATROSKA_ID_PREVSIZE:
4344 case GST_MATROSKA_ID_ENCRYPTEDBLOCK:
4345 case GST_MATROSKA_ID_SILENTTRACKS:
4346 GST_DEBUG_OBJECT (demux,
4347 "Skipping Cluster subelement 0x%x - ignoring", id);
4351 GST_DEBUG_OBJECT (demux, "skipping Element 0x%x", id);
4352 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4358 if (ret == GST_FLOW_PARSE)
4362 gst_ebml_read_clear (&ebml);
4368 /* simply exit, maybe not enough data yet */
4369 /* no ebml to clear if read error */
4374 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4375 ("Failed to parse Element 0x%x", id));
4376 ret = GST_FLOW_ERROR;
4381 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4382 ("File layout does not permit streaming"));
4383 ret = GST_FLOW_ERROR;
4388 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4389 ("No Tracks element found"));
4390 ret = GST_FLOW_ERROR;
4395 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Invalid header"));
4396 ret = GST_FLOW_ERROR;
4401 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Failed to seek"));
4402 ret = GST_FLOW_ERROR;
4408 gst_matroska_demux_loop (GstPad * pad)
4410 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (pad));
4416 /* If we have to close a segment, send a new segment to do this now */
4417 if (G_LIKELY (demux->common.state == GST_MATROSKA_READ_STATE_DATA)) {
4418 if (G_UNLIKELY (demux->new_segment)) {
4419 gst_matroska_demux_send_event (demux, demux->new_segment);
4420 demux->new_segment = NULL;
4424 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4425 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4426 if (ret == GST_FLOW_EOS) {
4428 } else if (ret == GST_FLOW_FLUSHING) {
4430 } else if (ret != GST_FLOW_OK) {
4431 ret = gst_matroska_demux_check_parse_error (demux);
4433 /* Only handle EOS as no error if we're outside the segment already */
4434 if (ret == GST_FLOW_EOS && (demux->common.ebml_segment_length != G_MAXUINT64
4435 && demux->common.offset >=
4436 demux->common.ebml_segment_start +
4437 demux->common.ebml_segment_length))
4439 else if (ret != GST_FLOW_OK)
4445 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
4446 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
4449 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4450 if (ret == GST_FLOW_EOS)
4452 if (ret != GST_FLOW_OK)
4455 /* check if we're at the end of a configured segment */
4456 if (G_LIKELY (demux->common.src->len)) {
4459 g_assert (demux->common.num_streams == demux->common.src->len);
4460 for (i = 0; i < demux->common.src->len; i++) {
4461 GstMatroskaTrackContext *context = g_ptr_array_index (demux->common.src,
4463 GST_DEBUG_OBJECT (context->pad, "pos %" GST_TIME_FORMAT,
4464 GST_TIME_ARGS (context->pos));
4465 if (context->eos == FALSE)
4469 GST_INFO_OBJECT (demux, "All streams are EOS");
4475 if (G_UNLIKELY (demux->cached_length == G_MAXUINT64 ||
4476 demux->common.offset >= demux->cached_length)) {
4477 demux->cached_length = gst_matroska_read_common_get_length (&demux->common);
4478 if (demux->common.offset == demux->cached_length) {
4479 GST_LOG_OBJECT (demux, "Reached end of stream");
4490 if (demux->common.segment.rate < 0.0) {
4491 ret = gst_matroska_demux_seek_to_previous_keyframe (demux);
4492 if (ret == GST_FLOW_OK)
4499 const gchar *reason = gst_flow_get_name (ret);
4500 gboolean push_eos = FALSE;
4502 GST_LOG_OBJECT (demux, "pausing task, reason %s", reason);
4503 gst_pad_pause_task (demux->common.sinkpad);
4505 if (ret == GST_FLOW_EOS) {
4506 /* perform EOS logic */
4508 /* If we were in the headers, make sure we send no-more-pads.
4509 This will ensure decodebin2 does not get stuck thinking
4510 the chain is not complete yet, and waiting indefinitely. */
4511 if (G_UNLIKELY (demux->common.state == GST_MATROSKA_READ_STATE_HEADER)) {
4512 if (demux->common.src->len == 0) {
4513 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
4514 ("No pads created"));
4516 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL),
4517 ("Failed to finish reading headers"));
4519 gst_element_no_more_pads (GST_ELEMENT (demux));
4522 if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
4525 /* for segment playback we need to post when (in stream time)
4526 * we stopped, this is either stop (when set) or the duration. */
4527 if ((stop = demux->common.segment.stop) == -1)
4528 stop = demux->last_stop_end;
4530 GST_LOG_OBJECT (demux, "Sending segment done, at end of segment");
4531 gst_element_post_message (GST_ELEMENT (demux),
4532 gst_message_new_segment_done (GST_OBJECT (demux), GST_FORMAT_TIME,
4534 gst_matroska_demux_send_event (demux,
4535 gst_event_new_segment_done (GST_FORMAT_TIME, stop));
4539 } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS) {
4540 /* for fatal errors we post an error message */
4541 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
4542 ("stream stopped, reason %s", reason));
4546 /* send EOS, and prevent hanging if no streams yet */
4547 GST_LOG_OBJECT (demux, "Sending EOS, at end of stream");
4548 if (!gst_matroska_demux_send_event (demux, gst_event_new_eos ()) &&
4549 (ret == GST_FLOW_EOS)) {
4550 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4551 (NULL), ("got eos but no streams (yet)"));
4559 * Create and push a flushing seek event upstream
4562 perform_seek_to_offset (GstMatroskaDemux * demux, gdouble rate, guint64 offset,
4568 GST_DEBUG_OBJECT (demux, "Seeking to %" G_GUINT64_FORMAT, offset);
4571 gst_event_new_seek (rate, GST_FORMAT_BYTES,
4572 GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, GST_SEEK_TYPE_SET, offset,
4573 GST_SEEK_TYPE_NONE, -1);
4574 gst_event_set_seqnum (event, seqnum);
4576 res = gst_pad_push_event (demux->common.sinkpad, event);
4578 /* segment event will update offset */
4582 static GstFlowReturn
4583 gst_matroska_demux_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
4585 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4587 GstFlowReturn ret = GST_FLOW_OK;
4592 if (G_UNLIKELY (GST_BUFFER_IS_DISCONT (buffer))) {
4593 GST_DEBUG_OBJECT (demux, "got DISCONT");
4594 gst_adapter_clear (demux->common.adapter);
4595 GST_OBJECT_LOCK (demux);
4596 gst_matroska_read_common_reset_streams (&demux->common,
4597 GST_CLOCK_TIME_NONE, FALSE);
4598 GST_OBJECT_UNLOCK (demux);
4601 gst_adapter_push (demux->common.adapter, buffer);
4605 available = gst_adapter_available (demux->common.adapter);
4607 ret = gst_matroska_read_common_peek_id_length_push (&demux->common,
4608 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4609 if (G_UNLIKELY (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)) {
4610 if (demux->common.ebml_segment_length != G_MAXUINT64
4611 && demux->common.offset >=
4612 demux->common.ebml_segment_start + demux->common.ebml_segment_length)
4617 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
4618 "size %" G_GUINT64_FORMAT ", needed %d, available %d",
4619 demux->common.offset, id, length, needed, available);
4621 if (needed > available)
4624 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4625 if (ret == GST_FLOW_EOS) {
4626 /* need more data */
4628 } else if (ret != GST_FLOW_OK) {
4635 gst_matroska_demux_handle_sink_event (GstPad * pad, GstObject * parent,
4638 gboolean res = TRUE;
4639 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4641 GST_DEBUG_OBJECT (demux,
4642 "have event type %s: %p on sink pad", GST_EVENT_TYPE_NAME (event), event);
4644 switch (GST_EVENT_TYPE (event)) {
4645 case GST_EVENT_SEGMENT:
4647 const GstSegment *segment;
4649 /* some debug output */
4650 gst_event_parse_segment (event, &segment);
4651 /* FIXME: do we need to update segment base here (like accum in 0.10)? */
4652 GST_DEBUG_OBJECT (demux,
4653 "received format %d segment %" GST_SEGMENT_FORMAT, segment->format,
4656 if (demux->common.state < GST_MATROSKA_READ_STATE_DATA) {
4657 GST_DEBUG_OBJECT (demux, "still starting");
4661 /* we only expect a BYTE segment, e.g. following a seek */
4662 if (segment->format != GST_FORMAT_BYTES) {
4663 GST_DEBUG_OBJECT (demux, "unsupported segment format, ignoring");
4667 GST_DEBUG_OBJECT (demux, "clearing segment state");
4668 GST_OBJECT_LOCK (demux);
4669 /* clear current segment leftover */
4670 gst_adapter_clear (demux->common.adapter);
4671 /* and some streaming setup */
4672 demux->common.offset = segment->start;
4673 /* accumulate base based on current position */
4674 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.position))
4675 demux->common.segment.base +=
4676 (MAX (demux->common.segment.position, demux->stream_start_time)
4677 - demux->stream_start_time) / fabs (demux->common.segment.rate);
4678 /* do not know where we are;
4679 * need to come across a cluster and generate segment */
4680 demux->common.segment.position = GST_CLOCK_TIME_NONE;
4681 demux->cluster_time = GST_CLOCK_TIME_NONE;
4682 demux->cluster_offset = 0;
4683 demux->need_segment = TRUE;
4684 demux->segment_seqnum = gst_event_get_seqnum (event);
4685 /* but keep some of the upstream segment */
4686 demux->common.segment.rate = segment->rate;
4687 /* also check if need to keep some of the requested seek position */
4688 if (demux->seek_offset == segment->start) {
4689 GST_DEBUG_OBJECT (demux, "position matches requested seek");
4690 demux->common.segment.position = demux->requested_seek_time;
4692 GST_DEBUG_OBJECT (demux, "unexpected segment position");
4694 demux->requested_seek_time = GST_CLOCK_TIME_NONE;
4695 demux->seek_offset = -1;
4696 GST_OBJECT_UNLOCK (demux);
4698 /* chain will send initial segment after pads have been added,
4699 * or otherwise come up with one */
4700 GST_DEBUG_OBJECT (demux, "eating event");
4701 gst_event_unref (event);
4707 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
4708 gst_event_unref (event);
4709 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4710 (NULL), ("got eos and didn't receive a complete header object"));
4711 } else if (demux->common.num_streams == 0) {
4712 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4713 (NULL), ("got eos but no streams (yet)"));
4715 gst_matroska_demux_send_event (demux, event);
4719 case GST_EVENT_FLUSH_STOP:
4723 gst_adapter_clear (demux->common.adapter);
4724 GST_OBJECT_LOCK (demux);
4725 gst_matroska_read_common_reset_streams (&demux->common,
4726 GST_CLOCK_TIME_NONE, TRUE);
4727 dur = demux->common.segment.duration;
4728 gst_segment_init (&demux->common.segment, GST_FORMAT_TIME);
4729 demux->common.segment.duration = dur;
4730 demux->cluster_time = GST_CLOCK_TIME_NONE;
4731 demux->cluster_offset = 0;
4732 GST_OBJECT_UNLOCK (demux);
4736 res = gst_pad_event_default (pad, parent, event);
4744 gst_matroska_demux_sink_activate (GstPad * sinkpad, GstObject * parent)
4746 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4748 gboolean pull_mode = FALSE;
4750 query = gst_query_new_scheduling ();
4752 if (gst_pad_peer_query (sinkpad, query))
4753 pull_mode = gst_query_has_scheduling_mode_with_flags (query,
4754 GST_PAD_MODE_PULL, GST_SCHEDULING_FLAG_SEEKABLE);
4756 gst_query_unref (query);
4759 GST_DEBUG ("going to pull mode");
4760 demux->streaming = FALSE;
4761 return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PULL, TRUE);
4763 GST_DEBUG ("going to push (streaming) mode");
4764 demux->streaming = TRUE;
4765 return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PUSH, TRUE);
4770 gst_matroska_demux_sink_activate_mode (GstPad * sinkpad, GstObject * parent,
4771 GstPadMode mode, gboolean active)
4774 case GST_PAD_MODE_PULL:
4776 /* if we have a scheduler we can start the task */
4777 gst_pad_start_task (sinkpad, (GstTaskFunction) gst_matroska_demux_loop,
4780 gst_pad_stop_task (sinkpad);
4783 case GST_PAD_MODE_PUSH:
4791 gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext *
4792 videocontext, const gchar * codec_id, guint8 * data, guint size,
4793 gchar ** codec_name, guint32 * riff_fourcc)
4795 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) videocontext;
4796 GstCaps *caps = NULL;
4798 g_assert (videocontext != NULL);
4799 g_assert (codec_name != NULL);
4804 /* TODO: check if we have all codec types from matroska-ids.h
4805 * check if we have to do more special things with codec_private
4808 * GST_MATROSKA_CODEC_ID_VIDEO_QUICKTIME
4809 * GST_MATROSKA_CODEC_ID_VIDEO_SNOW
4812 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VFW_FOURCC)) {
4813 gst_riff_strf_vids *vids = NULL;
4816 GstBuffer *buf = NULL;
4818 vids = (gst_riff_strf_vids *) data;
4820 /* assure size is big enough */
4822 GST_WARNING ("Too small BITMAPINFOHEADER (%d bytes)", size);
4825 if (size < sizeof (gst_riff_strf_vids)) {
4826 vids = g_new (gst_riff_strf_vids, 1);
4827 memcpy (vids, data, size);
4830 context->dts_only = TRUE; /* VFW files only store DTS */
4832 /* little-endian -> byte-order */
4833 vids->size = GUINT32_FROM_LE (vids->size);
4834 vids->width = GUINT32_FROM_LE (vids->width);
4835 vids->height = GUINT32_FROM_LE (vids->height);
4836 vids->planes = GUINT16_FROM_LE (vids->planes);
4837 vids->bit_cnt = GUINT16_FROM_LE (vids->bit_cnt);
4838 vids->compression = GUINT32_FROM_LE (vids->compression);
4839 vids->image_size = GUINT32_FROM_LE (vids->image_size);
4840 vids->xpels_meter = GUINT32_FROM_LE (vids->xpels_meter);
4841 vids->ypels_meter = GUINT32_FROM_LE (vids->ypels_meter);
4842 vids->num_colors = GUINT32_FROM_LE (vids->num_colors);
4843 vids->imp_colors = GUINT32_FROM_LE (vids->imp_colors);
4845 if (size > sizeof (gst_riff_strf_vids)) { /* some extra_data */
4846 gsize offset = sizeof (gst_riff_strf_vids);
4849 gst_buffer_new_wrapped (g_memdup ((guint8 *) vids + offset,
4850 size - offset), size - offset);
4854 *riff_fourcc = vids->compression;
4856 caps = gst_riff_create_video_caps (vids->compression, NULL, vids,
4857 buf, NULL, codec_name);
4860 GST_WARNING ("Unhandled RIFF fourcc %" GST_FOURCC_FORMAT,
4861 GST_FOURCC_ARGS (vids->compression));
4865 gst_buffer_unref (buf);
4867 if (vids != (gst_riff_strf_vids *) data)
4870 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_UNCOMPRESSED)) {
4872 GstVideoFormat format;
4874 gst_video_info_init (&info);
4875 switch (videocontext->fourcc) {
4876 case GST_MAKE_FOURCC ('I', '4', '2', '0'):
4877 format = GST_VIDEO_FORMAT_I420;
4879 case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
4880 format = GST_VIDEO_FORMAT_YUY2;
4882 case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
4883 format = GST_VIDEO_FORMAT_YV12;
4885 case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
4886 format = GST_VIDEO_FORMAT_UYVY;
4888 case GST_MAKE_FOURCC ('A', 'Y', 'U', 'V'):
4889 format = GST_VIDEO_FORMAT_AYUV;
4891 case GST_MAKE_FOURCC ('Y', '8', '0', '0'):
4892 case GST_MAKE_FOURCC ('Y', '8', ' ', ' '):
4893 format = GST_VIDEO_FORMAT_GRAY8;
4895 case GST_MAKE_FOURCC ('R', 'G', 'B', 24):
4896 format = GST_VIDEO_FORMAT_RGB;
4898 case GST_MAKE_FOURCC ('B', 'G', 'R', 24):
4899 format = GST_VIDEO_FORMAT_BGR;
4902 GST_DEBUG ("Unknown fourcc %" GST_FOURCC_FORMAT,
4903 GST_FOURCC_ARGS (videocontext->fourcc));
4907 gst_video_info_set_format (&info, format, videocontext->pixel_width,
4908 videocontext->pixel_height);
4909 caps = gst_video_info_to_caps (&info);
4910 *codec_name = gst_pb_utils_get_codec_description (caps);
4911 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_SP)) {
4912 caps = gst_caps_new_simple ("video/x-divx",
4913 "divxversion", G_TYPE_INT, 4, NULL);
4914 *codec_name = g_strdup ("MPEG-4 simple profile");
4915 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP) ||
4916 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AP)) {
4917 caps = gst_caps_new_simple ("video/mpeg",
4918 "mpegversion", G_TYPE_INT, 4,
4919 "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
4923 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
4924 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
4925 gst_buffer_unref (priv);
4927 gst_codec_utils_mpeg4video_caps_set_level_and_profile (caps, data, size);
4929 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP))
4930 *codec_name = g_strdup ("MPEG-4 advanced simple profile");
4932 *codec_name = g_strdup ("MPEG-4 advanced profile");
4933 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MSMPEG4V3)) {
4935 caps = gst_caps_new_full (gst_structure_new ("video/x-divx",
4936 "divxversion", G_TYPE_INT, 3, NULL),
4937 gst_structure_new ("video/x-msmpeg",
4938 "msmpegversion", G_TYPE_INT, 43, NULL), NULL);
4940 caps = gst_caps_new_simple ("video/x-msmpeg",
4941 "msmpegversion", G_TYPE_INT, 43, NULL);
4942 *codec_name = g_strdup ("Microsoft MPEG-4 v.3");
4943 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1) ||
4944 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG2)) {
4947 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1))
4952 caps = gst_caps_new_simple ("video/mpeg",
4953 "systemstream", G_TYPE_BOOLEAN, FALSE,
4954 "mpegversion", G_TYPE_INT, mpegversion, NULL);
4955 *codec_name = g_strdup_printf ("MPEG-%d video", mpegversion);
4956 context->postprocess_frame = gst_matroska_demux_add_mpeg_seq_header;
4957 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MJPEG)) {
4958 caps = gst_caps_new_empty_simple ("image/jpeg");
4959 *codec_name = g_strdup ("Motion-JPEG");
4960 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AVC)) {
4961 caps = gst_caps_new_empty_simple ("video/x-h264");
4965 /* First byte is the version, second is the profile indication, and third
4966 * is the 5 contraint_set_flags and 3 reserved bits. Fourth byte is the
4967 * level indication. */
4968 gst_codec_utils_h264_caps_set_level_and_profile (caps, data + 1,
4971 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
4972 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
4973 gst_buffer_unref (priv);
4975 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "avc",
4976 "alignment", G_TYPE_STRING, "au", NULL);
4978 GST_WARNING ("No codec data found, assuming output is byte-stream");
4979 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
4982 *codec_name = g_strdup ("H264");
4983 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEGH_HEVC)) {
4984 caps = gst_caps_new_empty_simple ("video/x-h265");
4988 gst_codec_utils_h265_caps_set_level_tier_and_profile (caps, data + 1,
4991 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
4992 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
4993 gst_buffer_unref (priv);
4995 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "hvc1",
4996 "alignment", G_TYPE_STRING, "au", NULL);
4998 GST_WARNING ("No codec data found, assuming output is byte-stream");
4999 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
5002 *codec_name = g_strdup ("HEVC");
5003 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1)) ||
5004 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2)) ||
5005 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3)) ||
5006 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))) {
5007 gint rmversion = -1;
5009 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1))
5011 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2))
5013 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3))
5015 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))
5018 caps = gst_caps_new_simple ("video/x-pn-realvideo",
5019 "rmversion", G_TYPE_INT, rmversion, NULL);
5020 GST_DEBUG ("data:%p, size:0x%x", data, size);
5021 /* We need to extract the extradata ! */
5022 if (data && (size >= 0x22)) {
5027 subformat = GST_READ_UINT32_BE (data + 0x1a);
5028 rformat = GST_READ_UINT32_BE (data + 0x1e);
5031 gst_buffer_new_wrapped (g_memdup (data + 0x1a, size - 0x1a),
5033 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, "format",
5034 G_TYPE_INT, rformat, "subformat", G_TYPE_INT, subformat, NULL);
5035 gst_buffer_unref (priv);
5038 *codec_name = g_strdup_printf ("RealVideo %d.0", rmversion);
5039 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_THEORA)) {
5040 caps = gst_caps_new_empty_simple ("video/x-theora");
5041 context->stream_headers =
5042 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
5043 context->codec_priv_size);
5044 /* FIXME: mark stream as broken and skip if there are no stream headers */
5045 context->send_stream_headers = TRUE;
5046 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_DIRAC)) {
5047 caps = gst_caps_new_empty_simple ("video/x-dirac");
5048 *codec_name = g_strdup_printf ("Dirac");
5049 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8)) {
5050 caps = gst_caps_new_empty_simple ("video/x-vp8");
5051 *codec_name = g_strdup_printf ("On2 VP8");
5052 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP9)) {
5053 caps = gst_caps_new_empty_simple ("video/x-vp9");
5054 *codec_name = g_strdup_printf ("On2 VP9");
5056 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
5062 GstStructure *structure;
5064 for (i = 0; i < gst_caps_get_size (caps); i++) {
5065 structure = gst_caps_get_structure (caps, i);
5067 /* FIXME: use the real unit here! */
5068 GST_DEBUG ("video size %dx%d, target display size %dx%d (any unit)",
5069 videocontext->pixel_width,
5070 videocontext->pixel_height,
5071 videocontext->display_width, videocontext->display_height);
5073 /* pixel width and height are the w and h of the video in pixels */
5074 if (videocontext->pixel_width > 0 && videocontext->pixel_height > 0) {
5075 gint w = videocontext->pixel_width;
5076 gint h = videocontext->pixel_height;
5078 gst_structure_set (structure,
5079 "width", G_TYPE_INT, w, "height", G_TYPE_INT, h, NULL);
5082 if (videocontext->display_width > 0 || videocontext->display_height > 0) {
5085 if (videocontext->display_width <= 0)
5086 videocontext->display_width = videocontext->pixel_width;
5087 if (videocontext->display_height <= 0)
5088 videocontext->display_height = videocontext->pixel_height;
5090 /* calculate the pixel aspect ratio using the display and pixel w/h */
5091 n = videocontext->display_width * videocontext->pixel_height;
5092 d = videocontext->display_height * videocontext->pixel_width;
5093 GST_DEBUG ("setting PAR to %d/%d", n, d);
5094 gst_structure_set (structure, "pixel-aspect-ratio",
5096 videocontext->display_width * videocontext->pixel_height,
5097 videocontext->display_height * videocontext->pixel_width, NULL);
5100 if (videocontext->default_fps > 0.0) {
5103 gst_util_double_to_fraction (videocontext->default_fps, &fps_n, &fps_d);
5105 GST_DEBUG ("using default fps %d/%d", fps_n, fps_d);
5107 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION, fps_n,
5109 } else if (context->default_duration > 0) {
5112 gst_video_guess_framerate (context->default_duration, &fps_n, &fps_d);
5114 GST_INFO ("using default duration %" G_GUINT64_FORMAT
5115 " framerate %d/%d", context->default_duration, fps_n, fps_d);
5117 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
5118 fps_n, fps_d, NULL);
5120 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
5124 if (videocontext->parent.flags & GST_MATROSKA_VIDEOTRACK_INTERLACED)
5125 gst_structure_set (structure, "interlace-mode", G_TYPE_STRING,
5129 caps = gst_caps_simplify (caps);
5136 * Some AAC specific code... *sigh*
5137 * FIXME: maybe we should use '15' and code the sample rate explicitly
5138 * if the sample rate doesn't match the predefined rates exactly? (tpm)
5142 aac_rate_idx (gint rate)
5146 else if (75132 <= rate)
5148 else if (55426 <= rate)
5150 else if (46009 <= rate)
5152 else if (37566 <= rate)
5154 else if (27713 <= rate)
5156 else if (23004 <= rate)
5158 else if (18783 <= rate)
5160 else if (13856 <= rate)
5162 else if (11502 <= rate)
5164 else if (9391 <= rate)
5171 aac_profile_idx (const gchar * codec_id)
5175 if (strlen (codec_id) <= 12)
5177 else if (!strncmp (&codec_id[12], "MAIN", 4))
5179 else if (!strncmp (&codec_id[12], "LC", 2))
5181 else if (!strncmp (&codec_id[12], "SSR", 3))
5190 round_up_pow2 (guint n)
5201 #define AAC_SYNC_EXTENSION_TYPE 0x02b7
5204 gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext *
5205 audiocontext, const gchar * codec_id, guint8 * data, guint size,
5206 gchar ** codec_name, guint16 * riff_audio_fmt)
5208 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) audiocontext;
5209 GstCaps *caps = NULL;
5211 g_assert (audiocontext != NULL);
5212 g_assert (codec_name != NULL);
5215 *riff_audio_fmt = 0;
5217 /* TODO: check if we have all codec types from matroska-ids.h
5218 * check if we have to do more special things with codec_private
5219 * check if we need bitdepth in different places too
5220 * implement channel position magic
5222 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID9
5223 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID10
5224 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDMC
5225 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDM2
5228 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1) ||
5229 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2) ||
5230 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L3)) {
5233 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1))
5235 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2))
5240 caps = gst_caps_new_simple ("audio/mpeg",
5241 "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, layer, NULL);
5242 *codec_name = g_strdup_printf ("MPEG-1 layer %d", layer);
5243 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE) ||
5244 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_LE)) {
5247 GstAudioFormat format;
5249 sign = (audiocontext->bitdepth != 8);
5250 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE))
5251 endianness = G_BIG_ENDIAN;
5253 endianness = G_LITTLE_ENDIAN;
5255 format = gst_audio_format_build_integer (sign, endianness,
5256 audiocontext->bitdepth, audiocontext->bitdepth);
5258 /* FIXME: Channel mask and reordering */
5259 caps = gst_caps_new_simple ("audio/x-raw",
5260 "format", G_TYPE_STRING, gst_audio_format_to_string (format),
5261 "layout", G_TYPE_STRING, "interleaved", NULL);
5263 *codec_name = g_strdup_printf ("Raw %d-bit PCM audio",
5264 audiocontext->bitdepth);
5265 context->alignment = GST_ROUND_UP_8 (audiocontext->bitdepth) / 8;
5266 context->alignment = round_up_pow2 (context->alignment);
5267 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_FLOAT)) {
5268 const gchar *format;
5269 if (audiocontext->bitdepth == 32)
5273 /* FIXME: Channel mask and reordering */
5274 caps = gst_caps_new_simple ("audio/x-raw",
5275 "format", G_TYPE_STRING, format,
5276 "layout", G_TYPE_STRING, "interleaved", NULL);
5277 *codec_name = g_strdup_printf ("Raw %d-bit floating-point audio",
5278 audiocontext->bitdepth);
5279 context->alignment = audiocontext->bitdepth / 8;
5280 context->alignment = round_up_pow2 (context->alignment);
5281 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AC3,
5282 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AC3))) {
5283 caps = gst_caps_new_simple ("audio/x-ac3",
5284 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5285 *codec_name = g_strdup ("AC-3 audio");
5286 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_EAC3,
5287 strlen (GST_MATROSKA_CODEC_ID_AUDIO_EAC3))) {
5288 caps = gst_caps_new_simple ("audio/x-eac3",
5289 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5290 *codec_name = g_strdup ("E-AC-3 audio");
5291 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TRUEHD,
5292 strlen (GST_MATROSKA_CODEC_ID_AUDIO_TRUEHD))) {
5293 caps = gst_caps_new_empty_simple ("audio/x-true-hd");
5294 *codec_name = g_strdup ("Dolby TrueHD");
5295 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_DTS)) {
5296 caps = gst_caps_new_empty_simple ("audio/x-dts");
5297 *codec_name = g_strdup ("DTS audio");
5298 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_VORBIS)) {
5299 caps = gst_caps_new_empty_simple ("audio/x-vorbis");
5300 context->stream_headers =
5301 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
5302 context->codec_priv_size);
5303 /* FIXME: mark stream as broken and skip if there are no stream headers */
5304 context->send_stream_headers = TRUE;
5305 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_FLAC)) {
5306 caps = gst_caps_new_empty_simple ("audio/x-flac");
5307 context->stream_headers =
5308 gst_matroska_parse_flac_stream_headers (context->codec_priv,
5309 context->codec_priv_size);
5310 /* FIXME: mark stream as broken and skip if there are no stream headers */
5311 context->send_stream_headers = TRUE;
5312 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_SPEEX)) {
5313 caps = gst_caps_new_empty_simple ("audio/x-speex");
5314 context->stream_headers =
5315 gst_matroska_parse_speex_stream_headers (context->codec_priv,
5316 context->codec_priv_size);
5317 /* FIXME: mark stream as broken and skip if there are no stream headers */
5318 context->send_stream_headers = TRUE;
5319 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_OPUS)) {
5320 caps = gst_caps_new_empty_simple ("audio/x-opus");
5321 *codec_name = g_strdup ("Opus");
5322 context->stream_headers =
5323 gst_matroska_parse_opus_stream_headers (context->codec_priv,
5324 context->codec_priv_size);
5325 if (context->stream_headers) {
5326 /* There was a valid header. Multistream headers are more than
5327 * 19 bytes, as they include an extra channel mapping table. */
5328 gboolean multistream = (context->codec_priv_size > 19);
5329 gst_caps_set_simple (caps, "multistream", G_TYPE_BOOLEAN, multistream,
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_ACM)) {
5335 gst_riff_strf_auds auds;
5337 if (data && size >= 18) {
5338 GstBuffer *codec_data = NULL;
5340 /* little-endian -> byte-order */
5341 auds.format = GST_READ_UINT16_LE (data);
5342 auds.channels = GST_READ_UINT16_LE (data + 2);
5343 auds.rate = GST_READ_UINT32_LE (data + 4);
5344 auds.av_bps = GST_READ_UINT32_LE (data + 8);
5345 auds.blockalign = GST_READ_UINT16_LE (data + 12);
5346 auds.bits_per_sample = GST_READ_UINT16_LE (data + 16);
5348 /* 18 is the waveformatex size */
5350 codec_data = gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY,
5351 data + 18, size - 18, 0, size - 18, NULL, NULL);
5355 *riff_audio_fmt = auds.format;
5357 /* FIXME: Handle reorder map */
5358 caps = gst_riff_create_audio_caps (auds.format, NULL, &auds, NULL,
5359 codec_data, codec_name, NULL);
5361 gst_buffer_unref (codec_data);
5364 GST_WARNING ("Unhandled RIFF audio format 0x%02x", auds.format);
5367 GST_WARNING ("Invalid codec data size (%d expected, got %d)", 18, size);
5369 } else if (g_str_has_prefix (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC)) {
5370 GstBuffer *priv = NULL;
5372 gint rate_idx, profile;
5373 guint8 *data = NULL;
5375 /* unspecified AAC profile with opaque private codec data */
5376 if (strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC) == 0) {
5377 if (context->codec_priv_size >= 2) {
5378 guint obj_type, freq_index, explicit_freq_bytes = 0;
5380 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
5382 freq_index = (GST_READ_UINT16_BE (context->codec_priv) & 0x780) >> 7;
5383 obj_type = (GST_READ_UINT16_BE (context->codec_priv) & 0xF800) >> 11;
5384 if (freq_index == 15)
5385 explicit_freq_bytes = 3;
5386 GST_DEBUG ("obj_type = %u, freq_index = %u", obj_type, freq_index);
5387 priv = gst_buffer_new_wrapped (g_memdup (context->codec_priv,
5388 context->codec_priv_size), context->codec_priv_size);
5389 /* assume SBR if samplerate <= 24kHz */
5390 if (obj_type == 5 || (freq_index >= 6 && freq_index != 15) ||
5391 (context->codec_priv_size == (5 + explicit_freq_bytes))) {
5392 audiocontext->samplerate *= 2;
5395 GST_WARNING ("Opaque A_AAC codec ID, but no codec private data");
5396 /* this is pretty broken;
5397 * maybe we need to make up some default private,
5398 * or maybe ADTS data got dumped in.
5399 * Let's set up some private data now, and check actual data later */
5400 /* just try this and see what happens ... */
5401 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
5402 context->postprocess_frame = gst_matroska_demux_check_aac;
5406 /* make up decoder-specific data if it is not supplied */
5410 priv = gst_buffer_new_allocate (NULL, 5, NULL);
5411 gst_buffer_map (priv, &map, GST_MAP_WRITE);
5413 rate_idx = aac_rate_idx (audiocontext->samplerate);
5414 profile = aac_profile_idx (codec_id);
5416 data[0] = ((profile + 1) << 3) | ((rate_idx & 0xE) >> 1);
5417 data[1] = ((rate_idx & 0x1) << 7) | (audiocontext->channels << 3);
5419 if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2,
5420 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2))) {
5422 gst_buffer_unmap (priv, &map);
5423 gst_buffer_set_size (priv, 2);
5424 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4,
5425 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4))) {
5428 if (g_strrstr (codec_id, "SBR")) {
5429 /* HE-AAC (aka SBR AAC) */
5430 audiocontext->samplerate *= 2;
5431 rate_idx = aac_rate_idx (audiocontext->samplerate);
5432 data[2] = AAC_SYNC_EXTENSION_TYPE >> 3;
5433 data[3] = ((AAC_SYNC_EXTENSION_TYPE & 0x07) << 5) | 5;
5434 data[4] = (1 << 7) | (rate_idx << 3);
5435 gst_buffer_unmap (priv, &map);
5437 gst_buffer_unmap (priv, &map);
5438 gst_buffer_set_size (priv, 2);
5441 gst_buffer_unmap (priv, &map);
5442 gst_buffer_unref (priv);
5444 GST_ERROR ("Unknown AAC profile and no codec private data");
5449 caps = gst_caps_new_simple ("audio/mpeg",
5450 "mpegversion", G_TYPE_INT, mpegversion,
5451 "framed", G_TYPE_BOOLEAN, TRUE,
5452 "stream-format", G_TYPE_STRING, "raw", NULL);
5453 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5454 if (context->codec_priv && context->codec_priv_size > 0)
5455 gst_codec_utils_aac_caps_set_level_and_profile (caps,
5456 context->codec_priv, context->codec_priv_size);
5457 *codec_name = g_strdup_printf ("MPEG-%d AAC audio", mpegversion);
5458 gst_buffer_unref (priv);
5460 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TTA)) {
5461 caps = gst_caps_new_simple ("audio/x-tta",
5462 "width", G_TYPE_INT, audiocontext->bitdepth, NULL);
5463 *codec_name = g_strdup ("TTA audio");
5464 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_WAVPACK4)) {
5465 caps = gst_caps_new_simple ("audio/x-wavpack",
5466 "width", G_TYPE_INT, audiocontext->bitdepth,
5467 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5468 *codec_name = g_strdup ("Wavpack audio");
5469 context->postprocess_frame = gst_matroska_demux_add_wvpk_header;
5470 audiocontext->wvpk_block_index = 0;
5471 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4)) ||
5472 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_28_8)) ||
5473 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))) {
5474 gint raversion = -1;
5476 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4))
5478 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))
5483 caps = gst_caps_new_simple ("audio/x-pn-realaudio",
5484 "raversion", G_TYPE_INT, raversion, NULL);
5485 /* Extract extra information from caps, mapping varies based on codec */
5486 if (data && (size >= 0x50)) {
5493 guint extra_data_size;
5495 GST_ERROR ("real audio raversion:%d", raversion);
5496 if (raversion == 8) {
5498 flavor = GST_READ_UINT16_BE (data + 22);
5499 packet_size = GST_READ_UINT32_BE (data + 24);
5500 height = GST_READ_UINT16_BE (data + 40);
5501 leaf_size = GST_READ_UINT16_BE (data + 44);
5502 sample_width = GST_READ_UINT16_BE (data + 58);
5503 extra_data_size = GST_READ_UINT32_BE (data + 74);
5506 ("flavor:%d, packet_size:%d, height:%d, leaf_size:%d, sample_width:%d, extra_data_size:%d",
5507 flavor, packet_size, height, leaf_size, sample_width,
5509 gst_caps_set_simple (caps, "flavor", G_TYPE_INT, flavor, "packet_size",
5510 G_TYPE_INT, packet_size, "height", G_TYPE_INT, height, "leaf_size",
5511 G_TYPE_INT, leaf_size, "width", G_TYPE_INT, sample_width, NULL);
5513 if ((size - 78) >= extra_data_size) {
5514 priv = gst_buffer_new_wrapped (g_memdup (data + 78, extra_data_size),
5516 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5517 gst_buffer_unref (priv);
5522 *codec_name = g_strdup_printf ("RealAudio %d.0", raversion);
5523 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_SIPR)) {
5524 caps = gst_caps_new_empty_simple ("audio/x-sipro");
5525 *codec_name = g_strdup ("Sipro/ACELP.NET Voice Codec");
5526 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_RALF)) {
5527 caps = gst_caps_new_empty_simple ("audio/x-ralf-mpeg4-generic");
5528 *codec_name = g_strdup ("Real Audio Lossless");
5529 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_ATRC)) {
5530 caps = gst_caps_new_empty_simple ("audio/x-vnd.sony.atrac3");
5531 *codec_name = g_strdup ("Sony ATRAC3");
5533 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
5538 if (audiocontext->samplerate > 0 && audiocontext->channels > 0) {
5541 for (i = 0; i < gst_caps_get_size (caps); i++) {
5542 gst_structure_set (gst_caps_get_structure (caps, i),
5543 "channels", G_TYPE_INT, audiocontext->channels,
5544 "rate", G_TYPE_INT, audiocontext->samplerate, NULL);
5548 caps = gst_caps_simplify (caps);
5555 gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
5556 subtitlecontext, const gchar * codec_id, gpointer data, guint size)
5558 GstCaps *caps = NULL;
5559 GstMatroskaTrackContext *context =
5560 (GstMatroskaTrackContext *) subtitlecontext;
5562 /* for backwards compatibility */
5563 if (!g_ascii_strcasecmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASCII))
5564 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8;
5565 else if (!g_ascii_strcasecmp (codec_id, "S_SSA"))
5566 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_SSA;
5567 else if (!g_ascii_strcasecmp (codec_id, "S_ASS"))
5568 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_ASS;
5569 else if (!g_ascii_strcasecmp (codec_id, "S_USF"))
5570 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_USF;
5572 /* TODO: Add GST_MATROSKA_CODEC_ID_SUBTITLE_BMP support
5573 * Check if we have to do something with codec_private */
5574 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8)) {
5575 /* well, plain text simply does not have a lot of markup ... */
5576 caps = gst_caps_new_simple ("text/x-raw", "format", G_TYPE_STRING,
5577 "pango-markup", NULL);
5578 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5579 subtitlecontext->check_markup = TRUE;
5580 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_SSA)) {
5581 caps = gst_caps_new_empty_simple ("application/x-ssa");
5582 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5583 subtitlecontext->check_markup = FALSE;
5584 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASS)) {
5585 caps = gst_caps_new_empty_simple ("application/x-ass");
5586 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5587 subtitlecontext->check_markup = FALSE;
5588 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_USF)) {
5589 caps = gst_caps_new_empty_simple ("application/x-usf");
5590 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5591 subtitlecontext->check_markup = FALSE;
5592 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB)) {
5593 caps = gst_caps_new_empty_simple ("subpicture/x-dvd");
5594 ((GstMatroskaTrackContext *) subtitlecontext)->send_dvd_event = TRUE;
5595 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_HDMVPGS)) {
5596 caps = gst_caps_new_empty_simple ("subpicture/x-pgs");
5597 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_KATE)) {
5598 caps = gst_caps_new_empty_simple ("subtitle/x-kate");
5599 context->stream_headers =
5600 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
5601 context->codec_priv_size);
5602 /* FIXME: mark stream as broken and skip if there are no stream headers */
5603 context->send_stream_headers = TRUE;
5605 GST_DEBUG ("Unknown subtitle stream: codec_id='%s'", codec_id);
5606 caps = gst_caps_new_empty_simple ("application/x-subtitle-unknown");
5609 if (data != NULL && size > 0) {
5612 buf = gst_buffer_new_wrapped (g_memdup (data, size), size);
5613 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, buf, NULL);
5614 gst_buffer_unref (buf);
5622 gst_matroska_demux_set_index (GstElement * element, GstIndex * index)
5624 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5626 GST_OBJECT_LOCK (demux);
5627 if (demux->common.element_index)
5628 gst_object_unref (demux->common.element_index);
5629 demux->common.element_index = index ? gst_object_ref (index) : NULL;
5630 GST_OBJECT_UNLOCK (demux);
5631 GST_DEBUG_OBJECT (demux, "Set index %" GST_PTR_FORMAT,
5632 demux->common.element_index);
5636 gst_matroska_demux_get_index (GstElement * element)
5638 GstIndex *result = NULL;
5639 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5641 GST_OBJECT_LOCK (demux);
5642 if (demux->common.element_index)
5643 result = gst_object_ref (demux->common.element_index);
5644 GST_OBJECT_UNLOCK (demux);
5646 GST_DEBUG_OBJECT (demux, "Returning index %" GST_PTR_FORMAT, result);
5652 static GstStateChangeReturn
5653 gst_matroska_demux_change_state (GstElement * element,
5654 GstStateChange transition)
5656 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5657 GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
5659 /* handle upwards state changes here */
5660 switch (transition) {
5665 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
5667 /* handle downwards state changes */
5668 switch (transition) {
5669 case GST_STATE_CHANGE_PAUSED_TO_READY:
5670 gst_matroska_demux_reset (GST_ELEMENT (demux));
5680 gst_matroska_demux_set_property (GObject * object,
5681 guint prop_id, const GValue * value, GParamSpec * pspec)
5683 GstMatroskaDemux *demux;
5685 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
5686 demux = GST_MATROSKA_DEMUX (object);
5689 case ARG_MAX_GAP_TIME:
5690 GST_OBJECT_LOCK (demux);
5691 demux->max_gap_time = g_value_get_uint64 (value);
5692 GST_OBJECT_UNLOCK (demux);
5695 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
5701 gst_matroska_demux_get_property (GObject * object,
5702 guint prop_id, GValue * value, GParamSpec * pspec)
5704 GstMatroskaDemux *demux;
5706 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
5707 demux = GST_MATROSKA_DEMUX (object);
5710 case ARG_MAX_GAP_TIME:
5711 GST_OBJECT_LOCK (demux);
5712 g_value_set_uint64 (value, demux->max_gap_time);
5713 GST_OBJECT_UNLOCK (demux);
5716 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
5722 gst_matroska_demux_plugin_init (GstPlugin * plugin)
5726 /* parser helper separate debug */
5727 GST_DEBUG_CATEGORY_INIT (ebmlread_debug, "ebmlread",
5728 0, "EBML stream helper class");
5730 /* create an elementfactory for the matroska_demux element */
5731 if (!gst_element_register (plugin, "matroskademux",
5732 GST_RANK_PRIMARY, GST_TYPE_MATROSKA_DEMUX))