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., 59 Temple Place - Suite 330,
22 * Boston, MA 02111-1307, 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 -v filesrc location=/path/to/mkv ! matroskademux ! vorbisdec ! audioconvert ! audioresample ! autoaudiosink
43 * ]| This pipeline demuxes a Matroska file and outputs the contained Vorbis audio.
52 /* FIXME 0.11: suppress warnings for deprecated API such as GStaticRecMutex
53 * with newer GLib versions (>= 2.31.0) */
54 #define GLIB_DISABLE_DEPRECATION_WARNINGS
58 #include <glib/gprintf.h>
60 /* For AVI compatibility mode
61 and for fourcc stuff */
62 #include <gst/riff/riff-read.h>
63 #include <gst/riff/riff-ids.h>
64 #include <gst/riff/riff-media.h>
66 #include <gst/tag/tag.h>
68 #include <gst/pbutils/pbutils.h>
70 #include "matroska-demux.h"
71 #include "matroska-ids.h"
73 GST_DEBUG_CATEGORY_STATIC (matroskademux_debug);
74 #define GST_CAT_DEFAULT matroskademux_debug
76 #define DEBUG_ELEMENT_START(demux, ebml, element) \
77 GST_DEBUG_OBJECT (demux, "Parsing " element " element at offset %" \
78 G_GUINT64_FORMAT, gst_ebml_read_get_pos (ebml))
80 #define DEBUG_ELEMENT_STOP(demux, ebml, element, ret) \
81 GST_DEBUG_OBJECT (demux, "Parsing " element " element " \
82 " finished with '%s'", gst_flow_get_name (ret))
92 #define DEFAULT_MAX_GAP_TIME (2 * GST_SECOND)
94 static GstStaticPadTemplate sink_templ = GST_STATIC_PAD_TEMPLATE ("sink",
97 GST_STATIC_CAPS ("video/x-matroska; video/webm")
100 /* TODO: fill in caps! */
102 static GstStaticPadTemplate audio_src_templ =
103 GST_STATIC_PAD_TEMPLATE ("audio_%02d",
106 GST_STATIC_CAPS ("ANY")
109 static GstStaticPadTemplate video_src_templ =
110 GST_STATIC_PAD_TEMPLATE ("video_%02d",
113 GST_STATIC_CAPS ("ANY")
116 static GstStaticPadTemplate subtitle_src_templ =
117 GST_STATIC_PAD_TEMPLATE ("subtitle_%02d",
120 GST_STATIC_CAPS ("text/x-pango-markup; application/x-ssa; "
121 "application/x-ass;application/x-usf; video/x-dvd-subpicture; "
122 "subpicture/x-pgs; subtitle/x-kate; " "application/x-subtitle-unknown")
125 static GstFlowReturn gst_matroska_demux_parse_id (GstMatroskaDemux * demux,
126 guint32 id, guint64 length, guint needed);
128 /* element functions */
129 static void gst_matroska_demux_loop (GstPad * pad);
131 static gboolean gst_matroska_demux_element_send_event (GstElement * element,
133 static gboolean gst_matroska_demux_element_query (GstElement * element,
137 static gboolean gst_matroska_demux_sink_activate_pull (GstPad * sinkpad,
139 static gboolean gst_matroska_demux_sink_activate (GstPad * sinkpad);
141 static gboolean gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
142 GstPad * pad, GstEvent * event);
143 static gboolean gst_matroska_demux_handle_src_event (GstPad * pad,
145 static const GstQueryType *gst_matroska_demux_get_src_query_types (GstPad *
147 static gboolean gst_matroska_demux_handle_src_query (GstPad * pad,
150 static gboolean gst_matroska_demux_handle_sink_event (GstPad * pad,
152 static GstFlowReturn gst_matroska_demux_chain (GstPad * pad,
155 static GstStateChangeReturn
156 gst_matroska_demux_change_state (GstElement * element,
157 GstStateChange transition);
159 gst_matroska_demux_set_index (GstElement * element, GstIndex * index);
160 static GstIndex *gst_matroska_demux_get_index (GstElement * element);
163 static GstCaps *gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext
164 * videocontext, const gchar * codec_id, guint8 * data, guint size,
165 gchar ** codec_name, guint32 * riff_fourcc);
166 static GstCaps *gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext
167 * audiocontext, const gchar * codec_id, guint8 * data, guint size,
168 gchar ** codec_name, guint16 * riff_audio_fmt);
170 * gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
171 subtitlecontext, const gchar * codec_id, gpointer data, guint size);
174 static void gst_matroska_demux_reset (GstElement * element);
175 static gboolean perform_seek_to_offset (GstMatroskaDemux * demux,
178 /* gobject functions */
179 static void gst_matroska_demux_set_property (GObject * object,
180 guint prop_id, const GValue * value, GParamSpec * pspec);
181 static void gst_matroska_demux_get_property (GObject * object,
182 guint prop_id, GValue * value, GParamSpec * pspec);
184 #ifdef MKV_DEMUX_MODIFICATION
185 static GstMatroskaIndex *gst_matroska_demux_get_next_index (GstMatroskaDemux * demux, GstMatroskaTrackContext * track, GstMatroskaIndex *entry);
186 static GstFlowReturn gst_matroska_demux_trickplay_find_tracks (GstMatroskaDemux * demux);
187 static GstFlowReturn gst_matroska_demux_trickplay_parse_id (GstMatroskaDemux * demux, guint32 id, guint64 length, guint needed);
188 static GstFlowReturn gst_matroska_demux_trickplay_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux, GstEbmlRead * ebml, guint64 cluster_time, guint64 cluster_offset, gboolean is_simpleblock);
189 static gint32 gst_matroska_demux_trickplay_nframes2show_bw_keyframes (GstMatroskaDemux* demux, GstMatroskaTrackContext * stream);
190 static GstFlowReturn gst_matroska_demux_backward_trickplay (GstMatroskaDemux* demux, GstMatroskaTrackContext * stream, GstBuffer* sub);
191 static GstFlowReturn gst_matroska_demux_forward_trickplay (GstMatroskaDemux* demux, GstMatroskaTrackContext * stream, GstBuffer *buffer, gboolean *skip);
194 GType gst_matroska_demux_get_type (void);
195 GST_BOILERPLATE (GstMatroskaDemux, gst_matroska_demux, GstElement,
199 gst_matroska_demux_base_init (gpointer klass)
201 GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
203 gst_element_class_add_static_pad_template (element_class, &video_src_templ);
204 gst_element_class_add_static_pad_template (element_class, &audio_src_templ);
205 gst_element_class_add_static_pad_template (element_class,
206 &subtitle_src_templ);
207 gst_element_class_add_static_pad_template (element_class, &sink_templ);
209 gst_element_class_set_details_simple (element_class, "Matroska demuxer",
211 "Demuxes Matroska/WebM streams into video/audio/subtitles",
212 "GStreamer maintainers <gstreamer-devel@lists.sourceforge.net>");
216 gst_matroska_demux_finalize (GObject * object)
218 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (object);
220 if (demux->common.src) {
221 g_ptr_array_free (demux->common.src, TRUE);
222 demux->common.src = NULL;
225 if (demux->common.global_tags) {
226 gst_tag_list_free (demux->common.global_tags);
227 demux->common.global_tags = NULL;
230 g_object_unref (demux->common.adapter);
232 G_OBJECT_CLASS (parent_class)->finalize (object);
236 gst_matroska_demux_class_init (GstMatroskaDemuxClass * klass)
238 GObjectClass *gobject_class = (GObjectClass *) klass;
239 GstElementClass *gstelement_class = (GstElementClass *) klass;
241 GST_DEBUG_CATEGORY_INIT (matroskademux_debug, "matroskademux", 0,
244 gobject_class->finalize = gst_matroska_demux_finalize;
246 gobject_class->get_property = gst_matroska_demux_get_property;
247 gobject_class->set_property = gst_matroska_demux_set_property;
249 g_object_class_install_property (gobject_class, ARG_MAX_GAP_TIME,
250 g_param_spec_uint64 ("max-gap-time", "Maximum gap time",
251 "The demuxer sends out newsegment events for skipping "
252 "gaps longer than this (0 = disabled).", 0, G_MAXUINT64,
253 DEFAULT_MAX_GAP_TIME, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
255 gstelement_class->change_state =
256 GST_DEBUG_FUNCPTR (gst_matroska_demux_change_state);
257 gstelement_class->send_event =
258 GST_DEBUG_FUNCPTR (gst_matroska_demux_element_send_event);
259 gstelement_class->query =
260 GST_DEBUG_FUNCPTR (gst_matroska_demux_element_query);
262 gstelement_class->set_index =
263 GST_DEBUG_FUNCPTR (gst_matroska_demux_set_index);
264 gstelement_class->get_index =
265 GST_DEBUG_FUNCPTR (gst_matroska_demux_get_index);
269 gst_matroska_demux_init (GstMatroskaDemux * demux,
270 GstMatroskaDemuxClass * klass)
272 demux->common.sinkpad = gst_pad_new_from_static_template (&sink_templ,
274 gst_pad_set_activate_function (demux->common.sinkpad,
275 GST_DEBUG_FUNCPTR (gst_matroska_demux_sink_activate));
276 gst_pad_set_activatepull_function (demux->common.sinkpad,
277 GST_DEBUG_FUNCPTR (gst_matroska_demux_sink_activate_pull));
278 gst_pad_set_chain_function (demux->common.sinkpad,
279 GST_DEBUG_FUNCPTR (gst_matroska_demux_chain));
280 gst_pad_set_event_function (demux->common.sinkpad,
281 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_sink_event));
282 gst_element_add_pad (GST_ELEMENT (demux), demux->common.sinkpad);
284 /* initial stream no. */
285 demux->common.src = NULL;
287 demux->common.writing_app = NULL;
288 demux->common.muxing_app = NULL;
289 demux->common.index = NULL;
290 demux->common.global_tags = NULL;
292 demux->common.adapter = gst_adapter_new ();
294 #ifdef MKV_DEMUX_MODIFICATION
295 demux->found_videokeyframe = FALSE;
296 demux->found_audioframe = FALSE;
297 demux->is_eos_blockgroup = FALSE;
298 demux->is_eos_simpleblock = FALSE;
299 demux->video_keyframe_pushed = FALSE;
302 /* property defaults */
303 demux->max_gap_time = DEFAULT_MAX_GAP_TIME;
306 gst_matroska_demux_reset (GST_ELEMENT (demux));
310 gst_matroska_track_free (GstMatroskaTrackContext * track)
312 g_free (track->codec_id);
313 g_free (track->codec_name);
314 g_free (track->name);
315 g_free (track->language);
316 g_free (track->codec_priv);
317 g_free (track->codec_state);
319 #ifdef MKV_DEMUX_MODIFICATION
320 while (!g_queue_is_empty (track->queue)) {
321 GstBuffer* buf = g_queue_pop_head (track->queue);
322 gst_buffer_unref (buf);
324 g_queue_free (track->queue);
327 if (track->encodings != NULL) {
330 for (i = 0; i < track->encodings->len; ++i) {
331 GstMatroskaTrackEncoding *enc = &g_array_index (track->encodings,
332 GstMatroskaTrackEncoding,
335 g_free (enc->comp_settings);
337 g_array_free (track->encodings, TRUE);
340 if (track->pending_tags)
341 gst_tag_list_free (track->pending_tags);
343 if (track->index_table)
344 g_array_free (track->index_table, TRUE);
350 * Returns the aggregated GstFlowReturn.
353 gst_matroska_demux_combine_flows (GstMatroskaDemux * demux,
354 GstMatroskaTrackContext * track, GstFlowReturn ret)
358 /* store the value */
359 track->last_flow = ret;
361 /* any other error that is not-linked can be returned right away */
362 if (ret != GST_FLOW_NOT_LINKED)
365 /* only return NOT_LINKED if all other pads returned NOT_LINKED */
366 g_assert (demux->common.src->len == demux->common.num_streams);
367 for (i = 0; i < demux->common.src->len; i++) {
368 GstMatroskaTrackContext *ostream = g_ptr_array_index (demux->common.src,
374 ret = ostream->last_flow;
375 /* some other return value (must be SUCCESS but we can return
376 * other values as well) */
377 if (ret != GST_FLOW_NOT_LINKED)
380 /* if we get here, all other pads were unlinked and we return
383 GST_LOG_OBJECT (demux, "combined return %s", gst_flow_get_name (ret));
388 gst_matroska_demux_free_parsed_el (gpointer mem, gpointer user_data)
390 g_slice_free (guint64, mem);
394 gst_matroska_demux_reset (GstElement * element)
396 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
399 GST_DEBUG_OBJECT (demux, "Resetting state");
402 demux->common.state = GST_MATROSKA_READ_STATE_START;
404 /* clean up existing streams */
405 if (demux->common.src) {
406 g_assert (demux->common.src->len == demux->common.num_streams);
407 for (i = 0; i < demux->common.src->len; i++) {
408 GstMatroskaTrackContext *context = g_ptr_array_index (demux->common.src,
411 if (context->pad != NULL)
412 gst_element_remove_pad (GST_ELEMENT (demux), context->pad);
414 gst_caps_replace (&context->caps, NULL);
415 gst_matroska_track_free (context);
417 g_ptr_array_free (demux->common.src, TRUE);
419 demux->common.src = g_ptr_array_new ();
421 demux->common.num_streams = 0;
422 demux->num_a_streams = 0;
423 demux->num_t_streams = 0;
424 demux->num_v_streams = 0;
426 /* reset media info */
427 g_free (demux->common.writing_app);
428 demux->common.writing_app = NULL;
429 g_free (demux->common.muxing_app);
430 demux->common.muxing_app = NULL;
433 if (demux->common.index) {
434 g_array_free (demux->common.index, TRUE);
435 demux->common.index = NULL;
438 if (demux->clusters) {
439 g_array_free (demux->clusters, TRUE);
440 demux->clusters = NULL;
445 demux->common.time_scale = 1000000;
446 demux->common.created = G_MININT64;
448 demux->common.index_parsed = FALSE;
449 demux->tracks_parsed = FALSE;
450 demux->common.segmentinfo_parsed = FALSE;
451 demux->common.attachments_parsed = FALSE;
453 g_list_foreach (demux->common.tags_parsed,
454 (GFunc) gst_matroska_demux_free_parsed_el, NULL);
455 g_list_free (demux->common.tags_parsed);
456 demux->common.tags_parsed = NULL;
458 g_list_foreach (demux->seek_parsed,
459 (GFunc) gst_matroska_demux_free_parsed_el, NULL);
460 g_list_free (demux->seek_parsed);
461 demux->seek_parsed = NULL;
463 gst_segment_init (&demux->common.segment, GST_FORMAT_TIME);
464 demux->last_stop_end = GST_CLOCK_TIME_NONE;
465 demux->seek_block = 0;
466 demux->stream_start_time = GST_CLOCK_TIME_NONE;
468 demux->common.offset = 0;
469 demux->cluster_time = GST_CLOCK_TIME_NONE;
470 demux->cluster_offset = 0;
471 demux->next_cluster_offset = 0;
472 demux->index_offset = 0;
473 demux->seekable = FALSE;
474 demux->need_newsegment = FALSE;
475 demux->building_index = FALSE;
476 if (demux->seek_event) {
477 gst_event_unref (demux->seek_event);
478 demux->seek_event = NULL;
481 demux->seek_index = NULL;
482 demux->seek_entry = 0;
484 if (demux->close_segment) {
485 gst_event_unref (demux->close_segment);
486 demux->close_segment = NULL;
489 if (demux->new_segment) {
490 gst_event_unref (demux->new_segment);
491 demux->new_segment = NULL;
494 if (demux->common.element_index) {
495 gst_object_unref (demux->common.element_index);
496 demux->common.element_index = NULL;
498 demux->common.element_index_writer_id = -1;
500 if (demux->common.global_tags) {
501 gst_tag_list_free (demux->common.global_tags);
503 demux->common.global_tags = gst_tag_list_new ();
505 if (demux->common.cached_buffer) {
506 gst_buffer_unref (demux->common.cached_buffer);
507 demux->common.cached_buffer = NULL;
510 demux->invalid_duration = FALSE;
514 gst_matroska_decode_buffer (GstMatroskaTrackContext * context, GstBuffer * buf)
520 g_return_val_if_fail (GST_IS_BUFFER (buf), NULL);
522 GST_DEBUG ("decoding buffer %p", buf);
524 data = GST_BUFFER_DATA (buf);
525 size = GST_BUFFER_SIZE (buf);
527 g_return_val_if_fail (data != NULL && size > 0, buf);
529 if (gst_matroska_decode_data (context->encodings, &data, &size,
530 GST_MATROSKA_TRACK_ENCODING_SCOPE_FRAME, FALSE)) {
531 new_buf = gst_buffer_new ();
532 GST_BUFFER_MALLOCDATA (new_buf) = (guint8 *) data;
533 GST_BUFFER_DATA (new_buf) = (guint8 *) data;
534 GST_BUFFER_SIZE (new_buf) = size;
536 gst_buffer_unref (buf);
541 GST_DEBUG ("decode data failed");
542 gst_buffer_unref (buf);
548 gst_matroska_demux_add_stream (GstMatroskaDemux * demux, GstEbmlRead * ebml)
550 GstElementClass *klass = GST_ELEMENT_GET_CLASS (demux);
551 GstMatroskaTrackContext *context;
552 GstPadTemplate *templ = NULL;
553 GstCaps *caps = NULL;
554 gchar *padname = NULL;
556 guint32 id, riff_fourcc = 0;
557 guint16 riff_audio_fmt = 0;
558 GstTagList *list = NULL;
561 DEBUG_ELEMENT_START (demux, ebml, "TrackEntry");
563 /* start with the master */
564 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
565 DEBUG_ELEMENT_STOP (demux, ebml, "TrackEntry", ret);
569 /* allocate generic... if we know the type, we'll g_renew()
570 * with the precise type */
571 context = g_new0 (GstMatroskaTrackContext, 1);
572 g_ptr_array_add (demux->common.src, context);
573 context->index = demux->common.num_streams;
574 context->index_writer_id = -1;
575 context->type = 0; /* no type yet */
576 context->default_duration = 0;
578 #ifdef MKV_DEMUX_MODIFICATION
579 context->found_next_kframe = FALSE;
581 context->set_discont = TRUE;
582 context->timecodescale = 1.0;
584 GST_MATROSKA_TRACK_ENABLED | GST_MATROSKA_TRACK_DEFAULT |
585 GST_MATROSKA_TRACK_LACING;
586 context->last_flow = GST_FLOW_OK;
587 context->to_offset = G_MAXINT64;
588 context->alignment = 1;
589 demux->common.num_streams++;
590 g_assert (demux->common.src->len == demux->common.num_streams);
592 #ifdef MKV_DEMUX_MODIFICATION
593 context->queue = g_queue_new ();
594 // context->found_key_frame = FALSE;
595 context->last_ts = GST_CLOCK_TIME_NONE;
596 // context->avg_duration = GST_CLOCK_TIME_NONE;
597 // context->intra_gap = 0;
600 GST_DEBUG_OBJECT (demux, "Stream number %d", context->index);
602 /* try reading the trackentry headers */
603 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
604 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
608 /* track number (unique stream ID) */
609 case GST_MATROSKA_ID_TRACKNUMBER:{
612 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
616 GST_ERROR_OBJECT (demux, "Invalid TrackNumber 0");
617 ret = GST_FLOW_ERROR;
619 } else if (!gst_matroska_read_common_tracknumber_unique (&demux->common,
621 GST_ERROR_OBJECT (demux, "TrackNumber %" G_GUINT64_FORMAT
622 " is not unique", num);
623 ret = GST_FLOW_ERROR;
627 GST_DEBUG_OBJECT (demux, "TrackNumber: %" G_GUINT64_FORMAT, num);
631 /* track UID (unique identifier) */
632 case GST_MATROSKA_ID_TRACKUID:{
635 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
639 GST_ERROR_OBJECT (demux, "Invalid TrackUID 0");
640 ret = GST_FLOW_ERROR;
644 GST_DEBUG_OBJECT (demux, "TrackUID: %" G_GUINT64_FORMAT, num);
649 /* track type (video, audio, combined, subtitle, etc.) */
650 case GST_MATROSKA_ID_TRACKTYPE:{
653 if ((ret = gst_ebml_read_uint (ebml, &id, &track_type)) != GST_FLOW_OK) {
657 if (context->type != 0 && context->type != track_type) {
658 GST_WARNING_OBJECT (demux,
659 "More than one tracktype defined in a TrackEntry - skipping");
661 } else if (track_type < 1 || track_type > 254) {
662 GST_WARNING_OBJECT (demux, "Invalid TrackType %" G_GUINT64_FORMAT,
667 GST_DEBUG_OBJECT (demux, "TrackType: %" G_GUINT64_FORMAT, track_type);
669 /* ok, so we're actually going to reallocate this thing */
670 switch (track_type) {
671 case GST_MATROSKA_TRACK_TYPE_VIDEO:
672 gst_matroska_track_init_video_context (&context);
674 case GST_MATROSKA_TRACK_TYPE_AUDIO:
675 gst_matroska_track_init_audio_context (&context);
677 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
678 gst_matroska_track_init_subtitle_context (&context);
680 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
681 case GST_MATROSKA_TRACK_TYPE_LOGO:
682 case GST_MATROSKA_TRACK_TYPE_BUTTONS:
683 case GST_MATROSKA_TRACK_TYPE_CONTROL:
685 GST_WARNING_OBJECT (demux,
686 "Unknown or unsupported TrackType %" G_GUINT64_FORMAT,
691 g_ptr_array_index (demux->common.src, demux->common.num_streams - 1)
696 /* tracktype specific stuff for video */
697 case GST_MATROSKA_ID_TRACKVIDEO:{
698 GstMatroskaTrackVideoContext *videocontext;
700 DEBUG_ELEMENT_START (demux, ebml, "TrackVideo");
702 if (!gst_matroska_track_init_video_context (&context)) {
703 GST_WARNING_OBJECT (demux,
704 "TrackVideo element in non-video track - ignoring track");
705 ret = GST_FLOW_ERROR;
707 } else if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
710 videocontext = (GstMatroskaTrackVideoContext *) context;
711 g_ptr_array_index (demux->common.src, demux->common.num_streams - 1)
714 while (ret == GST_FLOW_OK &&
715 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
716 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
720 /* Should be one level up but some broken muxers write it here. */
721 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
724 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
728 GST_WARNING_OBJECT (demux, "Invalid TrackDefaultDuration 0");
732 GST_DEBUG_OBJECT (demux,
733 "TrackDefaultDuration: %" G_GUINT64_FORMAT, num);
734 context->default_duration = num;
738 /* video framerate */
739 /* NOTE: This one is here only for backward compatibility.
740 * Use _TRACKDEFAULDURATION one level up. */
741 case GST_MATROSKA_ID_VIDEOFRAMERATE:{
744 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
748 GST_WARNING_OBJECT (demux, "Invalid TrackVideoFPS %lf", num);
752 GST_DEBUG_OBJECT (demux, "TrackVideoFrameRate: %lf", num);
753 if (context->default_duration == 0)
754 context->default_duration =
755 gst_gdouble_to_guint64 ((gdouble) GST_SECOND * (1.0 / num));
756 videocontext->default_fps = num;
760 /* width of the size to display the video at */
761 case GST_MATROSKA_ID_VIDEODISPLAYWIDTH:{
764 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
768 GST_WARNING_OBJECT (demux, "Invalid TrackVideoDisplayWidth 0");
772 GST_DEBUG_OBJECT (demux,
773 "TrackVideoDisplayWidth: %" G_GUINT64_FORMAT, num);
774 videocontext->display_width = num;
778 /* height of the size to display the video at */
779 case GST_MATROSKA_ID_VIDEODISPLAYHEIGHT:{
782 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
786 GST_WARNING_OBJECT (demux, "Invalid TrackVideoDisplayHeight 0");
790 GST_DEBUG_OBJECT (demux,
791 "TrackVideoDisplayHeight: %" G_GUINT64_FORMAT, num);
792 videocontext->display_height = num;
796 /* width of the video in the file */
797 case GST_MATROSKA_ID_VIDEOPIXELWIDTH:{
800 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
804 GST_WARNING_OBJECT (demux, "Invalid TrackVideoPixelWidth 0");
808 GST_DEBUG_OBJECT (demux,
809 "TrackVideoPixelWidth: %" G_GUINT64_FORMAT, num);
810 videocontext->pixel_width = num;
814 /* height of the video in the file */
815 case GST_MATROSKA_ID_VIDEOPIXELHEIGHT:{
818 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
822 GST_WARNING_OBJECT (demux, "Invalid TrackVideoPixelHeight 0");
826 GST_DEBUG_OBJECT (demux,
827 "TrackVideoPixelHeight: %" G_GUINT64_FORMAT, num);
828 videocontext->pixel_height = num;
832 /* whether the video is interlaced */
833 case GST_MATROSKA_ID_VIDEOFLAGINTERLACED:{
836 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
840 context->flags |= GST_MATROSKA_VIDEOTRACK_INTERLACED;
842 context->flags &= ~GST_MATROSKA_VIDEOTRACK_INTERLACED;
843 GST_DEBUG_OBJECT (demux, "TrackVideoInterlaced: %d",
844 (context->flags & GST_MATROSKA_VIDEOTRACK_INTERLACED) ? 1 :
849 /* aspect ratio behaviour */
850 case GST_MATROSKA_ID_VIDEOASPECTRATIOTYPE:{
853 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
856 if (num != GST_MATROSKA_ASPECT_RATIO_MODE_FREE &&
857 num != GST_MATROSKA_ASPECT_RATIO_MODE_KEEP &&
858 num != GST_MATROSKA_ASPECT_RATIO_MODE_FIXED) {
859 GST_WARNING_OBJECT (demux,
860 "Unknown TrackVideoAspectRatioType 0x%x", (guint) num);
863 GST_DEBUG_OBJECT (demux,
864 "TrackVideoAspectRatioType: %" G_GUINT64_FORMAT, num);
865 videocontext->asr_mode = num;
869 /* colourspace (only matters for raw video) fourcc */
870 case GST_MATROSKA_ID_VIDEOCOLOURSPACE:{
875 gst_ebml_read_binary (ebml, &id, &data,
876 &datalen)) != GST_FLOW_OK)
881 GST_WARNING_OBJECT (demux,
882 "Invalid TrackVideoColourSpace length %" G_GUINT64_FORMAT,
887 memcpy (&videocontext->fourcc, data, 4);
888 GST_DEBUG_OBJECT (demux,
889 "TrackVideoColourSpace: %" GST_FOURCC_FORMAT,
890 GST_FOURCC_ARGS (videocontext->fourcc));
896 GST_WARNING_OBJECT (demux,
897 "Unknown TrackVideo subelement 0x%x - ignoring", id);
899 case GST_MATROSKA_ID_VIDEOSTEREOMODE:
900 case GST_MATROSKA_ID_VIDEODISPLAYUNIT:
901 case GST_MATROSKA_ID_VIDEOPIXELCROPBOTTOM:
902 case GST_MATROSKA_ID_VIDEOPIXELCROPTOP:
903 case GST_MATROSKA_ID_VIDEOPIXELCROPLEFT:
904 case GST_MATROSKA_ID_VIDEOPIXELCROPRIGHT:
905 case GST_MATROSKA_ID_VIDEOGAMMAVALUE:
906 ret = gst_ebml_read_skip (ebml);
911 DEBUG_ELEMENT_STOP (demux, ebml, "TrackVideo", ret);
915 /* tracktype specific stuff for audio */
916 case GST_MATROSKA_ID_TRACKAUDIO:{
917 GstMatroskaTrackAudioContext *audiocontext;
919 DEBUG_ELEMENT_START (demux, ebml, "TrackAudio");
921 if (!gst_matroska_track_init_audio_context (&context)) {
922 GST_WARNING_OBJECT (demux,
923 "TrackAudio element in non-audio track - ignoring track");
924 ret = GST_FLOW_ERROR;
928 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
931 audiocontext = (GstMatroskaTrackAudioContext *) context;
932 g_ptr_array_index (demux->common.src, demux->common.num_streams - 1)
935 while (ret == GST_FLOW_OK &&
936 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
937 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
942 case GST_MATROSKA_ID_AUDIOSAMPLINGFREQ:{
945 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
950 GST_WARNING_OBJECT (demux,
951 "Invalid TrackAudioSamplingFrequency %lf", num);
955 GST_DEBUG_OBJECT (demux, "TrackAudioSamplingFrequency: %lf", num);
956 audiocontext->samplerate = num;
961 case GST_MATROSKA_ID_AUDIOBITDEPTH:{
964 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
968 GST_WARNING_OBJECT (demux, "Invalid TrackAudioBitDepth 0");
972 GST_DEBUG_OBJECT (demux, "TrackAudioBitDepth: %" G_GUINT64_FORMAT,
974 audiocontext->bitdepth = num;
979 case GST_MATROSKA_ID_AUDIOCHANNELS:{
982 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
986 GST_WARNING_OBJECT (demux, "Invalid TrackAudioChannels 0");
990 GST_DEBUG_OBJECT (demux, "TrackAudioChannels: %" G_GUINT64_FORMAT,
992 audiocontext->channels = num;
997 GST_WARNING_OBJECT (demux,
998 "Unknown TrackAudio subelement 0x%x - ignoring", id);
1000 case GST_MATROSKA_ID_AUDIOCHANNELPOSITIONS:
1001 case GST_MATROSKA_ID_AUDIOOUTPUTSAMPLINGFREQ:
1002 ret = gst_ebml_read_skip (ebml);
1007 DEBUG_ELEMENT_STOP (demux, ebml, "TrackAudio", ret);
1012 /* codec identifier */
1013 case GST_MATROSKA_ID_CODECID:{
1016 if ((ret = gst_ebml_read_ascii (ebml, &id, &text)) != GST_FLOW_OK)
1019 GST_DEBUG_OBJECT (demux, "CodecID: %s", GST_STR_NULL (text));
1020 context->codec_id = text;
1024 /* codec private data */
1025 case GST_MATROSKA_ID_CODECPRIVATE:{
1030 gst_ebml_read_binary (ebml, &id, &data, &size)) != GST_FLOW_OK)
1033 context->codec_priv = data;
1034 context->codec_priv_size = size;
1036 GST_DEBUG_OBJECT (demux, "CodecPrivate of size %" G_GUINT64_FORMAT,
1041 /* name of the codec */
1042 case GST_MATROSKA_ID_CODECNAME:{
1045 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1048 GST_DEBUG_OBJECT (demux, "CodecName: %s", GST_STR_NULL (text));
1049 context->codec_name = text;
1053 /* name of this track */
1054 case GST_MATROSKA_ID_TRACKNAME:{
1057 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1060 context->name = text;
1061 GST_DEBUG_OBJECT (demux, "TrackName: %s", GST_STR_NULL (text));
1065 /* language (matters for audio/subtitles, mostly) */
1066 case GST_MATROSKA_ID_TRACKLANGUAGE:{
1069 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1073 context->language = text;
1076 if (strlen (context->language) >= 4 && context->language[3] == '-')
1077 context->language[3] = '\0';
1079 GST_DEBUG_OBJECT (demux, "TrackLanguage: %s",
1080 GST_STR_NULL (context->language));
1084 /* whether this is actually used */
1085 case GST_MATROSKA_ID_TRACKFLAGENABLED:{
1088 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1092 context->flags |= GST_MATROSKA_TRACK_ENABLED;
1094 context->flags &= ~GST_MATROSKA_TRACK_ENABLED;
1096 GST_DEBUG_OBJECT (demux, "TrackEnabled: %d",
1097 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
1101 /* whether it's the default for this track type */
1102 case GST_MATROSKA_ID_TRACKFLAGDEFAULT:{
1105 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1109 context->flags |= GST_MATROSKA_TRACK_DEFAULT;
1111 context->flags &= ~GST_MATROSKA_TRACK_DEFAULT;
1113 GST_DEBUG_OBJECT (demux, "TrackDefault: %d",
1114 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
1118 /* whether the track must be used during playback */
1119 case GST_MATROSKA_ID_TRACKFLAGFORCED:{
1122 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1126 context->flags |= GST_MATROSKA_TRACK_FORCED;
1128 context->flags &= ~GST_MATROSKA_TRACK_FORCED;
1130 GST_DEBUG_OBJECT (demux, "TrackForced: %d",
1131 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
1135 /* lacing (like MPEG, where blocks don't end/start on frame
1137 case GST_MATROSKA_ID_TRACKFLAGLACING:{
1140 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1144 context->flags |= GST_MATROSKA_TRACK_LACING;
1146 context->flags &= ~GST_MATROSKA_TRACK_LACING;
1148 GST_DEBUG_OBJECT (demux, "TrackLacing: %d",
1149 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
1153 /* default length (in time) of one data block in this track */
1154 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
1157 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1162 GST_WARNING_OBJECT (demux, "Invalid TrackDefaultDuration 0");
1166 GST_DEBUG_OBJECT (demux, "TrackDefaultDuration: %" G_GUINT64_FORMAT,
1168 context->default_duration = num;
1172 case GST_MATROSKA_ID_CONTENTENCODINGS:{
1173 ret = gst_matroska_read_common_read_track_encodings (&demux->common,
1178 case GST_MATROSKA_ID_TRACKTIMECODESCALE:{
1181 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
1185 GST_WARNING_OBJECT (demux, "Invalid TrackTimeCodeScale %lf", num);
1189 GST_DEBUG_OBJECT (demux, "TrackTimeCodeScale: %lf", num);
1190 context->timecodescale = num;
1195 GST_WARNING ("Unknown TrackEntry subelement 0x%x - ignoring", id);
1198 /* we ignore these because they're nothing useful (i.e. crap)
1199 * or simply not implemented yet. */
1200 case GST_MATROSKA_ID_TRACKMINCACHE:
1201 case GST_MATROSKA_ID_TRACKMAXCACHE:
1202 case GST_MATROSKA_ID_MAXBLOCKADDITIONID:
1203 case GST_MATROSKA_ID_TRACKATTACHMENTLINK:
1204 case GST_MATROSKA_ID_TRACKOVERLAY:
1205 case GST_MATROSKA_ID_TRACKTRANSLATE:
1206 case GST_MATROSKA_ID_TRACKOFFSET:
1207 case GST_MATROSKA_ID_CODECSETTINGS:
1208 case GST_MATROSKA_ID_CODECINFOURL:
1209 case GST_MATROSKA_ID_CODECDOWNLOADURL:
1210 case GST_MATROSKA_ID_CODECDECODEALL:
1211 ret = gst_ebml_read_skip (ebml);
1216 DEBUG_ELEMENT_STOP (demux, ebml, "TrackEntry", ret);
1218 /* Decode codec private data if necessary */
1219 if (context->encodings && context->encodings->len > 0 && context->codec_priv
1220 && context->codec_priv_size > 0) {
1221 if (!gst_matroska_decode_data (context->encodings,
1222 &context->codec_priv, &context->codec_priv_size,
1223 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
1224 GST_WARNING_OBJECT (demux, "Decoding codec private data failed");
1225 ret = GST_FLOW_ERROR;
1229 if (context->type == 0 || context->codec_id == NULL || (ret != GST_FLOW_OK
1230 && ret != GST_FLOW_UNEXPECTED)) {
1231 if (ret == GST_FLOW_OK || ret == GST_FLOW_UNEXPECTED)
1232 GST_WARNING_OBJECT (ebml, "Unknown stream/codec in track entry header");
1234 demux->common.num_streams--;
1235 g_ptr_array_remove_index (demux->common.src, demux->common.num_streams);
1236 g_assert (demux->common.src->len == demux->common.num_streams);
1238 gst_matroska_track_free (context);
1244 /* now create the GStreamer connectivity */
1245 switch (context->type) {
1246 case GST_MATROSKA_TRACK_TYPE_VIDEO:{
1247 GstMatroskaTrackVideoContext *videocontext =
1248 (GstMatroskaTrackVideoContext *) context;
1250 padname = g_strdup_printf ("video_%02d", demux->num_v_streams++);
1251 templ = gst_element_class_get_pad_template (klass, "video_%02d");
1252 caps = gst_matroska_demux_video_caps (videocontext,
1253 context->codec_id, (guint8 *) context->codec_priv,
1254 context->codec_priv_size, &codec, &riff_fourcc);
1257 list = gst_tag_list_new ();
1258 gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
1259 GST_TAG_VIDEO_CODEC, codec, NULL);
1265 case GST_MATROSKA_TRACK_TYPE_AUDIO:{
1266 GstMatroskaTrackAudioContext *audiocontext =
1267 (GstMatroskaTrackAudioContext *) context;
1269 padname = g_strdup_printf ("audio_%02d", demux->num_a_streams++);
1270 templ = gst_element_class_get_pad_template (klass, "audio_%02d");
1271 caps = gst_matroska_demux_audio_caps (audiocontext,
1272 context->codec_id, context->codec_priv, context->codec_priv_size,
1273 &codec, &riff_audio_fmt);
1276 list = gst_tag_list_new ();
1277 gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
1278 GST_TAG_AUDIO_CODEC, codec, NULL);
1284 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:{
1285 GstMatroskaTrackSubtitleContext *subtitlecontext =
1286 (GstMatroskaTrackSubtitleContext *) context;
1288 padname = g_strdup_printf ("subtitle_%02d", demux->num_t_streams++);
1289 templ = gst_element_class_get_pad_template (klass, "subtitle_%02d");
1290 caps = gst_matroska_demux_subtitle_caps (subtitlecontext,
1291 context->codec_id, context->codec_priv, context->codec_priv_size);
1295 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1296 case GST_MATROSKA_TRACK_TYPE_LOGO:
1297 case GST_MATROSKA_TRACK_TYPE_BUTTONS:
1298 case GST_MATROSKA_TRACK_TYPE_CONTROL:
1300 /* we should already have quit by now */
1301 g_assert_not_reached ();
1304 if ((context->language == NULL || *context->language == '\0') &&
1305 (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO ||
1306 context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
1307 GST_LOG ("stream %d: language=eng (assuming default)", context->index);
1308 context->language = g_strdup ("eng");
1311 if (context->language) {
1315 list = gst_tag_list_new ();
1317 /* Matroska contains ISO 639-2B codes, we want ISO 639-1 */
1318 lang = gst_tag_get_language_code (context->language);
1319 gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
1320 GST_TAG_LANGUAGE_CODE, (lang) ? lang : context->language, NULL);
1324 GST_WARNING_OBJECT (demux, "could not determine caps for stream with "
1325 "codec_id='%s'", context->codec_id);
1326 switch (context->type) {
1327 case GST_MATROSKA_TRACK_TYPE_VIDEO:
1328 caps = gst_caps_new_simple ("video/x-unknown", NULL);
1330 case GST_MATROSKA_TRACK_TYPE_AUDIO:
1331 caps = gst_caps_new_simple ("audio/x-unknown", NULL);
1333 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
1334 caps = gst_caps_new_simple ("application/x-subtitle-unknown", NULL);
1336 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1338 caps = gst_caps_new_simple ("application/x-matroska-unknown", NULL);
1341 gst_caps_set_simple (caps, "codec-id", G_TYPE_STRING, context->codec_id,
1344 /* add any unrecognised riff fourcc / audio format, but after codec-id */
1345 if (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO && riff_audio_fmt != 0)
1346 gst_caps_set_simple (caps, "format", G_TYPE_INT, riff_audio_fmt, NULL);
1347 else if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO && riff_fourcc != 0)
1348 gst_caps_set_simple (caps, "fourcc", GST_TYPE_FOURCC, riff_fourcc, NULL);
1351 /* the pad in here */
1352 context->pad = gst_pad_new_from_template (templ, padname);
1353 context->caps = caps;
1355 gst_pad_set_event_function (context->pad,
1356 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_event));
1357 gst_pad_set_query_type_function (context->pad,
1358 GST_DEBUG_FUNCPTR (gst_matroska_demux_get_src_query_types));
1359 gst_pad_set_query_function (context->pad,
1360 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_query));
1362 GST_INFO_OBJECT (demux, "Adding pad '%s' with caps %" GST_PTR_FORMAT,
1365 context->pending_tags = list;
1367 gst_pad_set_element_private (context->pad, context);
1369 gst_pad_use_fixed_caps (context->pad);
1370 gst_pad_set_caps (context->pad, context->caps);
1371 gst_pad_set_active (context->pad, TRUE);
1372 gst_element_add_pad (GST_ELEMENT (demux), context->pad);
1376 #ifdef MKV_DEMUX_MODIFICATION
1377 if (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO)
1378 demux->audio_stream = context;
1379 if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO)
1380 demux->video = TRUE;
1387 static const GstQueryType *
1388 gst_matroska_demux_get_src_query_types (GstPad * pad)
1390 static const GstQueryType query_types[] = {
1401 gst_matroska_demux_query (GstMatroskaDemux * demux, GstPad * pad,
1404 gboolean res = FALSE;
1405 GstMatroskaTrackContext *context = NULL;
1408 context = gst_pad_get_element_private (pad);
1411 switch (GST_QUERY_TYPE (query)) {
1412 case GST_QUERY_POSITION:
1416 gst_query_parse_position (query, &format, NULL);
1418 if (format == GST_FORMAT_TIME) {
1419 GST_OBJECT_LOCK (demux);
1421 gst_query_set_position (query, GST_FORMAT_TIME,
1422 MAX (context->pos, demux->stream_start_time) -
1423 demux->stream_start_time);
1425 gst_query_set_position (query, GST_FORMAT_TIME,
1426 MAX (demux->common.segment.last_stop, demux->stream_start_time) -
1427 demux->stream_start_time);
1428 GST_OBJECT_UNLOCK (demux);
1429 } else if (format == GST_FORMAT_DEFAULT && context
1430 && context->default_duration) {
1431 GST_OBJECT_LOCK (demux);
1432 gst_query_set_position (query, GST_FORMAT_DEFAULT,
1433 context->pos / context->default_duration);
1434 GST_OBJECT_UNLOCK (demux);
1436 GST_DEBUG_OBJECT (demux,
1437 "only position query in TIME and DEFAULT format is supported");
1443 case GST_QUERY_DURATION:
1447 gst_query_parse_duration (query, &format, NULL);
1449 if (format == GST_FORMAT_TIME) {
1450 GST_OBJECT_LOCK (demux);
1451 gst_query_set_duration (query, GST_FORMAT_TIME,
1452 demux->common.segment.duration);
1453 GST_OBJECT_UNLOCK (demux);
1454 } else if (format == GST_FORMAT_DEFAULT && context
1455 && context->default_duration) {
1456 GST_OBJECT_LOCK (demux);
1457 gst_query_set_duration (query, GST_FORMAT_DEFAULT,
1458 demux->common.segment.duration / context->default_duration);
1459 GST_OBJECT_UNLOCK (demux);
1461 GST_DEBUG_OBJECT (demux,
1462 "only duration query in TIME and DEFAULT format is supported");
1469 case GST_QUERY_SEEKING:
1473 gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
1474 GST_OBJECT_LOCK (demux);
1475 if (fmt == GST_FORMAT_TIME) {
1478 if (demux->streaming) {
1479 /* assuming we'll be able to get an index ... */
1480 seekable = demux->seekable;
1485 gst_query_set_seeking (query, GST_FORMAT_TIME, seekable,
1486 0, demux->common.segment.duration);
1489 GST_OBJECT_UNLOCK (demux);
1493 res = gst_pad_query_default (pad, query);
1501 gst_matroska_demux_element_query (GstElement * element, GstQuery * query)
1503 return gst_matroska_demux_query (GST_MATROSKA_DEMUX (element), NULL, query);
1507 gst_matroska_demux_handle_src_query (GstPad * pad, GstQuery * query)
1510 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (gst_pad_get_parent (pad));
1512 ret = gst_matroska_demux_query (demux, pad, query);
1514 gst_object_unref (demux);
1519 /* returns FALSE if there are no pads to deliver event to,
1520 * otherwise TRUE (whatever the outcome of event sending),
1521 * takes ownership of the passed event! */
1523 gst_matroska_demux_send_event (GstMatroskaDemux * demux, GstEvent * event)
1525 gboolean is_newsegment;
1526 gboolean ret = FALSE;
1529 g_return_val_if_fail (event != NULL, FALSE);
1531 GST_DEBUG_OBJECT (demux, "Sending event of type %s to all source pads",
1532 GST_EVENT_TYPE_NAME (event));
1534 is_newsegment = (GST_EVENT_TYPE (event) == GST_EVENT_NEWSEGMENT);
1536 g_assert (demux->common.src->len == demux->common.num_streams);
1537 for (i = 0; i < demux->common.src->len; i++) {
1538 GstMatroskaTrackContext *stream;
1540 stream = g_ptr_array_index (demux->common.src, i);
1541 gst_event_ref (event);
1542 gst_pad_push_event (stream->pad, event);
1545 /* FIXME: send global tags before stream tags */
1546 if (G_UNLIKELY (is_newsegment && stream->pending_tags != NULL)) {
1547 GST_DEBUG_OBJECT (demux, "Sending pending_tags %p for pad %s:%s : %"
1548 GST_PTR_FORMAT, stream->pending_tags,
1549 GST_DEBUG_PAD_NAME (stream->pad), stream->pending_tags);
1550 gst_element_found_tags_for_pad (GST_ELEMENT (demux), stream->pad,
1551 stream->pending_tags);
1552 stream->pending_tags = NULL;
1556 if (G_UNLIKELY (is_newsegment && demux->common.global_tags != NULL)) {
1557 gst_tag_list_add (demux->common.global_tags, GST_TAG_MERGE_REPLACE,
1558 GST_TAG_CONTAINER_FORMAT, "Matroska", NULL);
1559 GST_DEBUG_OBJECT (demux, "Sending global_tags %p : %" GST_PTR_FORMAT,
1560 demux->common.global_tags, demux->common.global_tags);
1561 gst_element_found_tags (GST_ELEMENT (demux), demux->common.global_tags);
1562 demux->common.global_tags = NULL;
1565 gst_event_unref (event);
1570 gst_matroska_demux_element_send_event (GstElement * element, GstEvent * event)
1572 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
1575 g_return_val_if_fail (event != NULL, FALSE);
1577 if (GST_EVENT_TYPE (event) == GST_EVENT_SEEK) {
1578 res = gst_matroska_demux_handle_seek_event (demux, NULL, event);
1580 GST_WARNING_OBJECT (demux, "Unhandled event of type %s",
1581 GST_EVENT_TYPE_NAME (event));
1584 gst_event_unref (event);
1589 gst_matroska_demux_move_to_entry (GstMatroskaDemux * demux,
1590 GstMatroskaIndex * entry, gboolean reset)
1594 GST_OBJECT_LOCK (demux);
1596 /* seek (relative to matroska segment) */
1597 /* position might be invalid; will error when streaming resumes ... */
1598 demux->common.offset = entry->pos + demux->common.ebml_segment_start;
1600 GST_DEBUG_OBJECT (demux, "Seeked to offset %" G_GUINT64_FORMAT ", block %d, "
1601 "time %" GST_TIME_FORMAT, entry->pos + demux->common.ebml_segment_start,
1602 entry->block, GST_TIME_ARGS (entry->time));
1604 /* update the time */
1605 gst_matroska_read_common_reset_streams (&demux->common, entry->time, TRUE);
1606 demux->common.segment.last_stop = entry->time;
1607 demux->seek_block = entry->block;
1608 demux->seek_first = TRUE;
1609 demux->last_stop_end = GST_CLOCK_TIME_NONE;
1611 for (i = 0; i < demux->common.src->len; i++) {
1612 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
1615 stream->to_offset = G_MAXINT64;
1617 if (stream->from_offset != -1)
1618 stream->to_offset = stream->from_offset;
1620 stream->from_offset = -1;
1623 GST_OBJECT_UNLOCK (demux);
1629 gst_matroska_cluster_compare (gint64 * i1, gint64 * i2)
1639 /* searches for a cluster start from @pos,
1640 * return GST_FLOW_OK and cluster position in @pos if found */
1641 static GstFlowReturn
1642 gst_matroska_demux_search_cluster (GstMatroskaDemux * demux, gint64 * pos)
1644 gint64 newpos = *pos;
1646 GstFlowReturn ret = GST_FLOW_OK;
1647 const guint chunk = 64 * 1024;
1648 GstBuffer *buf = NULL;
1653 orig_offset = demux->common.offset;
1655 GST_LOG_OBJECT (demux, "searching cluster following offset %" G_GINT64_FORMAT,
1658 if (demux->clusters) {
1661 cpos = gst_util_array_binary_search (demux->clusters->data,
1662 demux->clusters->len, sizeof (gint64),
1663 (GCompareDataFunc) gst_matroska_cluster_compare,
1664 GST_SEARCH_MODE_AFTER, pos, NULL);
1667 GST_DEBUG_OBJECT (demux,
1668 "cluster reported at offset %" G_GINT64_FORMAT, *cpos);
1669 demux->common.offset = *cpos;
1670 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1671 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1672 if (ret == GST_FLOW_OK && id == GST_MATROSKA_ID_CLUSTER) {
1679 /* read in at newpos and scan for ebml cluster id */
1681 GstByteReader reader;
1685 gst_buffer_unref (buf);
1688 ret = gst_pad_pull_range (demux->common.sinkpad, newpos, chunk, &buf);
1689 if (ret != GST_FLOW_OK)
1691 GST_DEBUG_OBJECT (demux, "read buffer size %d at offset %" G_GINT64_FORMAT,
1692 GST_BUFFER_SIZE (buf), newpos);
1693 gst_byte_reader_init_from_buffer (&reader, buf);
1695 cluster_pos = gst_byte_reader_masked_scan_uint32 (&reader, 0xffffffff,
1696 GST_MATROSKA_ID_CLUSTER, 0, gst_byte_reader_get_remaining (&reader));
1697 if (cluster_pos >= 0) {
1698 newpos += cluster_pos;
1699 /* prepare resuming at next byte */
1700 gst_byte_reader_skip (&reader, cluster_pos + 1);
1701 GST_DEBUG_OBJECT (demux,
1702 "found cluster ebml id at offset %" G_GINT64_FORMAT, newpos);
1703 /* extra checks whether we really sync'ed to a cluster:
1704 * - either it is the first and only cluster
1705 * - either there is a cluster after this one
1706 * - either cluster length is undefined
1708 /* ok if first cluster (there may not a subsequent one) */
1709 if (newpos == demux->first_cluster_offset) {
1710 GST_DEBUG_OBJECT (demux, "cluster is first cluster -> OK");
1713 demux->common.offset = newpos;
1714 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1715 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1716 if (ret != GST_FLOW_OK) {
1717 GST_DEBUG_OBJECT (demux, "need more data -> continue");
1720 g_assert (id == GST_MATROSKA_ID_CLUSTER);
1721 GST_DEBUG_OBJECT (demux, "cluster size %" G_GUINT64_FORMAT ", prefix %d",
1723 /* ok if undefined length or first cluster */
1724 if (length == GST_EBML_SIZE_UNKNOWN || length == G_MAXUINT64) {
1725 GST_DEBUG_OBJECT (demux, "cluster has undefined length -> OK");
1729 demux->common.offset += length + needed;
1730 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1731 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1732 if (ret != GST_FLOW_OK)
1734 GST_DEBUG_OBJECT (demux, "next element is %scluster",
1735 id == GST_MATROSKA_ID_CLUSTER ? "" : "not ");
1736 if (id == GST_MATROSKA_ID_CLUSTER)
1738 /* not ok, resume */
1741 /* partial cluster id may have been in tail of buffer */
1742 newpos += MAX (gst_byte_reader_get_remaining (&reader), 4) - 3;
1747 gst_buffer_unref (buf);
1752 demux->common.offset = orig_offset;
1757 /* bisect and scan through file for cluster starting before @time,
1758 * returns fake index entry with corresponding info on cluster */
1759 static GstMatroskaIndex *
1760 gst_matroska_demux_search_pos (GstMatroskaDemux * demux, GstClockTime time)
1762 GstMatroskaIndex *entry = NULL;
1763 GstMatroskaReadState current_state;
1764 GstClockTime otime, prev_cluster_time, current_cluster_time, cluster_time;
1765 gint64 opos, newpos, startpos = 0, current_offset;
1766 gint64 prev_cluster_offset = -1, current_cluster_offset, cluster_offset;
1767 const guint chunk = 64 * 1024;
1773 /* (under)estimate new position, resync using cluster ebml id,
1774 * and scan forward to appropriate cluster
1775 * (and re-estimate if need to go backward) */
1777 prev_cluster_time = GST_CLOCK_TIME_NONE;
1779 /* store some current state */
1780 current_state = demux->common.state;
1781 g_return_val_if_fail (current_state == GST_MATROSKA_READ_STATE_DATA, NULL);
1783 current_cluster_offset = demux->cluster_offset;
1784 current_cluster_time = demux->cluster_time;
1785 current_offset = demux->common.offset;
1787 demux->common.state = GST_MATROSKA_READ_STATE_SCANNING;
1789 /* estimate using start and current position */
1790 GST_OBJECT_LOCK (demux);
1791 opos = demux->common.offset - demux->common.ebml_segment_start;
1792 otime = demux->common.segment.last_stop;
1793 GST_OBJECT_UNLOCK (demux);
1796 time = MAX (time, demux->stream_start_time);
1798 /* avoid division by zero in first estimation below */
1799 if (otime <= demux->stream_start_time)
1803 GST_LOG_OBJECT (demux,
1804 "opos: %" G_GUINT64_FORMAT ", otime: %" GST_TIME_FORMAT ", %"
1805 GST_TIME_FORMAT " in stream time (start %" GST_TIME_FORMAT "), time %"
1806 GST_TIME_FORMAT, opos, GST_TIME_ARGS (otime),
1807 GST_TIME_ARGS (otime - demux->stream_start_time),
1808 GST_TIME_ARGS (demux->stream_start_time), GST_TIME_ARGS (time));
1810 gst_util_uint64_scale (opos - demux->common.ebml_segment_start,
1811 time - demux->stream_start_time,
1812 otime - demux->stream_start_time) - chunk;
1815 /* favour undershoot */
1816 newpos = newpos * 90 / 100;
1817 newpos += demux->common.ebml_segment_start;
1819 GST_DEBUG_OBJECT (demux,
1820 "estimated offset for %" GST_TIME_FORMAT ": %" G_GINT64_FORMAT,
1821 GST_TIME_ARGS (time), newpos);
1823 /* and at least start scanning before previous scan start to avoid looping */
1824 startpos = startpos * 90 / 100;
1825 if (startpos && startpos < newpos)
1828 /* read in at newpos and scan for ebml cluster id */
1832 ret = gst_matroska_demux_search_cluster (demux, &newpos);
1833 if (ret == GST_FLOW_UNEXPECTED) {
1834 /* heuristic HACK */
1835 newpos = startpos * 80 / 100;
1836 GST_DEBUG_OBJECT (demux, "EOS; "
1837 "new estimated offset for %" GST_TIME_FORMAT ": %" G_GINT64_FORMAT,
1838 GST_TIME_ARGS (time), newpos);
1841 } else if (ret != GST_FLOW_OK) {
1848 /* then start scanning and parsing for cluster time,
1849 * re-estimate if overshoot, otherwise next cluster and so on */
1850 demux->common.offset = newpos;
1851 demux->cluster_time = cluster_time = GST_CLOCK_TIME_NONE;
1853 guint64 cluster_size = 0;
1855 /* peek and parse some elements */
1856 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1857 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1858 if (ret != GST_FLOW_OK)
1860 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
1861 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
1863 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
1864 if (ret != GST_FLOW_OK)
1867 if (id == GST_MATROSKA_ID_CLUSTER) {
1868 cluster_time = GST_CLOCK_TIME_NONE;
1869 if (length == G_MAXUINT64)
1872 cluster_size = length + needed;
1874 if (demux->cluster_time != GST_CLOCK_TIME_NONE &&
1875 cluster_time == GST_CLOCK_TIME_NONE) {
1876 cluster_time = demux->cluster_time * demux->common.time_scale;
1877 cluster_offset = demux->cluster_offset;
1878 GST_DEBUG_OBJECT (demux, "found cluster at offset %" G_GINT64_FORMAT
1879 " with time %" GST_TIME_FORMAT, cluster_offset,
1880 GST_TIME_ARGS (cluster_time));
1881 if (cluster_time > time) {
1882 GST_DEBUG_OBJECT (demux, "overshot target");
1883 /* cluster overshoots */
1884 if (cluster_offset == demux->first_cluster_offset) {
1885 /* but no prev one */
1886 GST_DEBUG_OBJECT (demux, "but using first cluster anyway");
1887 prev_cluster_time = cluster_time;
1888 prev_cluster_offset = cluster_offset;
1891 if (prev_cluster_time != GST_CLOCK_TIME_NONE) {
1892 /* prev cluster did not overshoot, so prev cluster is target */
1895 /* re-estimate using this new position info */
1896 opos = cluster_offset;
1897 otime = cluster_time;
1901 /* cluster undershoots, goto next one */
1902 prev_cluster_time = cluster_time;
1903 prev_cluster_offset = cluster_offset;
1904 /* skip cluster if length is defined,
1905 * otherwise will be skippingly parsed into */
1907 GST_DEBUG_OBJECT (demux, "skipping to next cluster");
1908 demux->common.offset = cluster_offset + cluster_size;
1909 demux->cluster_time = GST_CLOCK_TIME_NONE;
1911 GST_DEBUG_OBJECT (demux, "parsing/skipping cluster elements");
1918 if (ret == GST_FLOW_UNEXPECTED) {
1919 if (prev_cluster_time != GST_CLOCK_TIME_NONE)
1925 entry = g_new0 (GstMatroskaIndex, 1);
1926 entry->time = prev_cluster_time;
1927 entry->pos = prev_cluster_offset - demux->common.ebml_segment_start;
1928 GST_DEBUG_OBJECT (demux, "simulated index entry; time %" GST_TIME_FORMAT
1929 ", pos %" G_GUINT64_FORMAT, GST_TIME_ARGS (entry->time), entry->pos);
1933 /* restore some state */
1934 demux->cluster_offset = current_cluster_offset;
1935 demux->cluster_time = current_cluster_time;
1936 demux->common.offset = current_offset;
1937 demux->common.state = current_state;
1943 gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
1944 GstPad * pad, GstEvent * event)
1946 GstMatroskaIndex *entry = NULL;
1947 GstMatroskaIndex scan_entry;
1948 #ifdef MKV_DEMUX_MODIFICATION
1949 GstMatroskaIndex *next_entry = NULL;
1952 GstSeekType cur_type, stop_type;
1954 gboolean flush, keyunit;
1957 GstMatroskaTrackContext *track = NULL;
1958 GstSegment seeksegment = { 0, };
1959 gboolean update = TRUE;
1962 track = gst_pad_get_element_private (pad);
1964 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
1967 /* we can only seek on time */
1968 if (format != GST_FORMAT_TIME) {
1969 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
1973 #ifndef MKV_DEMUX_MODIFICATION
1974 /* cannot yet do backwards playback */
1976 GST_DEBUG_OBJECT (demux, "Can only seek with positive rate");
1981 /* copy segment, we need this because we still need the old
1982 * segment when we close the current segment. */
1983 memcpy (&seeksegment, &demux->common.segment, sizeof (GstSegment));
1985 #ifdef MKV_DEMUX_MODIFICATION
1986 gst_segment_set_last_stop (&seeksegment, GST_FORMAT_TIME, cur);
1989 /* pull mode without index means that the actual duration is not known,
1990 * we might be playing a file that's still being recorded
1991 * so, invalidate our current duration, which is only a moving target,
1992 * and should not be used to clamp anything */
1993 if (!demux->streaming && !demux->common.index &&
1994 demux->invalid_duration) {
1995 gst_segment_set_duration (&seeksegment, GST_FORMAT_TIME,
1996 GST_CLOCK_TIME_NONE);
2000 GST_DEBUG_OBJECT (demux, "configuring seek");
2001 gst_segment_set_seek (&seeksegment, rate, format, flags,
2002 cur_type, cur, stop_type, stop, &update);
2003 /* compensate for clip start time */
2004 if (GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
2005 seeksegment.last_stop += demux->stream_start_time;
2006 seeksegment.start += demux->stream_start_time;
2007 if (GST_CLOCK_TIME_IS_VALID (seeksegment.stop))
2008 seeksegment.stop += demux->stream_start_time;
2009 /* note that time should stay at indicated position */
2013 /* restore segment duration (if any effect),
2014 * would be determined again when parsing, but anyway ... */
2015 #ifndef MKV_DEMUX_MODIFICATION
2016 gst_segment_set_duration (&seeksegment, GST_FORMAT_TIME,
2017 demux->common.segment.duration);
2020 flush = ! !(flags & GST_SEEK_FLAG_FLUSH);
2021 keyunit = ! !(flags & GST_SEEK_FLAG_KEY_UNIT);
2023 GST_DEBUG_OBJECT (demux, "New segment %" GST_SEGMENT_FORMAT, &seeksegment);
2025 #ifndef MKV_DEMUX_MODIFICATION
2027 /* only have to update some segment,
2028 * but also still have to honour flush and so on */
2029 GST_DEBUG_OBJECT (demux, "... no update");
2030 /* bad goto, bad ... */
2035 /* check sanity before we start flushing and all that */
2036 GST_OBJECT_LOCK (demux);
2037 track = gst_matroska_read_common_get_seek_track (&demux->common, track);
2038 if ((entry = gst_matroska_read_common_do_index_seek (&demux->common, track,
2039 seeksegment.last_stop, &demux->seek_index, &demux->seek_entry)) ==
2041 /* pull mode without index can scan later on */
2042 if (demux->streaming) {
2043 GST_DEBUG_OBJECT (demux, "No matching seek entry in index");
2044 GST_OBJECT_UNLOCK (demux);
2049 #ifdef MKV_DEMUX_MODIFICATION
2053 if (seeksegment.rate < 0.0) {
2054 GST_INFO("Current Index is %"GST_TIME_FORMAT, GST_TIME_ARGS(entry->time));
2055 next_entry = gst_matroska_demux_get_next_index (demux, track, entry);
2056 if (next_entry == NULL) {
2057 GST_ERROR ("Entry Not found....");
2060 GST_INFO("Next Index is %"GST_TIME_FORMAT, GST_TIME_ARGS(next_entry->time));
2064 GST_DEBUG_OBJECT (demux, "Seek position looks sane");
2065 GST_OBJECT_UNLOCK (demux);
2067 if (demux->streaming) {
2068 /* need to seek to cluster start to pick up cluster time */
2069 /* upstream takes care of flushing and all that
2070 * ... and newsegment event handling takes care of the rest */
2071 return perform_seek_to_offset (demux,
2072 entry->pos + demux->common.ebml_segment_start);
2075 #ifdef MKV_DEMUX_MODIFICATION
2076 keyunit = TRUE;//intentionally making it as true. need to check
2081 GST_DEBUG_OBJECT (demux, "Starting flush");
2082 gst_pad_push_event (demux->common.sinkpad, gst_event_new_flush_start ());
2083 gst_matroska_demux_send_event (demux, gst_event_new_flush_start ());
2085 GST_DEBUG_OBJECT (demux, "Non-flushing seek, pausing task");
2086 gst_pad_pause_task (demux->common.sinkpad);
2089 #ifndef MKV_DEMUX_MODIFICATION
2095 /* now grab the stream lock so that streaming cannot continue, for
2096 * non flushing seeks when the element is in PAUSED this could block
2098 GST_DEBUG_OBJECT (demux, "Waiting for streaming to stop");
2099 GST_PAD_STREAM_LOCK (demux->common.sinkpad);
2101 /* pull mode without index can do some scanning */
2102 if (!demux->streaming && !entry) {
2103 /* need to stop flushing upstream as we need it next */
2105 gst_pad_push_event (demux->common.sinkpad, gst_event_new_flush_stop ());
2106 entry = gst_matroska_demux_search_pos (demux, seeksegment.last_stop);
2107 /* keep local copy */
2109 scan_entry = *entry;
2111 entry = &scan_entry;
2113 GST_DEBUG_OBJECT (demux, "Scan failed to find matching position");
2115 gst_matroska_demux_send_event (demux, gst_event_new_flush_stop ());
2121 GST_DEBUG_OBJECT (demux, "seek to key unit, adjusting segment start to %"
2122 GST_TIME_FORMAT, GST_TIME_ARGS (entry->time));
2123 #ifdef MKV_DEMUX_MODIFICATION
2124 if (seeksegment.stop == -1) {
2125 seeksegment.stop = seeksegment.duration;
2127 if (seeksegment.rate > 0.0) {
2128 seeksegment.start = cur;
2129 seeksegment.time = cur;
2130 seeksegment.last_stop = cur;
2131 seeksegment.stop = seeksegment.duration;
2132 } else if (seeksegment.rate < 0.0) {/* Reverse trick play */
2133 seeksegment.start = 0.0;
2134 seeksegment.stop = next_entry->time;
2135 seeksegment.last_stop = cur + GST_MSECOND;
2136 seeksegment.time = 0.0;
2137 demux->next_keyframe_ts = cur;
2138 GST_INFO("next_keyframe_ts %"GST_TIME_FORMAT, GST_TIME_ARGS(demux->next_keyframe_ts));
2141 seeksegment.start = MAX (entry->time, demux->stream_start_time);
2142 seeksegment.last_stop = seeksegment.start;
2143 seeksegment.time = seeksegment.start - demux->stream_start_time;
2149 GST_DEBUG_OBJECT (demux, "Stopping flush");
2150 gst_pad_push_event (demux->common.sinkpad, gst_event_new_flush_stop ());
2151 gst_matroska_demux_send_event (demux, gst_event_new_flush_stop ());
2152 #ifdef MKV_DEMUX_MODIFICATION
2153 } else if (demux->segment_running) {
2155 } else if (demux->segment_running && update) {
2157 GST_DEBUG_OBJECT (demux, "Closing currently running segment");
2159 GST_OBJECT_LOCK (demux);
2160 if (demux->close_segment)
2161 gst_event_unref (demux->close_segment);
2163 demux->close_segment = gst_event_new_new_segment (TRUE,
2164 demux->common.segment.rate, GST_FORMAT_TIME,
2165 demux->common.segment.start, demux->common.segment.last_stop,
2166 demux->common.segment.time);
2167 GST_OBJECT_UNLOCK (demux);
2170 GST_OBJECT_LOCK (demux);
2171 /* now update the real segment info */
2172 GST_DEBUG_OBJECT (demux, "Committing new seek segment");
2173 memcpy (&demux->common.segment, &seeksegment, sizeof (GstSegment));
2174 GST_OBJECT_UNLOCK (demux);
2176 /* update some (segment) state */
2177 #ifdef MKV_DEMUX_MODIFICATION
2178 if (!gst_matroska_demux_move_to_entry (demux, entry, TRUE))
2180 if (update && !gst_matroska_demux_move_to_entry (demux, entry, TRUE))
2184 /* notify start of new segment */
2185 if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
2188 msg = gst_message_new_segment_start (GST_OBJECT (demux),
2189 GST_FORMAT_TIME, demux->common.segment.start);
2190 gst_element_post_message (GST_ELEMENT (demux), msg);
2193 GST_OBJECT_LOCK (demux);
2194 if (demux->new_segment)
2195 gst_event_unref (demux->new_segment);
2196 #ifdef MKV_DEMUX_MODIFICATION
2197 if (demux->common.segment.rate > 0.0) {
2198 demux->new_segment = gst_event_new_new_segment_full (FALSE,
2199 demux->common.segment.rate, demux->common.segment.applied_rate,
2200 demux->common.segment.format, seeksegment.last_stop,
2201 demux->common.segment.stop, demux->common.segment.time);
2203 } else if (demux->common.segment.rate < 0.0) {
2204 /* Reverse trick play */
2205 demux->new_segment = gst_event_new_new_segment_full (FALSE,
2206 demux->common.segment.rate, demux->common.segment.applied_rate,
2207 demux->common.segment.format, demux->common.segment.start,
2208 seeksegment.last_stop, demux->common.segment.time);
2211 demux->new_segment = gst_event_new_new_segment_full (!update,
2212 demux->common.segment.rate, demux->common.segment.applied_rate,
2213 demux->common.segment.format, demux->common.segment.start,
2214 demux->common.segment.stop, demux->common.segment.time);
2216 GST_OBJECT_UNLOCK (demux);
2218 #ifdef MKV_DEMUX_MODIFICATION
2219 if (demux->common.segment.rate > 0.0) {
2220 demux->common.segment.last_stop = entry->time;
2221 } else if (demux->common.segment.rate < 0.0) {
2222 demux->common.segment.last_stop = next_entry->time;
2226 /* restart our task since it might have been stopped when we did the
2228 demux->segment_running = TRUE;
2229 gst_pad_start_task (demux->common.sinkpad,
2230 (GstTaskFunction) gst_matroska_demux_loop, demux->common.sinkpad);
2232 #ifdef MKV_DEMUX_MODIFICATION
2233 while (!g_queue_is_empty (track->queue)) {
2234 GstBuffer* buf = g_queue_pop_head (track->queue);
2235 gst_buffer_unref (buf);
2239 /* streaming can continue now */
2240 GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
2246 GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
2247 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Got a seek error"));
2253 * Handle whether we can perform the seek event or if we have to let the chain
2254 * function handle seeks to build the seek indexes first.
2257 gst_matroska_demux_handle_seek_push (GstMatroskaDemux * demux, GstPad * pad,
2261 GstSeekType cur_type, stop_type;
2266 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
2271 /* we can only seek on time */
2272 if (format != GST_FORMAT_TIME) {
2273 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
2277 if (stop_type != GST_SEEK_TYPE_NONE && stop != GST_CLOCK_TIME_NONE) {
2278 GST_DEBUG_OBJECT (demux, "Seek end-time not supported in streaming mode");
2282 if (!(flags & GST_SEEK_FLAG_FLUSH)) {
2283 GST_DEBUG_OBJECT (demux,
2284 "Non-flushing seek not supported in streaming mode");
2288 if (flags & GST_SEEK_FLAG_SEGMENT) {
2289 GST_DEBUG_OBJECT (demux, "Segment seek not supported in streaming mode");
2293 /* check for having parsed index already */
2294 if (!demux->common.index_parsed) {
2295 gboolean building_index;
2298 if (!demux->index_offset) {
2299 GST_DEBUG_OBJECT (demux, "no index (location); no seek in push mode");
2303 GST_OBJECT_LOCK (demux);
2304 /* handle the seek event in the chain function */
2305 demux->common.state = GST_MATROSKA_READ_STATE_SEEK;
2306 /* no more seek can be issued until state reset to _DATA */
2308 /* copy the event */
2309 if (demux->seek_event)
2310 gst_event_unref (demux->seek_event);
2311 demux->seek_event = gst_event_ref (event);
2313 /* set the building_index flag so that only one thread can setup the
2314 * structures for index seeking. */
2315 building_index = demux->building_index;
2316 if (!building_index) {
2317 demux->building_index = TRUE;
2318 offset = demux->index_offset;
2320 GST_OBJECT_UNLOCK (demux);
2322 if (!building_index) {
2323 /* seek to the first subindex or legacy index */
2324 GST_INFO_OBJECT (demux, "Seeking to Cues at %" G_GUINT64_FORMAT, offset);
2325 return perform_seek_to_offset (demux, offset);
2328 /* well, we are handling it already */
2332 /* delegate to tweaked regular seek */
2333 return gst_matroska_demux_handle_seek_event (demux, pad, event);
2337 gst_matroska_demux_handle_src_event (GstPad * pad, GstEvent * event)
2339 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (gst_pad_get_parent (pad));
2340 gboolean res = TRUE;
2342 switch (GST_EVENT_TYPE (event)) {
2343 case GST_EVENT_SEEK:
2344 /* no seeking until we are (safely) ready */
2345 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
2346 GST_DEBUG_OBJECT (demux, "not ready for seeking yet");
2349 if (!demux->streaming)
2350 res = gst_matroska_demux_handle_seek_event (demux, pad, event);
2352 res = gst_matroska_demux_handle_seek_push (demux, pad, event);
2353 gst_event_unref (event);
2358 GstMatroskaTrackContext *context = gst_pad_get_element_private (pad);
2359 if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
2360 GstMatroskaTrackVideoContext *videocontext =
2361 (GstMatroskaTrackVideoContext *) context;
2363 GstClockTimeDiff diff;
2364 GstClockTime timestamp;
2366 gst_event_parse_qos (event, &proportion, &diff, ×tamp);
2368 GST_OBJECT_LOCK (demux);
2369 videocontext->earliest_time = timestamp + diff;
2370 GST_OBJECT_UNLOCK (demux);
2373 gst_event_unref (event);
2377 /* events we don't need to handle */
2378 case GST_EVENT_NAVIGATION:
2379 gst_event_unref (event);
2383 case GST_EVENT_LATENCY:
2385 res = gst_pad_push_event (demux->common.sinkpad, event);
2389 gst_object_unref (demux);
2394 static GstFlowReturn
2395 gst_matroska_demux_seek_to_previous_keyframe (GstMatroskaDemux * demux)
2397 GstFlowReturn ret = GST_FLOW_UNEXPECTED;
2398 gboolean done = TRUE;
2401 g_return_val_if_fail (demux->seek_index, GST_FLOW_UNEXPECTED);
2402 g_return_val_if_fail (demux->seek_entry < demux->seek_index->len,
2403 GST_FLOW_UNEXPECTED);
2405 GST_DEBUG_OBJECT (demux, "locating previous keyframe");
2407 if (!demux->seek_entry) {
2408 GST_DEBUG_OBJECT (demux, "no earlier index entry");
2412 for (i = 0; i < demux->common.src->len; i++) {
2413 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
2415 GST_DEBUG_OBJECT (demux, "segment start %" GST_TIME_FORMAT
2416 ", stream %d at %" GST_TIME_FORMAT,
2417 GST_TIME_ARGS (demux->common.segment.start), stream->index,
2418 GST_TIME_ARGS (stream->from_time));
2419 if (GST_CLOCK_TIME_IS_VALID (stream->from_time)) {
2420 if (stream->from_time > demux->common.segment.start) {
2421 GST_DEBUG_OBJECT (demux, "stream %d not finished yet", stream->index);
2425 /* nothing pushed for this stream;
2426 * likely seek entry did not start at keyframe, so all was skipped.
2427 * So we need an earlier entry */
2433 GstMatroskaIndex *entry;
2435 entry = &g_array_index (demux->seek_index, GstMatroskaIndex,
2436 --demux->seek_entry);
2437 if (!gst_matroska_demux_move_to_entry (demux, entry, FALSE))
2447 static GstFlowReturn
2448 gst_matroska_demux_parse_tracks (GstMatroskaDemux * demux, GstEbmlRead * ebml)
2450 GstFlowReturn ret = GST_FLOW_OK;
2453 DEBUG_ELEMENT_START (demux, ebml, "Tracks");
2455 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2456 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
2460 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
2461 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
2465 /* one track within the "all-tracks" header */
2466 case GST_MATROSKA_ID_TRACKENTRY:
2467 ret = gst_matroska_demux_add_stream (demux, ebml);
2471 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
2476 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
2478 demux->tracks_parsed = TRUE;
2484 * Read signed/unsigned "EBML" numbers.
2485 * Return: number of bytes processed.
2489 gst_matroska_ebmlnum_uint (guint8 * data, guint size, guint64 * num)
2491 gint len_mask = 0x80, read = 1, n = 1, num_ffs = 0;
2499 while (read <= 8 && !(total & len_mask)) {
2506 if ((total &= (len_mask - 1)) == len_mask - 1)
2511 if (data[n] == 0xff)
2513 total = (total << 8) | data[n];
2517 if (read == num_ffs && total != 0)
2526 gst_matroska_ebmlnum_sint (guint8 * data, guint size, gint64 * num)
2531 /* read as unsigned number first */
2532 if ((res = gst_matroska_ebmlnum_uint (data, size, &unum)) < 0)
2536 if (unum == G_MAXUINT64)
2539 *num = unum - ((1 << ((7 * res) - 1)) - 1);
2545 * Mostly used for subtitles. We add void filler data for each
2546 * lagging stream to make sure we don't deadlock.
2550 gst_matroska_demux_sync_streams (GstMatroskaDemux * demux)
2554 GST_OBJECT_LOCK (demux);
2556 GST_LOG_OBJECT (demux, "Sync to %" GST_TIME_FORMAT,
2557 GST_TIME_ARGS (demux->common.segment.last_stop));
2559 g_assert (demux->common.num_streams == demux->common.src->len);
2560 for (stream_nr = 0; stream_nr < demux->common.src->len; stream_nr++) {
2561 GstMatroskaTrackContext *context;
2563 context = g_ptr_array_index (demux->common.src, stream_nr);
2565 GST_LOG_OBJECT (demux,
2566 "Checking for resync on stream %d (%" GST_TIME_FORMAT ")", stream_nr,
2567 GST_TIME_ARGS (context->pos));
2569 if (G_LIKELY (context->type != GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
2570 GST_LOG_OBJECT (demux, "Skipping sync on non-subtitle stream");
2573 #ifndef MKV_DEMUX_MODIFICATION
2574 /* does it lag? 0.5 seconds is a random threshold...
2575 * lag need only be considered if we have advanced into requested segment */
2576 if (GST_CLOCK_TIME_IS_VALID (context->pos) &&
2577 GST_CLOCK_TIME_IS_VALID (demux->common.segment.last_stop) &&
2578 demux->common.segment.last_stop > demux->common.segment.start &&
2579 context->pos + (GST_SECOND / 2) < demux->common.segment.last_stop) {
2583 new_start = demux->common.segment.last_stop - (GST_SECOND / 2);
2584 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop))
2585 new_start = MIN (new_start, demux->common.segment.stop);
2586 GST_DEBUG_OBJECT (demux,
2587 "Synchronizing stream %d with others by advancing time " "from %"
2588 GST_TIME_FORMAT " to %" GST_TIME_FORMAT, stream_nr,
2589 GST_TIME_ARGS (context->pos), GST_TIME_ARGS (new_start));
2591 context->pos = new_start;
2593 /* advance stream time */
2594 event = gst_event_new_new_segment (TRUE, demux->common.segment.rate,
2595 demux->common.segment.format, new_start, demux->common.segment.stop,
2597 GST_OBJECT_UNLOCK (demux);
2598 gst_pad_push_event (context->pad, event);
2599 GST_OBJECT_LOCK (demux);
2604 GST_OBJECT_UNLOCK (demux);
2607 static GstFlowReturn
2608 gst_matroska_demux_push_hdr_buf (GstMatroskaDemux * demux,
2609 GstMatroskaTrackContext * stream, guint8 * data, guint len)
2611 GstFlowReturn ret, cret;
2612 GstBuffer *header_buf;
2614 header_buf = gst_buffer_new_and_alloc (len);
2615 gst_buffer_set_caps (header_buf, stream->caps);
2616 memcpy (GST_BUFFER_DATA (header_buf), data, len);
2618 if (stream->set_discont) {
2619 GST_BUFFER_FLAG_SET (header_buf, GST_BUFFER_FLAG_DISCONT);
2620 stream->set_discont = FALSE;
2623 ret = gst_pad_push (stream->pad, header_buf);
2626 cret = gst_matroska_demux_combine_flows (demux, stream, ret);
2631 static GstFlowReturn
2632 gst_matroska_demux_push_flac_codec_priv_data (GstMatroskaDemux * demux,
2633 GstMatroskaTrackContext * stream)
2639 GST_LOG_OBJECT (demux, "priv data size = %u", stream->codec_priv_size);
2641 pdata = (guint8 *) stream->codec_priv;
2643 /* need at least 'fLaC' marker + STREAMINFO metadata block */
2644 if (stream->codec_priv_size < ((4) + (4 + 34))) {
2645 GST_WARNING_OBJECT (demux, "not enough codec priv data for flac headers");
2646 return GST_FLOW_ERROR;
2649 if (memcmp (pdata, "fLaC", 4) != 0) {
2650 GST_WARNING_OBJECT (demux, "no flac marker at start of stream headers");
2651 return GST_FLOW_ERROR;
2654 ret = gst_matroska_demux_push_hdr_buf (demux, stream, pdata, 4);
2655 if (ret != GST_FLOW_OK)
2658 off = 4; /* skip fLaC marker */
2659 while (off < stream->codec_priv_size) {
2660 len = GST_READ_UINT8 (pdata + off + 1) << 16;
2661 len |= GST_READ_UINT8 (pdata + off + 2) << 8;
2662 len |= GST_READ_UINT8 (pdata + off + 3);
2664 GST_DEBUG_OBJECT (demux, "header packet: len=%u bytes, flags=0x%02x",
2665 len, (guint) pdata[off]);
2667 ret = gst_matroska_demux_push_hdr_buf (demux, stream, pdata + off, len + 4);
2668 if (ret != GST_FLOW_OK)
2676 static GstFlowReturn
2677 gst_matroska_demux_push_speex_codec_priv_data (GstMatroskaDemux * demux,
2678 GstMatroskaTrackContext * stream)
2683 GST_LOG_OBJECT (demux, "priv data size = %u", stream->codec_priv_size);
2685 pdata = (guint8 *) stream->codec_priv;
2687 /* need at least 'fLaC' marker + STREAMINFO metadata block */
2688 if (stream->codec_priv_size < 80) {
2689 GST_WARNING_OBJECT (demux, "not enough codec priv data for speex headers");
2690 return GST_FLOW_ERROR;
2693 if (memcmp (pdata, "Speex ", 8) != 0) {
2694 GST_WARNING_OBJECT (demux, "no Speex marker at start of stream headers");
2695 return GST_FLOW_ERROR;
2698 ret = gst_matroska_demux_push_hdr_buf (demux, stream, pdata, 80);
2699 if (ret != GST_FLOW_OK)
2702 if (stream->codec_priv_size == 80)
2705 return gst_matroska_demux_push_hdr_buf (demux, stream, pdata + 80,
2706 stream->codec_priv_size - 80);
2709 static GstFlowReturn
2710 gst_matroska_demux_push_xiph_codec_priv_data (GstMatroskaDemux * demux,
2711 GstMatroskaTrackContext * stream)
2714 guint8 *p = (guint8 *) stream->codec_priv;
2715 gint i, offset, num_packets;
2716 guint *length, last;
2718 if (stream->codec_priv == NULL || stream->codec_priv_size == 0) {
2719 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
2720 ("Missing codec private data for xiph headers, broken file"));
2721 return GST_FLOW_ERROR;
2724 /* start of the stream and vorbis audio or theora video, need to
2725 * send the codec_priv data as first three packets */
2726 num_packets = p[0] + 1;
2727 GST_DEBUG_OBJECT (demux, "%u stream headers, total length=%u bytes",
2728 (guint) num_packets, stream->codec_priv_size);
2730 length = g_alloca (num_packets * sizeof (guint));
2734 /* first packets, read length values */
2735 for (i = 0; i < num_packets - 1; i++) {
2737 while (offset < stream->codec_priv_size) {
2738 length[i] += p[offset];
2739 if (p[offset++] != 0xff)
2744 if (offset + last > stream->codec_priv_size)
2745 return GST_FLOW_ERROR;
2747 /* last packet is the remaining size */
2748 length[i] = stream->codec_priv_size - offset - last;
2750 for (i = 0; i < num_packets; i++) {
2751 GST_DEBUG_OBJECT (demux, "buffer %d: length=%u bytes", i,
2753 if (offset + length[i] > stream->codec_priv_size)
2754 return GST_FLOW_ERROR;
2757 gst_matroska_demux_push_hdr_buf (demux, stream, p + offset, length[i]);
2758 if (ret != GST_FLOW_OK)
2761 offset += length[i];
2767 gst_matroska_demux_push_dvd_clut_change_event (GstMatroskaDemux * demux,
2768 GstMatroskaTrackContext * stream)
2772 g_assert (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB));
2774 if (!stream->codec_priv)
2777 /* ideally, VobSub private data should be parsed and stored more convenient
2778 * elsewhere, but for now, only interested in a small part */
2780 /* make sure we have terminating 0 */
2781 buf = g_strndup ((gchar *) stream->codec_priv, stream->codec_priv_size);
2783 /* just locate and parse palette part */
2784 start = strstr (buf, "palette:");
2789 guint8 r, g, b, y, u, v;
2792 while (g_ascii_isspace (*start))
2794 for (i = 0; i < 16; i++) {
2795 if (sscanf (start, "%06x", &col) != 1)
2798 while ((*start == ',') || g_ascii_isspace (*start))
2800 /* sigh, need to convert this from vobsub pseudo-RGB to YUV */
2801 r = (col >> 16) & 0xff;
2802 g = (col >> 8) & 0xff;
2804 y = CLAMP ((0.1494 * r + 0.6061 * g + 0.2445 * b) * 219 / 255 + 16, 0,
2806 u = CLAMP (0.6066 * r - 0.4322 * g - 0.1744 * b + 128, 0, 255);
2807 v = CLAMP (-0.08435 * r - 0.3422 * g + 0.4266 * b + 128, 0, 255);
2808 clut[i] = (y << 16) | (u << 8) | v;
2811 /* got them all without problems; build and send event */
2815 s = gst_structure_new ("application/x-gst-dvd", "event", G_TYPE_STRING,
2816 "dvd-spu-clut-change", "clut00", G_TYPE_INT, clut[0], "clut01",
2817 G_TYPE_INT, clut[1], "clut02", G_TYPE_INT, clut[2], "clut03",
2818 G_TYPE_INT, clut[3], "clut04", G_TYPE_INT, clut[4], "clut05",
2819 G_TYPE_INT, clut[5], "clut06", G_TYPE_INT, clut[6], "clut07",
2820 G_TYPE_INT, clut[7], "clut08", G_TYPE_INT, clut[8], "clut09",
2821 G_TYPE_INT, clut[9], "clut10", G_TYPE_INT, clut[10], "clut11",
2822 G_TYPE_INT, clut[11], "clut12", G_TYPE_INT, clut[12], "clut13",
2823 G_TYPE_INT, clut[13], "clut14", G_TYPE_INT, clut[14], "clut15",
2824 G_TYPE_INT, clut[15], NULL);
2826 gst_pad_push_event (stream->pad,
2827 gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM, s));
2833 static GstFlowReturn
2834 gst_matroska_demux_add_mpeg_seq_header (GstElement * element,
2835 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2838 guint seq_header_len;
2841 if (stream->codec_state) {
2842 seq_header = stream->codec_state;
2843 seq_header_len = stream->codec_state_size;
2844 } else if (stream->codec_priv) {
2845 seq_header = stream->codec_priv;
2846 seq_header_len = stream->codec_priv_size;
2851 /* Sequence header only needed for keyframes */
2852 if (GST_BUFFER_FLAG_IS_SET (*buf, GST_BUFFER_FLAG_DELTA_UNIT))
2855 if (GST_BUFFER_SIZE (*buf) < 4)
2858 header = GST_READ_UINT32_BE (GST_BUFFER_DATA (*buf));
2859 /* Sequence start code, if not found prepend */
2860 if (header != 0x000001b3) {
2863 newbuf = gst_buffer_new_and_alloc (GST_BUFFER_SIZE (*buf) + seq_header_len);
2864 gst_buffer_set_caps (newbuf, stream->caps);
2866 GST_DEBUG_OBJECT (element, "Prepending MPEG sequence header");
2867 gst_buffer_copy_metadata (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
2868 GST_BUFFER_COPY_FLAGS);
2869 g_memmove (GST_BUFFER_DATA (newbuf), seq_header, seq_header_len);
2870 g_memmove (GST_BUFFER_DATA (newbuf) + seq_header_len,
2871 GST_BUFFER_DATA (*buf), GST_BUFFER_SIZE (*buf));
2872 gst_buffer_unref (*buf);
2879 static GstFlowReturn
2880 gst_matroska_demux_add_wvpk_header (GstElement * element,
2881 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2883 GstMatroskaTrackAudioContext *audiocontext =
2884 (GstMatroskaTrackAudioContext *) stream;
2885 GstBuffer *newbuf = NULL;
2895 wvh.version = GST_READ_UINT16_LE (stream->codec_priv);
2898 wvh.total_samples = -1;
2899 wvh.block_index = audiocontext->wvpk_block_index;
2901 if (audiocontext->channels <= 2) {
2902 guint32 block_samples;
2904 block_samples = GST_READ_UINT32_LE (GST_BUFFER_DATA (*buf));
2905 /* we need to reconstruct the header of the wavpack block */
2907 /* -20 because ck_size is the size of the wavpack block -8
2908 * and lace_size is the size of the wavpack block + 12
2909 * (the three guint32 of the header that already are in the buffer) */
2910 wvh.ck_size = GST_BUFFER_SIZE (*buf) + sizeof (Wavpack4Header) - 20;
2912 /* block_samples, flags and crc are already in the buffer */
2913 newlen = GST_BUFFER_SIZE (*buf) + sizeof (Wavpack4Header) - 12;
2914 newbuf = gst_buffer_new_and_alloc (newlen);
2915 gst_buffer_set_caps (newbuf, stream->caps);
2917 data = GST_BUFFER_DATA (newbuf);
2922 GST_WRITE_UINT32_LE (data + 4, wvh.ck_size);
2923 GST_WRITE_UINT16_LE (data + 8, wvh.version);
2924 GST_WRITE_UINT8 (data + 10, wvh.track_no);
2925 GST_WRITE_UINT8 (data + 11, wvh.index_no);
2926 GST_WRITE_UINT32_LE (data + 12, wvh.total_samples);
2927 GST_WRITE_UINT32_LE (data + 16, wvh.block_index);
2928 g_memmove (data + 20, GST_BUFFER_DATA (*buf), GST_BUFFER_SIZE (*buf));
2929 gst_buffer_copy_metadata (newbuf, *buf,
2930 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS);
2931 gst_buffer_unref (*buf);
2933 audiocontext->wvpk_block_index += block_samples;
2938 guint32 block_samples, flags, crc, blocksize;
2940 data = GST_BUFFER_DATA (*buf);
2941 size = GST_BUFFER_SIZE (*buf);
2944 GST_ERROR_OBJECT (element, "Too small wavpack buffer");
2945 return GST_FLOW_ERROR;
2948 block_samples = GST_READ_UINT32_LE (data);
2953 flags = GST_READ_UINT32_LE (data);
2956 crc = GST_READ_UINT32_LE (data);
2959 blocksize = GST_READ_UINT32_LE (data);
2963 if (blocksize == 0 || size < blocksize)
2966 if (newbuf == NULL) {
2967 newbuf = gst_buffer_new_and_alloc (sizeof (Wavpack4Header) + blocksize);
2968 gst_buffer_set_caps (newbuf, stream->caps);
2970 gst_buffer_copy_metadata (newbuf, *buf,
2971 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS);
2974 outdata = GST_BUFFER_DATA (newbuf);
2976 GST_BUFFER_SIZE (newbuf) += sizeof (Wavpack4Header) + blocksize;
2977 GST_BUFFER_DATA (newbuf) =
2978 g_realloc (GST_BUFFER_DATA (newbuf), GST_BUFFER_SIZE (newbuf));
2979 GST_BUFFER_MALLOCDATA (newbuf) = GST_BUFFER_DATA (newbuf);
2980 outdata = GST_BUFFER_DATA (newbuf);
2983 outdata[outpos] = 'w';
2984 outdata[outpos + 1] = 'v';
2985 outdata[outpos + 2] = 'p';
2986 outdata[outpos + 3] = 'k';
2989 GST_WRITE_UINT32_LE (outdata + outpos,
2990 blocksize + sizeof (Wavpack4Header) - 8);
2991 GST_WRITE_UINT16_LE (outdata + outpos + 4, wvh.version);
2992 GST_WRITE_UINT8 (outdata + outpos + 6, wvh.track_no);
2993 GST_WRITE_UINT8 (outdata + outpos + 7, wvh.index_no);
2994 GST_WRITE_UINT32_LE (outdata + outpos + 8, wvh.total_samples);
2995 GST_WRITE_UINT32_LE (outdata + outpos + 12, wvh.block_index);
2996 GST_WRITE_UINT32_LE (outdata + outpos + 16, block_samples);
2997 GST_WRITE_UINT32_LE (outdata + outpos + 20, flags);
2998 GST_WRITE_UINT32_LE (outdata + outpos + 24, crc);
3001 g_memmove (outdata + outpos, data, blocksize);
3002 outpos += blocksize;
3006 gst_buffer_unref (*buf);
3008 audiocontext->wvpk_block_index += block_samples;
3014 /* @text must be null-terminated */
3016 gst_matroska_demux_subtitle_chunk_has_tag (GstElement * element,
3021 /* yes, this might all lead to false positives ... */
3022 tag = (gchar *) text;
3023 while ((tag = strchr (tag, '<'))) {
3025 if (*tag != '\0' && *(tag + 1) == '>') {
3026 /* some common convenience ones */
3027 /* maybe any character will do here ? */
3040 if (strstr (text, "<span"))
3046 static GstFlowReturn
3047 gst_matroska_demux_check_subtitle_buffer (GstElement * element,
3048 GstMatroskaTrackContext * stream, GstBuffer ** buf)
3050 GstMatroskaTrackSubtitleContext *sub_stream;
3051 const gchar *encoding, *data;
3057 sub_stream = (GstMatroskaTrackSubtitleContext *) stream;
3059 data = (const gchar *) GST_BUFFER_DATA (*buf);
3060 size = GST_BUFFER_SIZE (*buf);
3062 if (!sub_stream->invalid_utf8) {
3063 if (g_utf8_validate (data, size, NULL)) {
3066 GST_WARNING_OBJECT (element, "subtitle stream %d is not valid UTF-8, this "
3067 "is broken according to the matroska specification", stream->num);
3068 sub_stream->invalid_utf8 = TRUE;
3071 /* file with broken non-UTF8 subtitle, do the best we can do to fix it */
3072 encoding = g_getenv ("GST_SUBTITLE_ENCODING");
3073 if (encoding == NULL || *encoding == '\0') {
3074 /* if local encoding is UTF-8 and no encoding specified
3075 * via the environment variable, assume ISO-8859-15 */
3076 if (g_get_charset (&encoding)) {
3077 encoding = "ISO-8859-15";
3081 utf8 = g_convert_with_fallback (data, size, "UTF-8", encoding, (char *) "*",
3085 GST_LOG_OBJECT (element, "could not convert string from '%s' to UTF-8: %s",
3086 encoding, err->message);
3090 /* invalid input encoding, fall back to ISO-8859-15 (always succeeds) */
3091 encoding = "ISO-8859-15";
3092 utf8 = g_convert_with_fallback (data, size, "UTF-8", encoding, (char *) "*",
3096 GST_LOG_OBJECT (element, "converted subtitle text from %s to UTF-8 %s",
3097 encoding, (err) ? "(using ISO-8859-15 as fallback)" : "");
3100 utf8 = g_strdup ("invalid subtitle");
3102 newbuf = gst_buffer_new ();
3103 GST_BUFFER_MALLOCDATA (newbuf) = (guint8 *) utf8;
3104 GST_BUFFER_DATA (newbuf) = (guint8 *) utf8;
3105 GST_BUFFER_SIZE (newbuf) = strlen (utf8);
3106 gst_buffer_copy_metadata (newbuf, *buf, GST_BUFFER_COPY_ALL);
3107 gst_buffer_unref (*buf);
3110 data = (const gchar *) GST_BUFFER_DATA (*buf);
3111 size = GST_BUFFER_SIZE (*buf);
3115 if (sub_stream->check_markup) {
3116 /* caps claim markup text, so we need to escape text,
3117 * except if text is already markup and then needs no further escaping */
3118 sub_stream->seen_markup_tag = sub_stream->seen_markup_tag ||
3119 gst_matroska_demux_subtitle_chunk_has_tag (element, data);
3121 if (!sub_stream->seen_markup_tag) {
3122 utf8 = g_markup_escape_text (data, size);
3124 newbuf = gst_buffer_new ();
3125 GST_BUFFER_MALLOCDATA (newbuf) = (guint8 *) utf8;
3126 GST_BUFFER_DATA (newbuf) = (guint8 *) utf8;
3127 GST_BUFFER_SIZE (newbuf) = strlen (utf8);
3128 gst_buffer_copy_metadata (newbuf, *buf, GST_BUFFER_COPY_ALL);
3129 gst_buffer_unref (*buf);
3138 static GstFlowReturn
3139 gst_matroska_demux_check_aac (GstElement * element,
3140 GstMatroskaTrackContext * stream, GstBuffer ** buf)
3145 data = GST_BUFFER_DATA (*buf);
3146 size = GST_BUFFER_SIZE (*buf);
3148 if (size > 2 && data[0] == 0xff && (data[1] >> 4 == 0x0f)) {
3152 /* tss, ADTS data, remove codec_data
3153 * still assume it is at least parsed */
3154 new_caps = gst_caps_copy (stream->caps);
3155 s = gst_caps_get_structure (new_caps, 0);
3157 gst_structure_remove_field (s, "codec_data");
3158 gst_caps_replace (&stream->caps, new_caps);
3159 gst_pad_set_caps (stream->pad, new_caps);
3160 gst_buffer_set_caps (*buf, new_caps);
3161 GST_DEBUG_OBJECT (element, "ADTS AAC audio data; removing codec-data, "
3162 "new caps: %" GST_PTR_FORMAT, new_caps);
3163 gst_caps_unref (new_caps);
3166 /* disable subsequent checking */
3167 stream->postprocess_frame = NULL;
3172 static GstFlowReturn
3173 gst_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux,
3174 GstEbmlRead * ebml, guint64 cluster_time, guint64 cluster_offset,
3175 gboolean is_simpleblock)
3177 GstMatroskaTrackContext *stream = NULL;
3178 GstFlowReturn ret = GST_FLOW_OK;
3179 gboolean readblock = FALSE;
3181 guint64 block_duration = -1;
3182 GstBuffer *buf = NULL;
3183 gint stream_num = -1, n, laces = 0;
3185 gint *lace_size = NULL;
3188 gint64 referenceblock = 0;
3191 offset = gst_ebml_read_get_offset (ebml);
3193 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3194 if (!is_simpleblock) {
3195 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK) {
3199 id = GST_MATROSKA_ID_SIMPLEBLOCK;
3203 /* one block inside the group. Note, block parsing is one
3204 * of the harder things, so this code is a bit complicated.
3205 * See http://www.matroska.org/ for documentation. */
3206 case GST_MATROSKA_ID_SIMPLEBLOCK:
3207 case GST_MATROSKA_ID_BLOCK:
3213 gst_buffer_unref (buf);
3216 if ((ret = gst_ebml_read_buffer (ebml, &id, &buf)) != GST_FLOW_OK)
3219 data = GST_BUFFER_DATA (buf);
3220 size = GST_BUFFER_SIZE (buf);
3222 /* first byte(s): blocknum */
3223 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
3228 /* fetch stream from num */
3229 stream_num = gst_matroska_read_common_stream_from_num (&demux->common,
3231 if (G_UNLIKELY (size < 3)) {
3232 GST_WARNING_OBJECT (demux, "Invalid size %u", size);
3233 /* non-fatal, try next block(group) */
3236 } else if (G_UNLIKELY (stream_num < 0 ||
3237 stream_num >= demux->common.num_streams)) {
3238 /* let's not give up on a stray invalid track number */
3239 GST_WARNING_OBJECT (demux,
3240 "Invalid stream %d for track number %" G_GUINT64_FORMAT
3241 "; ignoring block", stream_num, num);
3245 stream = g_ptr_array_index (demux->common.src, stream_num);
3247 #ifdef MKV_DEMUX_MODIFICATION
3248 if (demux->common.segment.rate < 0.0) {
3249 if ((stream_num+1) == GST_MATROSKA_TRACK_TYPE_AUDIO) {
3250 /* found at least one audio block */
3251 demux->found_audioframe = TRUE;
3256 /* time (relative to cluster time) */
3257 time = ((gint16) GST_READ_UINT16_BE (data));
3260 flags = GST_READ_UINT8 (data);
3264 GST_LOG_OBJECT (demux, "time %" G_GUINT64_FORMAT ", flags %d", time,
3267 switch ((flags & 0x06) >> 1) {
3268 case 0x0: /* no lacing */
3270 lace_size = g_new (gint, 1);
3271 lace_size[0] = size;
3274 case 0x1: /* xiph lacing */
3275 case 0x2: /* fixed-size lacing */
3276 case 0x3: /* EBML lacing */
3278 goto invalid_lacing;
3279 laces = GST_READ_UINT8 (data) + 1;
3282 lace_size = g_new0 (gint, laces);
3284 switch ((flags & 0x06) >> 1) {
3285 case 0x1: /* xiph lacing */ {
3286 guint temp, total = 0;
3288 for (n = 0; ret == GST_FLOW_OK && n < laces - 1; n++) {
3291 goto invalid_lacing;
3292 temp = GST_READ_UINT8 (data);
3293 lace_size[n] += temp;
3299 total += lace_size[n];
3301 lace_size[n] = size - total;
3305 case 0x2: /* fixed-size lacing */
3306 for (n = 0; n < laces; n++)
3307 lace_size[n] = size / laces;
3310 case 0x3: /* EBML lacing */ {
3313 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
3317 total = lace_size[0] = num;
3318 for (n = 1; ret == GST_FLOW_OK && n < laces - 1; n++) {
3322 if ((r = gst_matroska_ebmlnum_sint (data, size, &snum)) < 0)
3326 lace_size[n] = lace_size[n - 1] + snum;
3327 total += lace_size[n];
3330 lace_size[n] = size - total;
3337 if (stream->send_xiph_headers) {
3338 ret = gst_matroska_demux_push_xiph_codec_priv_data (demux, stream);
3339 stream->send_xiph_headers = FALSE;
3342 if (stream->send_flac_headers) {
3343 ret = gst_matroska_demux_push_flac_codec_priv_data (demux, stream);
3344 stream->send_flac_headers = FALSE;
3347 if (stream->send_speex_headers) {
3348 ret = gst_matroska_demux_push_speex_codec_priv_data (demux, stream);
3349 stream->send_speex_headers = FALSE;
3352 if (stream->send_dvd_event) {
3353 gst_matroska_demux_push_dvd_clut_change_event (demux, stream);
3354 /* FIXME: should we send this event again after (flushing) seek ? */
3355 stream->send_dvd_event = FALSE;
3358 if (ret != GST_FLOW_OK)
3365 case GST_MATROSKA_ID_BLOCKDURATION:{
3366 ret = gst_ebml_read_uint (ebml, &id, &block_duration);
3367 GST_DEBUG_OBJECT (demux, "BlockDuration: %" G_GUINT64_FORMAT,
3372 case GST_MATROSKA_ID_REFERENCEBLOCK:{
3373 ret = gst_ebml_read_sint (ebml, &id, &referenceblock);
3374 GST_DEBUG_OBJECT (demux, "ReferenceBlock: %" G_GINT64_FORMAT,
3379 case GST_MATROSKA_ID_CODECSTATE:{
3381 guint64 data_len = 0;
3384 gst_ebml_read_binary (ebml, &id, &data,
3385 &data_len)) != GST_FLOW_OK)
3388 if (G_UNLIKELY (stream == NULL)) {
3389 GST_WARNING_OBJECT (demux,
3390 "Unexpected CodecState subelement - ignoring");
3394 g_free (stream->codec_state);
3395 stream->codec_state = data;
3396 stream->codec_state_size = data_len;
3398 /* Decode if necessary */
3399 if (stream->encodings && stream->encodings->len > 0
3400 && stream->codec_state && stream->codec_state_size > 0) {
3401 if (!gst_matroska_decode_data (stream->encodings,
3402 &stream->codec_state, &stream->codec_state_size,
3403 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
3404 GST_WARNING_OBJECT (demux, "Decoding codec state failed");
3408 GST_DEBUG_OBJECT (demux, "CodecState of %u bytes",
3409 stream->codec_state_size);
3414 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3418 case GST_MATROSKA_ID_BLOCKVIRTUAL:
3419 case GST_MATROSKA_ID_BLOCKADDITIONS:
3420 case GST_MATROSKA_ID_REFERENCEPRIORITY:
3421 case GST_MATROSKA_ID_REFERENCEVIRTUAL:
3422 case GST_MATROSKA_ID_SLICES:
3423 GST_DEBUG_OBJECT (demux,
3424 "Skipping BlockGroup subelement 0x%x - ignoring", id);
3425 ret = gst_ebml_read_skip (ebml);
3433 /* reading a number or so could have failed */
3434 if (ret != GST_FLOW_OK)
3437 if (ret == GST_FLOW_OK && readblock) {
3438 guint64 duration = 0;
3439 gint64 lace_time = 0;
3440 gboolean delta_unit;
3442 stream = g_ptr_array_index (demux->common.src, stream_num);
3444 if (cluster_time != GST_CLOCK_TIME_NONE) {
3445 /* FIXME: What to do with negative timestamps? Give timestamp 0 or -1?
3446 * Drop unless the lace contains timestamp 0? */
3447 if (time < 0 && (-time) > cluster_time) {
3450 if (stream->timecodescale == 1.0)
3451 lace_time = (cluster_time + time) * demux->common.time_scale;
3454 gst_util_guint64_to_gdouble ((cluster_time + time) *
3455 demux->common.time_scale) * stream->timecodescale;
3458 lace_time = GST_CLOCK_TIME_NONE;
3461 /* need to refresh segment info ASAP */
3462 if (GST_CLOCK_TIME_IS_VALID (lace_time) && demux->need_newsegment) {
3465 GST_DEBUG_OBJECT (demux,
3466 "generating segment starting at %" GST_TIME_FORMAT,
3467 GST_TIME_ARGS (lace_time));
3468 if (!GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
3469 demux->stream_start_time = lace_time;
3470 GST_DEBUG_OBJECT (demux,
3471 "Setting stream start time to %" GST_TIME_FORMAT,
3472 GST_TIME_ARGS (lace_time));
3474 clace_time = MAX (lace_time, demux->stream_start_time);
3475 gst_segment_set_newsegment (&demux->common.segment, FALSE,
3476 demux->common.segment.rate, GST_FORMAT_TIME, clace_time,
3477 GST_CLOCK_TIME_NONE, clace_time - demux->stream_start_time);
3478 /* now convey our segment notion downstream */
3479 gst_matroska_demux_send_event (demux, gst_event_new_new_segment (FALSE,
3480 demux->common.segment.rate, demux->common.segment.format,
3481 demux->common.segment.start, demux->common.segment.stop,
3482 demux->common.segment.start));
3483 demux->need_newsegment = FALSE;
3486 if (block_duration != -1) {
3487 if (stream->timecodescale == 1.0)
3488 duration = gst_util_uint64_scale (block_duration,
3489 demux->common.time_scale, 1);
3492 gst_util_gdouble_to_guint64 (gst_util_guint64_to_gdouble
3493 (gst_util_uint64_scale (block_duration, demux->common.time_scale,
3494 1)) * stream->timecodescale);
3495 } else if (stream->default_duration) {
3496 duration = stream->default_duration * laces;
3498 /* else duration is diff between timecode of this and next block */
3500 /* For SimpleBlock, look at the keyframe bit in flags. Otherwise,
3501 a ReferenceBlock implies that this is not a keyframe. In either
3502 case, it only makes sense for video streams. */
3503 delta_unit = stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
3504 ((is_simpleblock && !(flags & 0x80)) || referenceblock);
3506 if (delta_unit && stream->set_discont) {
3507 /* When doing seeks or such, we need to restart on key frames or
3508 * decoders might choke. */
3509 GST_DEBUG_OBJECT (demux, "skipping delta unit");
3513 for (n = 0; n < laces; n++) {
3515 #ifdef MKV_DEMUX_MODIFICATION
3516 gboolean skip_flag = FALSE;
3519 if (G_UNLIKELY (lace_size[n] > size)) {
3520 GST_WARNING_OBJECT (demux, "Invalid lace size");
3524 /* QoS for video track with an index. the assumption is that
3525 index entries point to keyframes, but if that is not true we
3526 will instad skip until the next keyframe. */
3527 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
3528 stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
3529 stream->index_table && demux->common.segment.rate > 0.0) {
3530 GstMatroskaTrackVideoContext *videocontext =
3531 (GstMatroskaTrackVideoContext *) stream;
3532 GstClockTime earliest_time;
3533 GstClockTime earliest_stream_time;
3535 GST_OBJECT_LOCK (demux);
3536 earliest_time = videocontext->earliest_time;
3537 GST_OBJECT_UNLOCK (demux);
3538 earliest_stream_time = gst_segment_to_position (&demux->common.segment,
3539 GST_FORMAT_TIME, earliest_time);
3541 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
3542 GST_CLOCK_TIME_IS_VALID (earliest_stream_time) &&
3543 lace_time <= earliest_stream_time) {
3544 /* find index entry (keyframe) <= earliest_stream_time */
3545 GstMatroskaIndex *entry =
3546 gst_util_array_binary_search (stream->index_table->data,
3547 stream->index_table->len, sizeof (GstMatroskaIndex),
3548 (GCompareDataFunc) gst_matroska_index_seek_find,
3549 GST_SEARCH_MODE_BEFORE, &earliest_stream_time, NULL);
3551 /* if that entry (keyframe) is after the current the current
3552 buffer, we can skip pushing (and thus decoding) all
3553 buffers until that keyframe. */
3554 if (entry && GST_CLOCK_TIME_IS_VALID (entry->time) &&
3555 entry->time > lace_time) {
3556 GST_LOG_OBJECT (demux, "Skipping lace before late keyframe");
3557 stream->set_discont = TRUE;
3563 sub = gst_buffer_create_sub (buf,
3564 GST_BUFFER_SIZE (buf) - size, lace_size[n]);
3565 GST_DEBUG_OBJECT (demux, "created subbuffer %p", sub);
3568 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
3570 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
3572 if (stream->encodings != NULL && stream->encodings->len > 0)
3573 sub = gst_matroska_decode_buffer (stream, sub);
3576 GST_WARNING_OBJECT (demux, "Decoding buffer failed");
3580 GST_BUFFER_TIMESTAMP (sub) = lace_time;
3582 if (GST_CLOCK_TIME_IS_VALID (lace_time)) {
3583 GstClockTime last_stop_end;
3585 #ifndef MKV_DEMUX_MODIFICATION
3586 /* Check if this stream is after segment stop */
3587 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop) &&
3588 lace_time >= demux->common.segment.stop) {
3589 GST_DEBUG_OBJECT (demux,
3590 "Stream %d after segment stop %" GST_TIME_FORMAT, stream->index,
3591 GST_TIME_ARGS (demux->common.segment.stop));
3592 gst_buffer_unref (sub);
3595 if (offset >= stream->to_offset) {
3596 GST_DEBUG_OBJECT (demux, "Stream %d after playback section",
3598 gst_buffer_unref (sub);
3603 /* handle gaps, e.g. non-zero start-time, or an cue index entry
3604 * that landed us with timestamps not quite intended */
3605 GST_OBJECT_LOCK (demux);
3606 if (demux->max_gap_time &&
3607 #ifdef MKV_DEMUX_MODIFICATION
3608 GST_CLOCK_TIME_IS_VALID (/*demux->last_stop_end*/demux->common.segment.last_stop) &&
3609 demux->common.segment.rate > 0.0) {
3611 GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) &&
3612 demux->common.segment.rate > 0.0) {
3615 GstClockTimeDiff diff;
3616 GstEvent *event1, *event2;
3618 /* only send newsegments with increasing start times,
3619 * otherwise if these go back and forth downstream (sinks) increase
3620 * accumulated time and running_time */
3621 #ifdef MKV_DEMUX_MODIFICATION
3622 diff = GST_CLOCK_DIFF (/*demux->last_stop_end*/demux->common.segment.last_stop, lace_time);
3624 diff = GST_CLOCK_DIFF (demux->last_stop_end, lace_time);
3626 if (diff > 0 && diff > demux->max_gap_time
3627 && lace_time > demux->common.segment.start
3628 && (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop)
3629 || lace_time < demux->common.segment.stop)) {
3630 GST_DEBUG_OBJECT (demux,
3631 "Gap of %" G_GINT64_FORMAT " ns detected in"
3632 "stream %d (%" GST_TIME_FORMAT " -> %" GST_TIME_FORMAT "). "
3633 "Sending updated NEWSEGMENT events", diff,
3634 stream->index, GST_TIME_ARGS (stream->pos),
3635 GST_TIME_ARGS (lace_time));
3636 /* send newsegment events such that the gap is not accounted in
3637 * accum time, hence running_time */
3638 /* close ahead of gap */
3639 event1 = gst_event_new_new_segment (TRUE,
3640 demux->common.segment.rate, demux->common.segment.format,
3641 demux->last_stop_end, demux->last_stop_end,
3642 demux->last_stop_end);
3644 event2 = gst_event_new_new_segment (FALSE,
3645 demux->common.segment.rate,
3646 demux->common.segment.format, lace_time,
3647 demux->common.segment.stop, lace_time);
3648 GST_OBJECT_UNLOCK (demux);
3649 gst_matroska_demux_send_event (demux, event1);
3650 gst_matroska_demux_send_event (demux, event2);
3651 GST_OBJECT_LOCK (demux);
3652 /* align segment view with downstream,
3653 * prevents double-counting accum when closing segment */
3654 gst_segment_set_newsegment (&demux->common.segment, FALSE,
3655 demux->common.segment.rate, demux->common.segment.format,
3656 lace_time, demux->common.segment.stop, lace_time);
3657 demux->common.segment.last_stop = lace_time;
3661 if (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.last_stop)
3662 || demux->common.segment.last_stop < lace_time) {
3663 demux->common.segment.last_stop = lace_time;
3665 GST_OBJECT_UNLOCK (demux);
3667 last_stop_end = lace_time;
3669 GST_BUFFER_DURATION (sub) = duration / laces;
3670 last_stop_end += GST_BUFFER_DURATION (sub);
3673 if (!GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) ||
3674 demux->last_stop_end < last_stop_end)
3675 demux->last_stop_end = last_stop_end;
3677 GST_OBJECT_LOCK (demux);
3678 if (demux->common.segment.duration == -1 ||
3679 demux->stream_start_time + demux->common.segment.duration <
3681 gst_segment_set_duration (&demux->common.segment, GST_FORMAT_TIME,
3682 last_stop_end - demux->stream_start_time);
3683 GST_OBJECT_UNLOCK (demux);
3684 if (!demux->invalid_duration) {
3685 gst_element_post_message (GST_ELEMENT_CAST (demux),
3686 gst_message_new_duration (GST_OBJECT_CAST (demux),
3687 GST_FORMAT_TIME, GST_CLOCK_TIME_NONE));
3688 demux->invalid_duration = TRUE;
3691 GST_OBJECT_UNLOCK (demux);
3695 stream->pos = lace_time;
3697 gst_matroska_demux_sync_streams (demux);
3699 if (stream->set_discont) {
3700 GST_DEBUG_OBJECT (demux, "marking DISCONT");
3701 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DISCONT);
3702 stream->set_discont = FALSE;
3705 /* reverse playback book-keeping */
3706 if (!GST_CLOCK_TIME_IS_VALID (stream->from_time))
3707 stream->from_time = lace_time;
3708 if (stream->from_offset == -1)
3709 stream->from_offset = offset;
3711 #ifdef MKV_DEMUX_MODIFICATION
3712 if ((demux->common.segment.rate < 0.0) && ((stream_num+1) == GST_MATROSKA_TRACK_TYPE_VIDEO)) {
3713 if (GST_BUFFER_FLAG_IS_SET (sub, GST_BUFFER_FLAG_DELTA_UNIT)) {
3714 GST_DEBUG_OBJECT (demux, "skipping delta unit");
3715 gst_buffer_unref (sub);
3718 /* found key frame*/
3719 demux->found_videokeyframe = TRUE;
3722 demux->current_ts = GST_BUFFER_TIMESTAMP (sub);
3725 GST_DEBUG_OBJECT (demux,
3726 "Pushing lace %d, data of size %d for stream %d, time=%"
3727 GST_TIME_FORMAT " and duration=%" GST_TIME_FORMAT, n,
3728 GST_BUFFER_SIZE (sub), stream_num,
3729 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (sub)),
3730 GST_TIME_ARGS (GST_BUFFER_DURATION (sub)));
3732 if (demux->common.element_index) {
3733 if (stream->index_writer_id == -1)
3734 gst_index_get_writer_id (demux->common.element_index,
3735 GST_OBJECT (stream->pad), &stream->index_writer_id);
3737 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
3738 G_GUINT64_FORMAT " for writer id %d",
3739 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (sub)), cluster_offset,
3740 stream->index_writer_id);
3741 gst_index_add_association (demux->common.element_index,
3742 stream->index_writer_id, GST_BUFFER_FLAG_IS_SET (sub,
3743 GST_BUFFER_FLAG_DELTA_UNIT) ? 0 : GST_ASSOCIATION_FLAG_KEY_UNIT,
3744 GST_FORMAT_TIME, GST_BUFFER_TIMESTAMP (sub), GST_FORMAT_BYTES,
3745 cluster_offset, NULL);
3748 gst_buffer_set_caps (sub, GST_PAD_CAPS (stream->pad));
3750 /* Postprocess the buffers depending on the codec used */
3751 if (stream->postprocess_frame) {
3752 GST_LOG_OBJECT (demux, "running post process");
3753 ret = stream->postprocess_frame (GST_ELEMENT (demux), stream, &sub);
3756 #ifdef MKV_DEMUX_MODIFICATION
3757 if (demux->video && demux->common.segment.rate > 1.0
3758 && stream->type <= GST_MATROSKA_TRACK_TYPE_AUDIO) {
3760 if(GST_BUFFER_TIMESTAMP(sub) >= demux->common.segment.start) {
3761 GST_BUFFER_FLAG_UNSET(sub, GST_BUFFER_FLAG_DELTA_UNIT);
3762 GST_INFO("Entering into forward Trickplay");
3763 ret = gst_matroska_demux_forward_trickplay (demux, stream, sub, &skip_flag);
3765 if (skip_flag == FALSE) {
3766 GST_INFO("buffer pushed %"GST_TIME_FORMAT, GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(sub)));
3767 ret = gst_pad_push (stream->pad, sub);
3769 GST_INFO("Unreffing the buffer %"GST_TIME_FORMAT, GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(sub)));
3770 gst_buffer_unref (sub);
3772 } else if (demux->common.segment.rate < 0.0) {
3773 ret = gst_matroska_demux_backward_trickplay (demux, stream, sub);
3777 /* At this point, we have a sub-buffer pointing at data within a larger
3778 buffer. This data might not be aligned with anything. If the data is
3779 raw samples though, we want it aligned to the raw type (eg, 4 bytes
3780 for 32 bit samples, etc), or bad things will happen downstream as
3781 elements typically assume minimal alignment.
3782 Therefore, create an aligned copy if necessary. */
3783 g_assert (stream->alignment <= G_MEM_ALIGN);
3784 if (((guintptr) GST_BUFFER_DATA (sub)) & (stream->alignment - 1)) {
3785 GstBuffer *buffer = gst_buffer_new_and_alloc (GST_BUFFER_SIZE (sub));
3786 memcpy (GST_BUFFER_DATA (buffer), GST_BUFFER_DATA (sub),
3787 GST_BUFFER_SIZE (sub));
3788 gst_buffer_copy_metadata (buffer, sub, GST_BUFFER_COPY_ALL);
3789 GST_DEBUG_OBJECT (demux, "We want output aligned on %d, reallocated",
3791 gst_buffer_unref (sub);
3795 ret = gst_pad_push (stream->pad, sub);
3798 if (demux->common.segment.rate < 0) {
3799 if (lace_time > demux->common.segment.stop
3800 && ret == GST_FLOW_UNEXPECTED) {
3801 /* In reverse playback we can get a GST_FLOW_UNEXPECTED when
3802 * we are at the end of the segment, so we just need to jump
3803 * back to the previous section. */
3804 GST_DEBUG_OBJECT (demux, "downstream has reached end of segment");
3809 ret = gst_matroska_demux_combine_flows (demux, stream, ret);
3812 size -= lace_size[n];
3813 if (lace_time != GST_CLOCK_TIME_NONE && duration)
3814 lace_time += duration / laces;
3816 lace_time = GST_CLOCK_TIME_NONE;
3822 gst_buffer_unref (buf);
3833 ret = gst_matroska_demux_combine_flows (demux, stream, ret);
3838 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Invalid lacing size"));
3839 /* non-fatal, try next block(group) */
3845 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Data error"));
3846 /* non-fatal, try next block(group) */
3852 /* return FALSE if block(group) should be skipped (due to a seek) */
3853 static inline gboolean
3854 gst_matroska_demux_seek_block (GstMatroskaDemux * demux)
3856 if (G_UNLIKELY (demux->seek_block)) {
3857 if (!(--demux->seek_block)) {
3860 GST_LOG_OBJECT (demux, "should skip block due to seek");
3868 static GstFlowReturn
3869 gst_matroska_demux_parse_contents_seekentry (GstMatroskaDemux * demux,
3873 guint64 seek_pos = (guint64) - 1;
3874 guint32 seek_id = 0;
3877 DEBUG_ELEMENT_START (demux, ebml, "Seek");
3879 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3880 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
3884 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3885 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3889 case GST_MATROSKA_ID_SEEKID:
3893 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
3896 GST_DEBUG_OBJECT (demux, "SeekID: %" G_GUINT64_FORMAT, t);
3901 case GST_MATROSKA_ID_SEEKPOSITION:
3905 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
3908 if (t > G_MAXINT64) {
3909 GST_WARNING_OBJECT (demux,
3910 "Too large SeekPosition %" G_GUINT64_FORMAT, t);
3914 GST_DEBUG_OBJECT (demux, "SeekPosition: %" G_GUINT64_FORMAT, t);
3920 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3926 if (ret != GST_FLOW_OK && ret != GST_FLOW_UNEXPECTED)
3929 if (!seek_id || seek_pos == (guint64) - 1) {
3930 GST_WARNING_OBJECT (demux, "Incomplete seekhead entry (0x%x/%"
3931 G_GUINT64_FORMAT ")", seek_id, seek_pos);
3936 case GST_MATROSKA_ID_SEEKHEAD:
3939 case GST_MATROSKA_ID_CUES:
3940 case GST_MATROSKA_ID_TAGS:
3941 case GST_MATROSKA_ID_TRACKS:
3942 case GST_MATROSKA_ID_SEGMENTINFO:
3943 case GST_MATROSKA_ID_ATTACHMENTS:
3944 case GST_MATROSKA_ID_CHAPTERS:
3946 guint64 before_pos, length;
3950 length = gst_matroska_read_common_get_length (&demux->common);
3951 before_pos = demux->common.offset;
3953 if (length == (guint64) - 1) {
3954 GST_DEBUG_OBJECT (demux, "no upstream length, skipping SeakHead entry");
3958 /* check for validity */
3959 if (seek_pos + demux->common.ebml_segment_start + 12 >= length) {
3960 GST_WARNING_OBJECT (demux,
3961 "SeekHead reference lies outside file!" " (%"
3962 G_GUINT64_FORMAT "+%" G_GUINT64_FORMAT "+12 >= %"
3963 G_GUINT64_FORMAT ")", seek_pos, demux->common.ebml_segment_start,
3968 /* only pick up index location when streaming */
3969 if (demux->streaming) {
3970 if (seek_id == GST_MATROSKA_ID_CUES) {
3971 demux->index_offset = seek_pos + demux->common.ebml_segment_start;
3972 GST_DEBUG_OBJECT (demux, "Cues located at offset %" G_GUINT64_FORMAT,
3973 demux->index_offset);
3979 demux->common.offset = seek_pos + demux->common.ebml_segment_start;
3982 if ((ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
3983 GST_ELEMENT_CAST (demux), &id, &length, &needed)) !=
3987 if (id != seek_id) {
3988 GST_WARNING_OBJECT (demux,
3989 "We looked for ID=0x%x but got ID=0x%x (pos=%" G_GUINT64_FORMAT ")",
3990 seek_id, id, seek_pos + demux->common.ebml_segment_start);
3993 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
3998 demux->common.offset = before_pos;
4002 case GST_MATROSKA_ID_CLUSTER:
4004 guint64 pos = seek_pos + demux->common.ebml_segment_start;
4006 GST_LOG_OBJECT (demux, "Cluster position");
4007 if (G_UNLIKELY (!demux->clusters))
4008 demux->clusters = g_array_sized_new (TRUE, TRUE, sizeof (guint64), 100);
4009 g_array_append_val (demux->clusters, pos);
4014 GST_DEBUG_OBJECT (demux, "Ignoring Seek entry for ID=0x%x", seek_id);
4017 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
4022 static GstFlowReturn
4023 gst_matroska_demux_parse_contents (GstMatroskaDemux * demux, GstEbmlRead * ebml)
4025 GstFlowReturn ret = GST_FLOW_OK;
4028 DEBUG_ELEMENT_START (demux, ebml, "SeekHead");
4030 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
4031 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
4035 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
4036 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
4040 case GST_MATROSKA_ID_SEEKENTRY:
4042 ret = gst_matroska_demux_parse_contents_seekentry (demux, ebml);
4043 /* Ignore EOS and errors here */
4044 if (ret != GST_FLOW_OK) {
4045 GST_DEBUG_OBJECT (demux, "Ignoring %s", gst_flow_get_name (ret));
4052 ret = gst_matroska_read_common_parse_skip (&demux->common,
4053 ebml, "SeekHead", id);
4058 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
4060 /* Sort clusters by position for easier searching */
4061 if (demux->clusters)
4062 g_array_sort (demux->clusters, (GCompareFunc) gst_matroska_cluster_compare);
4067 #define GST_FLOW_OVERFLOW GST_FLOW_CUSTOM_ERROR
4069 #define MAX_BLOCK_SIZE (15 * 1024 * 1024)
4071 static inline GstFlowReturn
4072 gst_matroska_demux_check_read_size (GstMatroskaDemux * demux, guint64 bytes)
4074 if (G_UNLIKELY (bytes > MAX_BLOCK_SIZE)) {
4075 /* only a few blocks are expected/allowed to be large,
4076 * and will be recursed into, whereas others will be read and must fit */
4077 if (demux->streaming) {
4078 /* fatal in streaming case, as we can't step over easily */
4079 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4080 ("reading large block of size %" G_GUINT64_FORMAT " not supported; "
4081 "file might be corrupt.", bytes));
4082 return GST_FLOW_ERROR;
4084 /* indicate higher level to quietly give up */
4085 GST_DEBUG_OBJECT (demux,
4086 "too large block of size %" G_GUINT64_FORMAT, bytes);
4087 return GST_FLOW_ERROR;
4094 /* returns TRUE if we truely are in error state, and should give up */
4095 static inline gboolean
4096 gst_matroska_demux_check_parse_error (GstMatroskaDemux * demux)
4098 if (!demux->streaming && demux->next_cluster_offset > 0) {
4099 /* just repositioning to where next cluster should be and try from there */
4100 GST_WARNING_OBJECT (demux, "parse error, trying next cluster expected at %"
4101 G_GUINT64_FORMAT, demux->next_cluster_offset);
4102 demux->common.offset = demux->next_cluster_offset;
4103 demux->next_cluster_offset = 0;
4108 /* sigh, one last attempt above and beyond call of duty ...;
4109 * search for cluster mark following current pos */
4110 pos = demux->common.offset;
4111 GST_WARNING_OBJECT (demux, "parse error, looking for next cluster");
4112 if (gst_matroska_demux_search_cluster (demux, &pos) != GST_FLOW_OK) {
4113 /* did not work, give up */
4116 GST_DEBUG_OBJECT (demux, "... found at %" G_GUINT64_FORMAT, pos);
4117 /* try that position */
4118 demux->common.offset = pos;
4124 static inline GstFlowReturn
4125 gst_matroska_demux_flush (GstMatroskaDemux * demux, guint flush)
4127 GST_LOG_OBJECT (demux, "skipping %d bytes", flush);
4128 demux->common.offset += flush;
4129 if (demux->streaming) {
4132 /* hard to skip large blocks when streaming */
4133 ret = gst_matroska_demux_check_read_size (demux, flush);
4134 if (ret != GST_FLOW_OK)
4136 if (flush <= gst_adapter_available (demux->common.adapter))
4137 gst_adapter_flush (demux->common.adapter, flush);
4139 return GST_FLOW_UNEXPECTED;
4144 /* initializes @ebml with @bytes from input stream at current offset.
4145 * Returns UNEXPECTED if insufficient available,
4146 * ERROR if too much was attempted to read. */
4147 static inline GstFlowReturn
4148 gst_matroska_demux_take (GstMatroskaDemux * demux, guint64 bytes,
4151 GstBuffer *buffer = NULL;
4152 GstFlowReturn ret = GST_FLOW_OK;
4154 GST_LOG_OBJECT (demux, "taking %" G_GUINT64_FORMAT " bytes for parsing",
4156 ret = gst_matroska_demux_check_read_size (demux, bytes);
4157 if (G_UNLIKELY (ret != GST_FLOW_OK)) {
4158 if (!demux->streaming) {
4159 /* in pull mode, we can skip */
4160 if ((ret = gst_matroska_demux_flush (demux, bytes)) == GST_FLOW_OK)
4161 ret = GST_FLOW_OVERFLOW;
4163 /* otherwise fatal */
4164 ret = GST_FLOW_ERROR;
4168 if (demux->streaming) {
4169 if (gst_adapter_available (demux->common.adapter) >= bytes)
4170 buffer = gst_adapter_take_buffer (demux->common.adapter, bytes);
4172 ret = GST_FLOW_UNEXPECTED;
4174 ret = gst_matroska_read_common_peek_bytes (&demux->common,
4175 demux->common.offset, bytes, &buffer, NULL);
4176 if (G_LIKELY (buffer)) {
4177 gst_ebml_read_init (ebml, GST_ELEMENT_CAST (demux), buffer,
4178 demux->common.offset);
4179 demux->common.offset += bytes;
4186 gst_matroska_demux_check_seekability (GstMatroskaDemux * demux)
4189 gboolean seekable = FALSE;
4190 gint64 start = -1, stop = -1;
4192 query = gst_query_new_seeking (GST_FORMAT_BYTES);
4193 if (!gst_pad_peer_query (demux->common.sinkpad, query)) {
4194 GST_DEBUG_OBJECT (demux, "seeking query failed");
4198 gst_query_parse_seeking (query, NULL, &seekable, &start, &stop);
4200 /* try harder to query upstream size if we didn't get it the first time */
4201 if (seekable && stop == -1) {
4202 GstFormat fmt = GST_FORMAT_BYTES;
4204 GST_DEBUG_OBJECT (demux, "doing duration query to fix up unset stop");
4205 gst_pad_query_peer_duration (demux->common.sinkpad, &fmt, &stop);
4208 /* if upstream doesn't know the size, it's likely that it's not seekable in
4209 * practice even if it technically may be seekable */
4210 if (seekable && (start != 0 || stop <= start)) {
4211 GST_DEBUG_OBJECT (demux, "seekable but unknown start/stop -> disable");
4216 GST_INFO_OBJECT (demux, "seekable: %d (%" G_GUINT64_FORMAT " - %"
4217 G_GUINT64_FORMAT ")", seekable, start, stop);
4218 demux->seekable = seekable;
4220 gst_query_unref (query);
4223 static GstFlowReturn
4224 gst_matroska_demux_find_tracks (GstMatroskaDemux * demux)
4230 GstFlowReturn ret = GST_FLOW_OK;
4232 GST_WARNING_OBJECT (demux,
4233 "Found Cluster element before Tracks, searching Tracks");
4236 before_pos = demux->common.offset;
4238 /* Search Tracks element */
4240 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4241 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4242 if (ret != GST_FLOW_OK)
4245 if (id != GST_MATROSKA_ID_TRACKS) {
4246 /* we may be skipping large cluster here, so forego size check etc */
4247 /* ... but we can't skip undefined size; force error */
4248 if (length == G_MAXUINT64) {
4249 ret = gst_matroska_demux_check_read_size (demux, length);
4252 demux->common.offset += needed;
4253 demux->common.offset += length;
4258 /* will lead to track parsing ... */
4259 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4264 demux->common.offset = before_pos;
4269 #define GST_READ_CHECK(stmt) \
4271 if (G_UNLIKELY ((ret = (stmt)) != GST_FLOW_OK)) { \
4272 if (ret == GST_FLOW_OVERFLOW) { \
4273 ret = GST_FLOW_OK; \
4279 static GstFlowReturn
4280 gst_matroska_demux_parse_id (GstMatroskaDemux * demux, guint32 id,
4281 guint64 length, guint needed)
4283 GstEbmlRead ebml = { 0, };
4284 GstFlowReturn ret = GST_FLOW_OK;
4287 GST_LOG_OBJECT (demux, "Parsing Element id 0x%x, "
4288 "size %" G_GUINT64_FORMAT ", prefix %d", id, length, needed);
4290 /* if we plan to read and parse this element, we need prefix (id + length)
4291 * and the contents */
4292 /* mind about overflow wrap-around when dealing with undefined size */
4294 if (G_LIKELY (length != G_MAXUINT64))
4297 switch (demux->common.state) {
4298 case GST_MATROSKA_READ_STATE_START:
4300 case GST_EBML_ID_HEADER:
4301 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4302 ret = gst_matroska_read_common_parse_header (&demux->common, &ebml);
4303 if (ret != GST_FLOW_OK)
4305 demux->common.state = GST_MATROSKA_READ_STATE_SEGMENT;
4306 gst_matroska_demux_check_seekability (demux);
4309 goto invalid_header;
4313 case GST_MATROSKA_READ_STATE_SEGMENT:
4315 case GST_MATROSKA_ID_SEGMENT:
4316 /* eat segment prefix */
4317 GST_READ_CHECK (gst_matroska_demux_flush (demux, needed));
4318 GST_DEBUG_OBJECT (demux,
4319 "Found Segment start at offset %" G_GUINT64_FORMAT,
4320 demux->common.offset);
4321 /* seeks are from the beginning of the segment,
4322 * after the segment ID/length */
4323 demux->common.ebml_segment_start = demux->common.offset;
4324 demux->common.state = GST_MATROSKA_READ_STATE_HEADER;
4327 GST_WARNING_OBJECT (demux,
4328 "Expected a Segment ID (0x%x), but received 0x%x!",
4329 GST_MATROSKA_ID_SEGMENT, id);
4330 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4334 case GST_MATROSKA_READ_STATE_SCANNING:
4335 if (id != GST_MATROSKA_ID_CLUSTER &&
4336 id != GST_MATROSKA_ID_CLUSTERTIMECODE)
4339 case GST_MATROSKA_READ_STATE_HEADER:
4340 case GST_MATROSKA_READ_STATE_DATA:
4341 case GST_MATROSKA_READ_STATE_SEEK:
4343 case GST_MATROSKA_ID_SEGMENTINFO:
4344 if (!demux->common.segmentinfo_parsed) {
4345 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4346 ret = gst_matroska_read_common_parse_info (&demux->common,
4347 GST_ELEMENT_CAST (demux), &ebml);
4348 #ifdef MKV_DEMUX_MODIFICATION
4349 demux->duration = demux->common.segment.duration; /* need to check */
4352 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4355 case GST_MATROSKA_ID_TRACKS:
4356 if (!demux->tracks_parsed) {
4357 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4358 ret = gst_matroska_demux_parse_tracks (demux, &ebml);
4360 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4363 case GST_MATROSKA_ID_CLUSTER:
4364 if (G_UNLIKELY (!demux->tracks_parsed)) {
4365 if (demux->streaming) {
4366 GST_DEBUG_OBJECT (demux, "Cluster before Track");
4367 goto not_streamable;
4369 ret = gst_matroska_demux_find_tracks (demux);
4370 if (!demux->tracks_parsed)
4374 if (G_UNLIKELY (demux->common.state
4375 == GST_MATROSKA_READ_STATE_HEADER)) {
4376 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
4377 demux->first_cluster_offset = demux->common.offset;
4378 GST_DEBUG_OBJECT (demux, "signaling no more pads");
4379 gst_element_no_more_pads (GST_ELEMENT (demux));
4380 /* send initial newsegment - we wait till we know the first
4381 incoming timestamp, so we can properly set the start of
4383 demux->need_newsegment = TRUE;
4385 demux->cluster_time = GST_CLOCK_TIME_NONE;
4386 demux->cluster_offset = demux->common.offset;
4387 if (G_UNLIKELY (!demux->seek_first && demux->seek_block)) {
4388 GST_DEBUG_OBJECT (demux, "seek target block %" G_GUINT64_FORMAT
4389 " not found in Cluster, trying next Cluster's first block instead",
4391 demux->seek_block = 0;
4393 demux->seek_first = FALSE;
4394 /* record next cluster for recovery */
4395 if (read != G_MAXUINT64)
4396 demux->next_cluster_offset = demux->cluster_offset + read;
4397 /* eat cluster prefix */
4398 gst_matroska_demux_flush (demux, needed);
4400 case GST_MATROSKA_ID_CLUSTERTIMECODE:
4404 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4405 if ((ret = gst_ebml_read_uint (&ebml, &id, &num)) != GST_FLOW_OK)
4407 GST_DEBUG_OBJECT (demux, "ClusterTimeCode: %" G_GUINT64_FORMAT, num);
4408 demux->cluster_time = num;
4409 if (demux->common.element_index) {
4410 if (demux->common.element_index_writer_id == -1)
4411 gst_index_get_writer_id (demux->common.element_index,
4412 GST_OBJECT (demux), &demux->common.element_index_writer_id);
4413 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
4414 G_GUINT64_FORMAT " for writer id %d",
4415 GST_TIME_ARGS (demux->cluster_time), demux->cluster_offset,
4416 demux->common.element_index_writer_id);
4417 gst_index_add_association (demux->common.element_index,
4418 demux->common.element_index_writer_id,
4419 GST_ASSOCIATION_FLAG_KEY_UNIT,
4420 GST_FORMAT_TIME, demux->cluster_time,
4421 GST_FORMAT_BYTES, demux->cluster_offset, NULL);
4425 case GST_MATROSKA_ID_BLOCKGROUP:
4426 if (!gst_matroska_demux_seek_block (demux))
4428 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4429 DEBUG_ELEMENT_START (demux, &ebml, "BlockGroup");
4430 if ((ret = gst_ebml_read_master (&ebml, &id)) == GST_FLOW_OK) {
4431 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4432 &ebml, demux->cluster_time, demux->cluster_offset, FALSE);
4435 #ifdef MKV_DEMUX_MODIFICATION
4436 if ((demux->common.segment.rate < 0.0) && (demux->found_videokeyframe == TRUE)
4437 && (demux->found_audioframe == TRUE) && (demux->current_ts >= demux->next_keyframe_ts) ) {
4438 /* we displayed at least one one audio block and one video key frame
4439 Now, goto previous cluster */
4442 guint64 duration = 0;
4443 GstClockTime time_position;
4444 GstMatroskaIndex *entry = NULL;
4446 demux->next_keyframe_ts = demux->prev_keyframe_ts;
4447 GST_INFO("next_keyframe_ts is %"GST_TIME_FORMAT, GST_TIME_ARGS(demux->next_keyframe_ts));
4448 demux->video_keyframe_pushed = FALSE;
4449 for (i = 0; i < demux->common.src->len; i++) {
4450 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
4451 if (stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
4452 GST_DEBUG ("video track duration = %"G_GUINT64_FORMAT"position = %"GST_TIME_FORMAT"\n",
4453 stream->default_duration, GST_TIME_ARGS(stream->pos));
4454 duration = stream->default_duration;
4455 time_position = stream->pos;
4459 if((time_position - (minusone *demux->common.segment.rate)*((double)duration/1000000000))> 0) {
4460 time_position -= (minusone *demux->common.segment.rate)*((double)duration/1000000000);
4465 for (i = 0; i < demux->common.src->len; i++) {
4466 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
4469 GST_OBJECT_LOCK (demux);
4470 if (stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
4471 if ((entry = gst_matroska_read_common_do_index_seek (&demux->common, stream, time_position, NULL, NULL)) == NULL) {
4472 GST_DEBUG_OBJECT (demux, "No matching seek entry in index");
4475 GST_DEBUG_OBJECT (demux, "pos = %"G_GUINT64_FORMAT", track = %d, block = %d, time = %"GST_TIME_FORMAT"\n",
4476 entry->pos, entry->track, entry->block, GST_TIME_ARGS(entry->time));
4478 offset = entry->pos + demux->common.ebml_segment_start;
4479 if (offset >= gst_matroska_read_common_get_length(&demux->common)) {
4480 GST_INFO_OBJECT (demux, " Seek failed");
4483 demux->common.offset = offset;
4485 stream->pos = entry->time;
4486 stream->set_discont = TRUE;
4487 stream->last_flow = GST_FLOW_OK;
4488 if (stream->pos > 0.0) {
4489 stream->eos = FALSE;
4491 if(demux->is_eos_blockgroup == FALSE) {
4492 demux->is_eos_blockgroup = TRUE;
4495 GST_INFO_OBJECT (demux, "Reached EOS.....");
4498 demux->common.segment.last_stop = entry->time;
4500 GST_OBJECT_UNLOCK (demux);
4503 if (entry->time == 0.0 && demux->is_eos_blockgroup == TRUE && demux->is_eos_simpleblock == TRUE) {
4504 gst_segment_init (&demux->common.segment, GST_FORMAT_TIME);
4505 gst_segment_set_duration (&demux->common.segment, GST_FORMAT_TIME, demux->duration);
4507 /* send new_segment event with start =0 and stop = duration */
4508 demux->new_segment = gst_event_new_new_segment_full (TRUE,
4509 demux->common.segment.rate, demux->common.segment.applied_rate, demux->common.segment.format,
4510 demux->common.segment.start, demux->common.segment.stop, demux->common.segment.time);
4513 demux->found_videokeyframe = FALSE;
4514 demux->found_audioframe = FALSE;
4515 demux->prev_keyframe_ts = entry->time;
4516 GST_INFO("prev_keyframe in blockgroup is %"GST_TIME_FORMAT,GST_TIME_ARGS(demux->prev_keyframe_ts));
4521 DEBUG_ELEMENT_STOP (demux, &ebml, "BlockGroup", ret);
4523 case GST_MATROSKA_ID_SIMPLEBLOCK:
4524 if (!gst_matroska_demux_seek_block (demux))
4526 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4527 DEBUG_ELEMENT_START (demux, &ebml, "SimpleBlock");
4528 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4529 &ebml, demux->cluster_time, demux->cluster_offset, TRUE);
4531 #ifdef MKV_DEMUX_MODIFICATION
4532 if ((demux->common.segment.rate < 0.0) && (demux->found_videokeyframe == TRUE) && (demux->found_audioframe == TRUE)
4533 && (demux->current_ts >= demux->next_keyframe_ts) ) {
4534 /* we displayed at least one one audio block and one video key frame
4535 Now, goto previous cluster */
4538 guint64 duration = 0;
4539 GstClockTime time_position;
4540 GstMatroskaIndex *entry = NULL;
4542 demux->next_keyframe_ts = demux->prev_keyframe_ts;
4543 GST_INFO("next_keyframe_ts is %"GST_TIME_FORMAT, GST_TIME_ARGS(demux->next_keyframe_ts));
4544 demux->video_keyframe_pushed = FALSE;
4545 for (i = 0; i < demux->common.src->len; i++) {
4546 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
4547 if (stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
4548 GST_DEBUG ("video track duration = %"G_GUINT64_FORMAT"position = %"GST_TIME_FORMAT"\n",
4549 stream->default_duration, GST_TIME_ARGS(stream->pos));
4550 duration = stream->default_duration;
4551 time_position = stream->pos;
4555 if((time_position - (minusone *demux->common.segment.rate)*((double)duration/1000000000))> 0) {
4556 time_position -= (minusone *demux->common.segment.rate)*((double)duration/1000000000);
4561 for (i = 0; i < demux->common.src->len; i++) {
4562 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
4565 GST_OBJECT_LOCK (demux);
4566 if (stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
4567 if ((entry = gst_matroska_read_common_do_index_seek (&demux->common, stream, time_position, NULL, NULL)) == NULL) {
4568 GST_DEBUG_OBJECT (demux, "No matching seek entry in index");
4571 GST_DEBUG_OBJECT (demux, "pos = %"G_GUINT64_FORMAT", track = %d, block = %d, time = %"GST_TIME_FORMAT"\n",
4572 entry->pos, entry->track, entry->block, GST_TIME_ARGS(entry->time));
4574 /* seek (relative to matroska segment) */
4576 offset = entry->pos + demux->common.ebml_segment_start;
4577 if (offset >= gst_matroska_read_common_get_length(&demux->common)) {
4578 GST_INFO_OBJECT (demux, " Seek failed");
4581 demux->common.offset = offset;
4584 stream->pos = entry->time;
4585 stream->set_discont = TRUE;
4586 stream->last_flow = GST_FLOW_OK;
4587 if (stream->pos > 0.0) {
4588 stream->eos = FALSE;
4590 if(demux->is_eos_simpleblock == FALSE) {
4591 demux->is_eos_simpleblock = TRUE;
4594 GST_INFO_OBJECT (demux, "Reached EOS.....");
4597 demux->common.segment.last_stop = entry->time;
4599 GST_OBJECT_UNLOCK (demux);
4602 if (entry->time == 0.0 && demux->is_eos_simpleblock == TRUE && demux->is_eos_blockgroup == TRUE) {
4603 gst_segment_init (&demux->common.segment, GST_FORMAT_TIME);
4604 gst_segment_set_duration (&demux->common.segment, GST_FORMAT_TIME, demux->duration);
4606 /* send new_segment event with start =0 and stop = duration */
4607 demux->new_segment = gst_event_new_new_segment_full (TRUE,
4608 demux->common.segment.rate, demux->common.segment.applied_rate, demux->common.segment.format,
4609 demux->common.segment.start, demux->common.segment.stop, demux->common.segment.time);
4612 demux->found_videokeyframe = FALSE;
4613 demux->found_audioframe = FALSE;
4614 demux->prev_keyframe_ts = entry->time;
4615 GST_INFO("prev_keyframe in simpleblock is %"GST_TIME_FORMAT,GST_TIME_ARGS(demux->prev_keyframe_ts));
4620 DEBUG_ELEMENT_STOP (demux, &ebml, "SimpleBlock", ret);
4622 case GST_MATROSKA_ID_ATTACHMENTS:
4623 if (!demux->common.attachments_parsed) {
4624 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4625 ret = gst_matroska_read_common_parse_attachments (&demux->common,
4626 GST_ELEMENT_CAST (demux), &ebml);
4628 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4631 case GST_MATROSKA_ID_TAGS:
4632 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4633 ret = gst_matroska_read_common_parse_metadata (&demux->common,
4634 GST_ELEMENT_CAST (demux), &ebml);
4636 case GST_MATROSKA_ID_CHAPTERS:
4637 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4638 ret = gst_matroska_read_common_parse_chapters (&demux->common, &ebml);
4640 case GST_MATROSKA_ID_SEEKHEAD:
4641 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4642 ret = gst_matroska_demux_parse_contents (demux, &ebml);
4644 case GST_MATROSKA_ID_CUES:
4645 if (demux->common.index_parsed) {
4646 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4649 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4650 ret = gst_matroska_read_common_parse_index (&demux->common, &ebml);
4651 /* only push based; delayed index building */
4652 if (ret == GST_FLOW_OK
4653 && demux->common.state == GST_MATROSKA_READ_STATE_SEEK) {
4656 GST_OBJECT_LOCK (demux);
4657 event = demux->seek_event;
4658 demux->seek_event = NULL;
4659 GST_OBJECT_UNLOCK (demux);
4662 /* unlikely to fail, since we managed to seek to this point */
4663 if (!gst_matroska_demux_handle_seek_event (demux, NULL, event))
4665 /* resume data handling, main thread clear to seek again */
4666 GST_OBJECT_LOCK (demux);
4667 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
4668 GST_OBJECT_UNLOCK (demux);
4671 case GST_MATROSKA_ID_POSITION:
4672 case GST_MATROSKA_ID_PREVSIZE:
4673 case GST_MATROSKA_ID_ENCRYPTEDBLOCK:
4674 case GST_MATROSKA_ID_SILENTTRACKS:
4675 GST_DEBUG_OBJECT (demux,
4676 "Skipping Cluster subelement 0x%x - ignoring", id);
4680 GST_DEBUG_OBJECT (demux, "skipping Element 0x%x", id);
4681 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4687 if (ret == GST_FLOW_PARSE)
4691 gst_ebml_read_clear (&ebml);
4697 /* simply exit, maybe not enough data yet */
4698 /* no ebml to clear if read error */
4703 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4704 ("Failed to parse Element 0x%x", id));
4705 ret = GST_FLOW_ERROR;
4710 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4711 ("File layout does not permit streaming"));
4712 ret = GST_FLOW_ERROR;
4717 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4718 ("No Tracks element found"));
4719 ret = GST_FLOW_ERROR;
4724 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Invalid header"));
4725 ret = GST_FLOW_ERROR;
4730 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Failed to seek"));
4731 ret = GST_FLOW_ERROR;
4737 gst_matroska_demux_loop (GstPad * pad)
4739 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (pad));
4745 /* If we have to close a segment, send a new segment to do this now */
4746 if (G_LIKELY (demux->common.state == GST_MATROSKA_READ_STATE_DATA)) {
4747 if (G_UNLIKELY (demux->close_segment)) {
4748 gst_matroska_demux_send_event (demux, demux->close_segment);
4749 demux->close_segment = NULL;
4751 if (G_UNLIKELY (demux->new_segment)) {
4752 gst_matroska_demux_send_event (demux, demux->new_segment);
4753 demux->new_segment = NULL;
4757 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4758 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4759 if (ret == GST_FLOW_UNEXPECTED)
4761 if (ret != GST_FLOW_OK) {
4762 if (gst_matroska_demux_check_parse_error (demux))
4768 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
4769 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
4772 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4773 if (ret == GST_FLOW_UNEXPECTED)
4775 if (ret != GST_FLOW_OK)
4778 /* check if we're at the end of a configured segment */
4779 if (G_LIKELY (demux->common.src->len)) {
4782 g_assert (demux->common.num_streams == demux->common.src->len);
4783 for (i = 0; i < demux->common.src->len; i++) {
4784 GstMatroskaTrackContext *context = g_ptr_array_index (demux->common.src,
4786 GST_DEBUG_OBJECT (context->pad, "pos %" GST_TIME_FORMAT,
4787 GST_TIME_ARGS (context->pos));
4788 if (context->eos == FALSE)
4792 GST_INFO_OBJECT (demux, "All streams are EOS");
4793 ret = GST_FLOW_UNEXPECTED;
4798 if (G_UNLIKELY (demux->common.offset ==
4799 gst_matroska_read_common_get_length (&demux->common))) {
4800 GST_LOG_OBJECT (demux, "Reached end of stream");
4801 ret = GST_FLOW_UNEXPECTED;
4810 if (demux->common.segment.rate < 0.0) {
4811 ret = gst_matroska_demux_seek_to_previous_keyframe (demux);
4812 if (ret == GST_FLOW_OK)
4819 const gchar *reason = gst_flow_get_name (ret);
4820 gboolean push_eos = FALSE;
4822 GST_LOG_OBJECT (demux, "pausing task, reason %s", reason);
4823 demux->segment_running = FALSE;
4824 gst_pad_pause_task (demux->common.sinkpad);
4826 if (ret == GST_FLOW_UNEXPECTED) {
4827 /* perform EOS logic */
4829 /* If we were in the headers, make sure we send no-more-pads.
4830 This will ensure decodebin2 does not get stuck thinking
4831 the chain is not complete yet, and waiting indefinitely. */
4832 if (G_UNLIKELY (demux->common.state == GST_MATROSKA_READ_STATE_HEADER)) {
4833 if (demux->common.src->len == 0) {
4834 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
4835 ("No pads created"));
4837 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL),
4838 ("Failed to finish reading headers"));
4840 gst_element_no_more_pads (GST_ELEMENT (demux));
4843 /* Close the segment, i.e. update segment stop with the duration
4844 * if no stop was set */
4845 if (GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) &&
4846 !GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop) &&
4847 GST_CLOCK_TIME_IS_VALID (demux->common.segment.start) &&
4848 demux->last_stop_end > demux->common.segment.start) {
4849 /* arrange to accumulate duration downstream, but avoid sending
4850 * newsegment with decreasing start (w.r.t. sync newsegment events) */
4852 gst_event_new_new_segment_full (TRUE, demux->common.segment.rate,
4853 demux->common.segment.applied_rate, demux->common.segment.format,
4854 demux->last_stop_end, demux->last_stop_end,
4855 demux->common.segment.time + (demux->last_stop_end -
4856 demux->common.segment.start));
4857 gst_matroska_demux_send_event (demux, event);
4860 if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
4863 /* for segment playback we need to post when (in stream time)
4864 * we stopped, this is either stop (when set) or the duration. */
4865 if ((stop = demux->common.segment.stop) == -1)
4866 stop = demux->last_stop_end;
4868 GST_LOG_OBJECT (demux, "Sending segment done, at end of segment");
4869 gst_element_post_message (GST_ELEMENT (demux),
4870 gst_message_new_segment_done (GST_OBJECT (demux), GST_FORMAT_TIME,
4875 } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_UNEXPECTED) {
4876 /* for fatal errors we post an error message */
4877 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
4878 ("stream stopped, reason %s", reason));
4882 /* send EOS, and prevent hanging if no streams yet */
4883 GST_LOG_OBJECT (demux, "Sending EOS, at end of stream");
4884 if (!gst_matroska_demux_send_event (demux, gst_event_new_eos ()) &&
4885 (ret == GST_FLOW_UNEXPECTED)) {
4886 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4887 (NULL), ("got eos but no streams (yet)"));
4895 * Create and push a flushing seek event upstream
4898 perform_seek_to_offset (GstMatroskaDemux * demux, guint64 offset)
4903 GST_DEBUG_OBJECT (demux, "Seeking to %" G_GUINT64_FORMAT, offset);
4906 gst_event_new_seek (1.0, GST_FORMAT_BYTES,
4907 GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, GST_SEEK_TYPE_SET, offset,
4908 GST_SEEK_TYPE_NONE, -1);
4910 res = gst_pad_push_event (demux->common.sinkpad, event);
4912 /* newsegment event will update offset */
4916 static GstFlowReturn
4917 gst_matroska_demux_chain (GstPad * pad, GstBuffer * buffer)
4919 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (pad));
4921 GstFlowReturn ret = GST_FLOW_OK;
4926 if (G_UNLIKELY (GST_BUFFER_IS_DISCONT (buffer))) {
4927 GST_DEBUG_OBJECT (demux, "got DISCONT");
4928 gst_adapter_clear (demux->common.adapter);
4929 GST_OBJECT_LOCK (demux);
4930 gst_matroska_read_common_reset_streams (&demux->common,
4931 GST_CLOCK_TIME_NONE, FALSE);
4932 GST_OBJECT_UNLOCK (demux);
4935 gst_adapter_push (demux->common.adapter, buffer);
4939 available = gst_adapter_available (demux->common.adapter);
4941 ret = gst_matroska_read_common_peek_id_length_push (&demux->common,
4942 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4943 if (G_UNLIKELY (ret != GST_FLOW_OK && ret != GST_FLOW_UNEXPECTED))
4946 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
4947 "size %" G_GUINT64_FORMAT ", needed %d, available %d",
4948 demux->common.offset, id, length, needed, available);
4950 if (needed > available)
4953 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4954 if (ret == GST_FLOW_UNEXPECTED) {
4955 /* need more data */
4957 } else if (ret != GST_FLOW_OK) {
4964 gst_matroska_demux_handle_sink_event (GstPad * pad, GstEvent * event)
4966 gboolean res = TRUE;
4967 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (pad));
4969 GST_DEBUG_OBJECT (demux,
4970 "have event type %s: %p on sink pad", GST_EVENT_TYPE_NAME (event), event);
4972 switch (GST_EVENT_TYPE (event)) {
4973 case GST_EVENT_NEWSEGMENT:
4976 gdouble rate, arate;
4977 gint64 start, stop, time = 0;
4981 /* some debug output */
4982 gst_segment_init (&segment, GST_FORMAT_UNDEFINED);
4983 gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format,
4984 &start, &stop, &time);
4985 gst_segment_set_newsegment_full (&segment, update, rate, arate, format,
4987 GST_DEBUG_OBJECT (demux,
4988 "received format %d newsegment %" GST_SEGMENT_FORMAT, format,
4991 if (demux->common.state < GST_MATROSKA_READ_STATE_DATA) {
4992 GST_DEBUG_OBJECT (demux, "still starting");
4996 /* we only expect a BYTE segment, e.g. following a seek */
4997 if (format != GST_FORMAT_BYTES) {
4998 GST_DEBUG_OBJECT (demux, "unsupported segment format, ignoring");
5002 GST_DEBUG_OBJECT (demux, "clearing segment state");
5003 GST_OBJECT_LOCK (demux);
5004 /* clear current segment leftover */
5005 gst_adapter_clear (demux->common.adapter);
5006 /* and some streaming setup */
5007 demux->common.offset = start;
5008 /* do not know where we are;
5009 * need to come across a cluster and generate newsegment */
5010 demux->common.segment.last_stop = GST_CLOCK_TIME_NONE;
5011 demux->cluster_time = GST_CLOCK_TIME_NONE;
5012 demux->cluster_offset = 0;
5013 demux->need_newsegment = TRUE;
5014 /* but keep some of the upstream segment */
5015 demux->common.segment.rate = rate;
5016 GST_OBJECT_UNLOCK (demux);
5018 /* chain will send initial newsegment after pads have been added,
5019 * or otherwise come up with one */
5020 GST_DEBUG_OBJECT (demux, "eating event");
5021 gst_event_unref (event);
5027 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
5028 gst_event_unref (event);
5029 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
5030 (NULL), ("got eos and didn't receive a complete header object"));
5031 } else if (demux->common.num_streams == 0) {
5032 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
5033 (NULL), ("got eos but no streams (yet)"));
5035 gst_matroska_demux_send_event (demux, event);
5039 case GST_EVENT_FLUSH_STOP:
5041 gst_adapter_clear (demux->common.adapter);
5042 GST_OBJECT_LOCK (demux);
5043 gst_matroska_read_common_reset_streams (&demux->common,
5044 GST_CLOCK_TIME_NONE, TRUE);
5045 demux->common.segment.last_stop = GST_CLOCK_TIME_NONE;
5046 demux->cluster_time = GST_CLOCK_TIME_NONE;
5047 demux->cluster_offset = 0;
5048 GST_OBJECT_UNLOCK (demux);
5052 res = gst_pad_event_default (pad, event);
5060 gst_matroska_demux_sink_activate (GstPad * sinkpad)
5062 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (sinkpad));
5064 if (gst_pad_check_pull_range (sinkpad)) {
5065 GST_DEBUG ("going to pull mode");
5066 demux->streaming = FALSE;
5067 return gst_pad_activate_pull (sinkpad, TRUE);
5069 GST_DEBUG ("going to push (streaming) mode");
5070 demux->streaming = TRUE;
5071 return gst_pad_activate_push (sinkpad, TRUE);
5078 gst_matroska_demux_sink_activate_pull (GstPad * sinkpad, gboolean active)
5080 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (sinkpad));
5083 /* if we have a scheduler we can start the task */
5084 demux->segment_running = TRUE;
5085 gst_pad_start_task (sinkpad, (GstTaskFunction) gst_matroska_demux_loop,
5088 demux->segment_running = FALSE;
5089 gst_pad_stop_task (sinkpad);
5096 gst_duration_to_fraction (guint64 duration, gint * dest_n, gint * dest_d)
5098 static const int common_den[] = { 1, 2, 3, 4, 1001 };
5103 for (i = 0; i < G_N_ELEMENTS (common_den); i++) {
5105 n = floor (0.5 + (d * 1e9) / duration);
5106 a = gst_util_uint64_scale_int (1000000000, d, n);
5107 if (duration >= a - 1 && duration <= a + 1) {
5112 gst_util_double_to_fraction (1e9 / duration, &n, &d);
5121 gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext *
5122 videocontext, const gchar * codec_id, guint8 * data, guint size,
5123 gchar ** codec_name, guint32 * riff_fourcc)
5125 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) videocontext;
5126 GstCaps *caps = NULL;
5128 g_assert (videocontext != NULL);
5129 g_assert (codec_name != NULL);
5131 context->send_xiph_headers = FALSE;
5132 context->send_flac_headers = FALSE;
5133 context->send_speex_headers = FALSE;
5138 /* TODO: check if we have all codec types from matroska-ids.h
5139 * check if we have to do more special things with codec_private
5142 * GST_MATROSKA_CODEC_ID_VIDEO_QUICKTIME
5143 * GST_MATROSKA_CODEC_ID_VIDEO_SNOW
5146 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VFW_FOURCC)) {
5147 gst_riff_strf_vids *vids = NULL;
5150 GstBuffer *buf = NULL;
5152 vids = (gst_riff_strf_vids *) data;
5154 /* assure size is big enough */
5156 GST_WARNING ("Too small BITMAPINFOHEADER (%d bytes)", size);
5159 if (size < sizeof (gst_riff_strf_vids)) {
5160 vids = g_new (gst_riff_strf_vids, 1);
5161 memcpy (vids, data, size);
5164 /* little-endian -> byte-order */
5165 vids->size = GUINT32_FROM_LE (vids->size);
5166 vids->width = GUINT32_FROM_LE (vids->width);
5167 vids->height = GUINT32_FROM_LE (vids->height);
5168 vids->planes = GUINT16_FROM_LE (vids->planes);
5169 vids->bit_cnt = GUINT16_FROM_LE (vids->bit_cnt);
5170 vids->compression = GUINT32_FROM_LE (vids->compression);
5171 vids->image_size = GUINT32_FROM_LE (vids->image_size);
5172 vids->xpels_meter = GUINT32_FROM_LE (vids->xpels_meter);
5173 vids->ypels_meter = GUINT32_FROM_LE (vids->ypels_meter);
5174 vids->num_colors = GUINT32_FROM_LE (vids->num_colors);
5175 vids->imp_colors = GUINT32_FROM_LE (vids->imp_colors);
5177 if (size > sizeof (gst_riff_strf_vids)) { /* some extra_data */
5178 buf = gst_buffer_new_and_alloc (size - sizeof (gst_riff_strf_vids));
5179 memcpy (GST_BUFFER_DATA (buf),
5180 (guint8 *) vids + sizeof (gst_riff_strf_vids),
5181 GST_BUFFER_SIZE (buf));
5185 *riff_fourcc = vids->compression;
5187 caps = gst_riff_create_video_caps (vids->compression, NULL, vids,
5188 buf, NULL, codec_name);
5191 GST_WARNING ("Unhandled RIFF fourcc %" GST_FOURCC_FORMAT,
5192 GST_FOURCC_ARGS (vids->compression));
5196 gst_buffer_unref (buf);
5198 if (vids != (gst_riff_strf_vids *) data)
5201 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_UNCOMPRESSED)) {
5204 switch (videocontext->fourcc) {
5205 case GST_MAKE_FOURCC ('I', '4', '2', '0'):
5206 *codec_name = g_strdup ("Raw planar YUV 4:2:0");
5207 fourcc = videocontext->fourcc;
5209 case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
5210 *codec_name = g_strdup ("Raw packed YUV 4:2:2");
5211 fourcc = videocontext->fourcc;
5213 case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
5214 *codec_name = g_strdup ("Raw packed YUV 4:2:0");
5215 fourcc = videocontext->fourcc;
5217 case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
5218 *codec_name = g_strdup ("Raw packed YUV 4:2:2");
5219 fourcc = videocontext->fourcc;
5221 case GST_MAKE_FOURCC ('A', 'Y', 'U', 'V'):
5222 *codec_name = g_strdup ("Raw packed YUV 4:4:4 with alpha channel");
5223 fourcc = videocontext->fourcc;
5227 GST_DEBUG ("Unknown fourcc %" GST_FOURCC_FORMAT,
5228 GST_FOURCC_ARGS (videocontext->fourcc));
5232 caps = gst_caps_new_simple ("video/x-raw-yuv",
5233 "format", GST_TYPE_FOURCC, fourcc, NULL);
5234 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_SP)) {
5235 caps = gst_caps_new_simple ("video/x-divx",
5236 "divxversion", G_TYPE_INT, 4, NULL);
5237 *codec_name = g_strdup ("MPEG-4 simple profile");
5238 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP) ||
5239 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AP)) {
5241 caps = gst_caps_new_full (gst_structure_new ("video/x-divx",
5242 "divxversion", G_TYPE_INT, 5, NULL),
5243 gst_structure_new ("video/x-xvid", NULL),
5244 gst_structure_new ("video/mpeg",
5245 "mpegversion", G_TYPE_INT, 4,
5246 "systemstream", G_TYPE_BOOLEAN, FALSE, NULL), NULL);
5248 caps = gst_caps_new_simple ("video/mpeg",
5249 "mpegversion", G_TYPE_INT, 4,
5250 "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
5252 GstBuffer *priv = gst_buffer_new_and_alloc (size);
5254 memcpy (GST_BUFFER_DATA (priv), data, size);
5255 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5256 gst_buffer_unref (priv);
5258 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP))
5259 *codec_name = g_strdup ("MPEG-4 advanced simple profile");
5261 *codec_name = g_strdup ("MPEG-4 advanced profile");
5262 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MSMPEG4V3)) {
5264 caps = gst_caps_new_full (gst_structure_new ("video/x-divx",
5265 "divxversion", G_TYPE_INT, 3, NULL),
5266 gst_structure_new ("video/x-msmpeg",
5267 "msmpegversion", G_TYPE_INT, 43, NULL), NULL);
5269 caps = gst_caps_new_simple ("video/x-msmpeg",
5270 "msmpegversion", G_TYPE_INT, 43, NULL);
5271 *codec_name = g_strdup ("Microsoft MPEG-4 v.3");
5272 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1) ||
5273 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG2)) {
5276 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1))
5281 caps = gst_caps_new_simple ("video/mpeg",
5282 "systemstream", G_TYPE_BOOLEAN, FALSE,
5283 "mpegversion", G_TYPE_INT, mpegversion, NULL);
5284 *codec_name = g_strdup_printf ("MPEG-%d video", mpegversion);
5285 context->postprocess_frame = gst_matroska_demux_add_mpeg_seq_header;
5286 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MJPEG)) {
5287 caps = gst_caps_new_simple ("image/jpeg", NULL);
5288 *codec_name = g_strdup ("Motion-JPEG");
5289 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AVC)) {
5290 caps = gst_caps_new_simple ("video/x-h264", NULL);
5292 GstBuffer *priv = gst_buffer_new_and_alloc (size);
5294 /* First byte is the version, second is the profile indication, and third
5295 * is the 5 contraint_set_flags and 3 reserved bits. Fourth byte is the
5296 * level indication. */
5297 gst_codec_utils_h264_caps_set_level_and_profile (caps, data + 1,
5300 memcpy (GST_BUFFER_DATA (priv), data, size);
5301 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5302 gst_buffer_unref (priv);
5304 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "avc",
5305 "alignment", G_TYPE_STRING, "au", NULL);
5307 GST_WARNING ("No codec data found, assuming output is byte-stream");
5308 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
5311 *codec_name = g_strdup ("H264");
5312 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1)) ||
5313 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2)) ||
5314 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3)) ||
5315 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))) {
5316 gint rmversion = -1;
5318 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1))
5320 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2))
5322 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3))
5324 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))
5327 caps = gst_caps_new_simple ("video/x-pn-realvideo",
5328 "rmversion", G_TYPE_INT, rmversion, NULL);
5329 GST_DEBUG ("data:%p, size:0x%x", data, size);
5330 /* We need to extract the extradata ! */
5331 if (data && (size >= 0x22)) {
5336 subformat = GST_READ_UINT32_BE (data + 0x1a);
5337 rformat = GST_READ_UINT32_BE (data + 0x1e);
5339 priv = gst_buffer_new_and_alloc (size - 0x1a);
5341 memcpy (GST_BUFFER_DATA (priv), data + 0x1a, size - 0x1a);
5342 gst_caps_set_simple (caps,
5343 "codec_data", GST_TYPE_BUFFER, priv,
5344 "format", G_TYPE_INT, rformat,
5345 "subformat", G_TYPE_INT, subformat, NULL);
5346 gst_buffer_unref (priv);
5349 *codec_name = g_strdup_printf ("RealVideo %d.0", rmversion);
5350 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_THEORA)) {
5351 caps = gst_caps_new_simple ("video/x-theora", NULL);
5352 context->send_xiph_headers = TRUE;
5353 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_DIRAC)) {
5354 caps = gst_caps_new_simple ("video/x-dirac", NULL);
5355 *codec_name = g_strdup_printf ("Dirac");
5356 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8)) {
5357 caps = gst_caps_new_simple ("video/x-vp8", NULL);
5358 *codec_name = g_strdup_printf ("On2 VP8");
5360 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
5366 GstStructure *structure;
5368 for (i = 0; i < gst_caps_get_size (caps); i++) {
5369 structure = gst_caps_get_structure (caps, i);
5371 /* FIXME: use the real unit here! */
5372 GST_DEBUG ("video size %dx%d, target display size %dx%d (any unit)",
5373 videocontext->pixel_width,
5374 videocontext->pixel_height,
5375 videocontext->display_width, videocontext->display_height);
5377 /* pixel width and height are the w and h of the video in pixels */
5378 if (videocontext->pixel_width > 0 && videocontext->pixel_height > 0) {
5379 gint w = videocontext->pixel_width;
5380 gint h = videocontext->pixel_height;
5382 gst_structure_set (structure,
5383 "width", G_TYPE_INT, w, "height", G_TYPE_INT, h, NULL);
5386 if (videocontext->display_width > 0 || videocontext->display_height > 0) {
5389 if (videocontext->display_width <= 0)
5390 videocontext->display_width = videocontext->pixel_width;
5391 if (videocontext->display_height <= 0)
5392 videocontext->display_height = videocontext->pixel_height;
5394 /* calculate the pixel aspect ratio using the display and pixel w/h */
5395 n = videocontext->display_width * videocontext->pixel_height;
5396 d = videocontext->display_height * videocontext->pixel_width;
5397 GST_DEBUG ("setting PAR to %d/%d", n, d);
5398 gst_structure_set (structure, "pixel-aspect-ratio",
5400 videocontext->display_width * videocontext->pixel_height,
5401 videocontext->display_height * videocontext->pixel_width, NULL);
5404 if (videocontext->default_fps > 0.0) {
5405 GValue fps_double = { 0, };
5406 GValue fps_fraction = { 0, };
5408 g_value_init (&fps_double, G_TYPE_DOUBLE);
5409 g_value_init (&fps_fraction, GST_TYPE_FRACTION);
5410 g_value_set_double (&fps_double, videocontext->default_fps);
5411 g_value_transform (&fps_double, &fps_fraction);
5413 GST_DEBUG ("using default fps %f", videocontext->default_fps);
5415 gst_structure_set_value (structure, "framerate", &fps_fraction);
5416 g_value_unset (&fps_double);
5417 g_value_unset (&fps_fraction);
5418 } else if (context->default_duration > 0) {
5421 gst_duration_to_fraction (context->default_duration, &fps_n, &fps_d);
5423 GST_INFO ("using default duration %" G_GUINT64_FORMAT
5424 " framerate %d/%d", context->default_duration, fps_n, fps_d);
5426 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
5427 fps_n, fps_d, NULL);
5429 /* sort of a hack to get most codecs to support,
5430 * even if the default_duration is missing */
5431 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
5435 if (videocontext->parent.flags & GST_MATROSKA_VIDEOTRACK_INTERLACED)
5436 gst_structure_set (structure, "interlaced", G_TYPE_BOOLEAN, TRUE, NULL);
5439 gst_caps_do_simplify (caps);
5446 * Some AAC specific code... *sigh*
5447 * FIXME: maybe we should use '15' and code the sample rate explicitly
5448 * if the sample rate doesn't match the predefined rates exactly? (tpm)
5452 aac_rate_idx (gint rate)
5456 else if (75132 <= rate)
5458 else if (55426 <= rate)
5460 else if (46009 <= rate)
5462 else if (37566 <= rate)
5464 else if (27713 <= rate)
5466 else if (23004 <= rate)
5468 else if (18783 <= rate)
5470 else if (13856 <= rate)
5472 else if (11502 <= rate)
5474 else if (9391 <= rate)
5481 aac_profile_idx (const gchar * codec_id)
5485 if (strlen (codec_id) <= 12)
5487 else if (!strncmp (&codec_id[12], "MAIN", 4))
5489 else if (!strncmp (&codec_id[12], "LC", 2))
5491 else if (!strncmp (&codec_id[12], "SSR", 3))
5499 #define AAC_SYNC_EXTENSION_TYPE 0x02b7
5502 gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext *
5503 audiocontext, const gchar * codec_id, guint8 * data, guint size,
5504 gchar ** codec_name, guint16 * riff_audio_fmt)
5506 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) audiocontext;
5507 GstCaps *caps = NULL;
5509 g_assert (audiocontext != NULL);
5510 g_assert (codec_name != NULL);
5513 *riff_audio_fmt = 0;
5515 context->send_xiph_headers = FALSE;
5516 context->send_flac_headers = FALSE;
5517 context->send_speex_headers = FALSE;
5519 /* TODO: check if we have all codec types from matroska-ids.h
5520 * check if we have to do more special things with codec_private
5521 * check if we need bitdepth in different places too
5522 * implement channel position magic
5524 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID9
5525 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID10
5526 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDMC
5527 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDM2
5530 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1) ||
5531 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2) ||
5532 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L3)) {
5535 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1))
5537 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2))
5542 caps = gst_caps_new_simple ("audio/mpeg",
5543 "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, layer, NULL);
5544 *codec_name = g_strdup_printf ("MPEG-1 layer %d", layer);
5545 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE) ||
5546 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_LE)) {
5549 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE))
5550 endianness = G_BIG_ENDIAN;
5552 endianness = G_LITTLE_ENDIAN;
5554 caps = gst_caps_new_simple ("audio/x-raw-int",
5555 "width", G_TYPE_INT, audiocontext->bitdepth,
5556 "depth", G_TYPE_INT, audiocontext->bitdepth,
5557 "signed", G_TYPE_BOOLEAN, audiocontext->bitdepth != 8,
5558 "endianness", G_TYPE_INT, endianness, NULL);
5560 *codec_name = g_strdup_printf ("Raw %d-bit PCM audio",
5561 audiocontext->bitdepth);
5562 context->alignment = audiocontext->bitdepth / 8;
5563 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_FLOAT)) {
5564 caps = gst_caps_new_simple ("audio/x-raw-float",
5565 "endianness", G_TYPE_INT, G_LITTLE_ENDIAN,
5566 "width", G_TYPE_INT, audiocontext->bitdepth, NULL);
5567 *codec_name = g_strdup_printf ("Raw %d-bit floating-point audio",
5568 audiocontext->bitdepth);
5569 context->alignment = audiocontext->bitdepth / 8;
5570 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AC3,
5571 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AC3))) {
5572 caps = gst_caps_new_simple ("audio/x-ac3",
5573 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5574 *codec_name = g_strdup ("AC-3 audio");
5575 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_EAC3,
5576 strlen (GST_MATROSKA_CODEC_ID_AUDIO_EAC3))) {
5577 caps = gst_caps_new_simple ("audio/x-eac3",
5578 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5579 *codec_name = g_strdup ("E-AC-3 audio");
5580 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_DTS)) {
5581 caps = gst_caps_new_simple ("audio/x-dts", NULL);
5582 *codec_name = g_strdup ("DTS audio");
5583 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_VORBIS)) {
5584 caps = gst_caps_new_simple ("audio/x-vorbis", NULL);
5585 context->send_xiph_headers = TRUE;
5586 /* vorbis decoder does tags */
5587 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_FLAC)) {
5588 caps = gst_caps_new_simple ("audio/x-flac", NULL);
5589 context->send_flac_headers = TRUE;
5590 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_SPEEX)) {
5591 caps = gst_caps_new_simple ("audio/x-speex", NULL);
5592 context->send_speex_headers = TRUE;
5593 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_ACM)) {
5594 gst_riff_strf_auds auds;
5597 GstBuffer *codec_data = gst_buffer_new ();
5599 /* little-endian -> byte-order */
5600 auds.format = GST_READ_UINT16_LE (data);
5601 auds.channels = GST_READ_UINT16_LE (data + 2);
5602 auds.rate = GST_READ_UINT32_LE (data + 4);
5603 auds.av_bps = GST_READ_UINT32_LE (data + 8);
5604 auds.blockalign = GST_READ_UINT16_LE (data + 12);
5605 auds.size = GST_READ_UINT16_LE (data + 16);
5607 /* 18 is the waveformatex size */
5608 gst_buffer_set_data (codec_data, data + 18, auds.size);
5611 *riff_audio_fmt = auds.format;
5613 caps = gst_riff_create_audio_caps (auds.format, NULL, &auds, NULL,
5614 codec_data, codec_name);
5615 gst_buffer_unref (codec_data);
5618 GST_WARNING ("Unhandled RIFF audio format 0x%02x", auds.format);
5621 } else if (g_str_has_prefix (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC)) {
5622 GstBuffer *priv = NULL;
5624 gint rate_idx, profile;
5625 guint8 *data = NULL;
5627 /* unspecified AAC profile with opaque private codec data */
5628 if (strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC) == 0) {
5629 if (context->codec_priv_size >= 2) {
5630 guint obj_type, freq_index, explicit_freq_bytes = 0;
5632 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
5634 freq_index = (GST_READ_UINT16_BE (context->codec_priv) & 0x780) >> 7;
5635 obj_type = (GST_READ_UINT16_BE (context->codec_priv) & 0xF800) >> 11;
5636 if (freq_index == 15)
5637 explicit_freq_bytes = 3;
5638 GST_DEBUG ("obj_type = %u, freq_index = %u", obj_type, freq_index);
5639 priv = gst_buffer_new_and_alloc (context->codec_priv_size);
5640 memcpy (GST_BUFFER_DATA (priv), context->codec_priv,
5641 context->codec_priv_size);
5642 /* assume SBR if samplerate <= 24kHz */
5643 if (obj_type == 5 || (freq_index >= 6 && freq_index != 15) ||
5644 (context->codec_priv_size == (5 + explicit_freq_bytes))) {
5645 audiocontext->samplerate *= 2;
5648 GST_WARNING ("Opaque A_AAC codec ID, but no codec private data");
5649 /* this is pretty broken;
5650 * maybe we need to make up some default private,
5651 * or maybe ADTS data got dumped in.
5652 * Let's set up some private data now, and check actual data later */
5653 /* just try this and see what happens ... */
5654 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
5655 context->postprocess_frame = gst_matroska_demux_check_aac;
5659 /* make up decoder-specific data if it is not supplied */
5661 priv = gst_buffer_new_and_alloc (5);
5662 data = GST_BUFFER_DATA (priv);
5663 rate_idx = aac_rate_idx (audiocontext->samplerate);
5664 profile = aac_profile_idx (codec_id);
5666 data[0] = ((profile + 1) << 3) | ((rate_idx & 0xE) >> 1);
5667 data[1] = ((rate_idx & 0x1) << 7) | (audiocontext->channels << 3);
5668 GST_BUFFER_SIZE (priv) = 2;
5670 if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2,
5671 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2))) {
5673 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4,
5674 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4))) {
5677 if (g_strrstr (codec_id, "SBR")) {
5678 /* HE-AAC (aka SBR AAC) */
5679 audiocontext->samplerate *= 2;
5680 rate_idx = aac_rate_idx (audiocontext->samplerate);
5681 data[2] = AAC_SYNC_EXTENSION_TYPE >> 3;
5682 data[3] = ((AAC_SYNC_EXTENSION_TYPE & 0x07) << 5) | 5;
5683 data[4] = (1 << 7) | (rate_idx << 3);
5684 GST_BUFFER_SIZE (priv) = 5;
5687 gst_buffer_unref (priv);
5689 GST_ERROR ("Unknown AAC profile and no codec private data");
5694 caps = gst_caps_new_simple ("audio/mpeg",
5695 "mpegversion", G_TYPE_INT, mpegversion,
5696 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5697 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5698 *codec_name = g_strdup_printf ("MPEG-%d AAC audio", mpegversion);
5699 gst_buffer_unref (priv);
5701 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TTA)) {
5702 caps = gst_caps_new_simple ("audio/x-tta",
5703 "width", G_TYPE_INT, audiocontext->bitdepth, NULL);
5704 *codec_name = g_strdup ("TTA audio");
5705 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_WAVPACK4)) {
5706 caps = gst_caps_new_simple ("audio/x-wavpack",
5707 "width", G_TYPE_INT, audiocontext->bitdepth,
5708 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5709 *codec_name = g_strdup ("Wavpack audio");
5710 context->postprocess_frame = gst_matroska_demux_add_wvpk_header;
5711 audiocontext->wvpk_block_index = 0;
5712 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4)) ||
5713 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4)) ||
5714 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))) {
5715 gint raversion = -1;
5717 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4))
5719 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))
5724 caps = gst_caps_new_simple ("audio/x-pn-realaudio",
5725 "raversion", G_TYPE_INT, raversion, NULL);
5726 /* Extract extra information from caps, mapping varies based on codec */
5727 if (data && (size >= 0x50)) {
5734 guint extra_data_size;
5736 GST_ERROR ("real audio raversion:%d", raversion);
5737 if (raversion == 8) {
5739 flavor = GST_READ_UINT16_BE (data + 22);
5740 packet_size = GST_READ_UINT32_BE (data + 24);
5741 height = GST_READ_UINT16_BE (data + 40);
5742 leaf_size = GST_READ_UINT16_BE (data + 44);
5743 sample_width = GST_READ_UINT16_BE (data + 58);
5744 extra_data_size = GST_READ_UINT32_BE (data + 74);
5747 ("flavor:%d, packet_size:%d, height:%d, leaf_size:%d, sample_width:%d, extra_data_size:%d",
5748 flavor, packet_size, height, leaf_size, sample_width,
5750 gst_caps_set_simple (caps, "flavor", G_TYPE_INT, flavor, "packet_size",
5751 G_TYPE_INT, packet_size, "height", G_TYPE_INT, height, "leaf_size",
5752 G_TYPE_INT, leaf_size, "width", G_TYPE_INT, sample_width, NULL);
5754 if ((size - 78) >= extra_data_size) {
5755 priv = gst_buffer_new_and_alloc (extra_data_size);
5756 memcpy (GST_BUFFER_DATA (priv), data + 78, extra_data_size);
5757 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5758 gst_buffer_unref (priv);
5763 *codec_name = g_strdup_printf ("RealAudio %d.0", raversion);
5764 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_SIPR)) {
5765 caps = gst_caps_new_simple ("audio/x-sipro", NULL);
5766 *codec_name = g_strdup ("Sipro/ACELP.NET Voice Codec");
5767 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_RALF)) {
5768 caps = gst_caps_new_simple ("audio/x-ralf-mpeg4-generic", NULL);
5769 *codec_name = g_strdup ("Real Audio Lossless");
5770 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_ATRC)) {
5771 caps = gst_caps_new_simple ("audio/x-vnd.sony.atrac3", NULL);
5772 *codec_name = g_strdup ("Sony ATRAC3");
5774 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
5779 if (audiocontext->samplerate > 0 && audiocontext->channels > 0) {
5782 for (i = 0; i < gst_caps_get_size (caps); i++) {
5783 gst_structure_set (gst_caps_get_structure (caps, i),
5784 "channels", G_TYPE_INT, audiocontext->channels,
5785 "rate", G_TYPE_INT, audiocontext->samplerate, NULL);
5789 gst_caps_do_simplify (caps);
5796 gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
5797 subtitlecontext, const gchar * codec_id, gpointer data, guint size)
5799 GstCaps *caps = NULL;
5800 GstMatroskaTrackContext *context =
5801 (GstMatroskaTrackContext *) subtitlecontext;
5803 /* for backwards compatibility */
5804 if (!g_ascii_strcasecmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASCII))
5805 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8;
5806 else if (!g_ascii_strcasecmp (codec_id, "S_SSA"))
5807 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_SSA;
5808 else if (!g_ascii_strcasecmp (codec_id, "S_ASS"))
5809 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_ASS;
5810 else if (!g_ascii_strcasecmp (codec_id, "S_USF"))
5811 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_USF;
5813 /* TODO: Add GST_MATROSKA_CODEC_ID_SUBTITLE_BMP support
5814 * Check if we have to do something with codec_private */
5815 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8)) {
5816 /* well, plain text simply does not have a lot of markup ... */
5817 caps = gst_caps_new_simple ("text/x-pango-markup", NULL);
5818 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5819 subtitlecontext->check_markup = TRUE;
5820 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_SSA)) {
5821 caps = gst_caps_new_simple ("application/x-ssa", NULL);
5822 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5823 subtitlecontext->check_markup = FALSE;
5824 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASS)) {
5825 caps = gst_caps_new_simple ("application/x-ass", NULL);
5826 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5827 subtitlecontext->check_markup = FALSE;
5828 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_USF)) {
5829 caps = gst_caps_new_simple ("application/x-usf", NULL);
5830 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5831 subtitlecontext->check_markup = FALSE;
5832 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB)) {
5833 caps = gst_caps_new_simple ("video/x-dvd-subpicture", NULL);
5834 ((GstMatroskaTrackContext *) subtitlecontext)->send_dvd_event = TRUE;
5835 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_HDMVPGS)) {
5836 caps = gst_caps_new_simple ("subpicture/x-pgs", NULL);
5837 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_KATE)) {
5838 caps = gst_caps_new_simple ("subtitle/x-kate", NULL);
5839 context->send_xiph_headers = TRUE;
5841 GST_DEBUG ("Unknown subtitle stream: codec_id='%s'", codec_id);
5842 caps = gst_caps_new_simple ("application/x-subtitle-unknown", NULL);
5845 if (data != NULL && size > 0) {
5848 buf = gst_buffer_new_and_alloc (size);
5849 memcpy (GST_BUFFER_DATA (buf), data, size);
5850 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, buf, NULL);
5851 gst_buffer_unref (buf);
5858 gst_matroska_demux_set_index (GstElement * element, GstIndex * index)
5860 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5862 GST_OBJECT_LOCK (demux);
5863 if (demux->common.element_index)
5864 gst_object_unref (demux->common.element_index);
5865 demux->common.element_index = index ? gst_object_ref (index) : NULL;
5866 GST_OBJECT_UNLOCK (demux);
5867 GST_DEBUG_OBJECT (demux, "Set index %" GST_PTR_FORMAT,
5868 demux->common.element_index);
5872 gst_matroska_demux_get_index (GstElement * element)
5874 GstIndex *result = NULL;
5875 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5877 GST_OBJECT_LOCK (demux);
5878 if (demux->common.element_index)
5879 result = gst_object_ref (demux->common.element_index);
5880 GST_OBJECT_UNLOCK (demux);
5882 GST_DEBUG_OBJECT (demux, "Returning index %" GST_PTR_FORMAT, result);
5888 #ifdef MKV_DEMUX_MODIFICATION
5889 static GstMatroskaIndex *
5890 gst_matroska_demux_get_next_index (GstMatroskaDemux * demux, GstMatroskaTrackContext * track, GstMatroskaIndex *entry)
5894 GstMatroskaIndex *tmp = NULL;
5896 /* find entry just before or at the requested position */
5897 if (track && track->index_table)
5898 index = track->index_table;
5900 index = demux->common.index;
5902 for (i=0; i < index->len; i++) {
5903 tmp = &g_array_index (index, GstMatroskaIndex, i);
5904 if ((tmp->time == entry->time) && (tmp->pos == entry->pos)) {
5905 if ((index->len - i) == 1) {
5906 GST_DEBUG_OBJECT (demux, "entry found in last index...returning last index");
5908 GST_DEBUG_OBJECT (demux, "Found entry at index = %d");
5910 tmp = &g_array_index (index, GstMatroskaIndex, i);
5918 static GstFlowReturn
5919 gst_matroska_demux_trickplay_find_tracks (GstMatroskaDemux * demux)
5925 GstFlowReturn ret = GST_FLOW_OK;
5927 GST_WARNING_OBJECT (demux,
5928 "Found Cluster element before Tracks, searching Tracks");
5931 before_pos = demux->common.offset;
5933 /* Search Tracks element */
5935 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
5936 GST_ELEMENT_CAST (demux), &id, &length, &needed);
5937 if (ret != GST_FLOW_OK)
5940 if (id != GST_MATROSKA_ID_TRACKS) {
5941 /* we may be skipping large cluster here, so forego size check etc */
5942 /* ... but we can't skip undefined size; force error */
5943 if (length == G_MAXUINT64) {
5944 ret = gst_matroska_demux_check_read_size (demux, length);
5947 demux->common.offset += needed;
5948 demux->common.offset += length;
5953 /* will lead to track parsing ... */
5954 ret = gst_matroska_demux_trickplay_parse_id (demux, id, length, needed);
5959 demux->common.offset = before_pos;
5964 static GstFlowReturn
5965 gst_matroska_demux_trickplay_parse_id (GstMatroskaDemux * demux, guint32 id,
5966 guint64 length, guint needed)
5968 GstEbmlRead ebml = { 0, };
5969 GstFlowReturn ret = GST_FLOW_OK;
5972 GST_LOG_OBJECT (demux, "Parsing Element id 0x%x, "
5973 "size %" G_GUINT64_FORMAT ", prefix %d", id, length, needed);
5975 /* if we plan to read and parse this element, we need prefix (id + length)
5976 * and the contents */
5977 /* mind about overflow wrap-around when dealing with undefined size */
5979 if (G_LIKELY (length != G_MAXUINT64))
5982 switch (demux->common.state) {
5983 case GST_MATROSKA_READ_STATE_START:
5985 case GST_EBML_ID_HEADER:
5986 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5987 ret = gst_matroska_read_common_parse_header (&demux->common, &ebml);
5988 if (ret != GST_FLOW_OK)
5990 demux->common.state = GST_MATROSKA_READ_STATE_SEGMENT;
5991 gst_matroska_demux_check_seekability (demux);
5994 goto invalid_header;
5998 case GST_MATROSKA_READ_STATE_SEGMENT:
6000 case GST_MATROSKA_ID_SEGMENT:
6001 /* eat segment prefix */
6002 GST_READ_CHECK (gst_matroska_demux_flush (demux, needed));
6003 GST_DEBUG_OBJECT (demux,
6004 "Found Segment start at offset %" G_GUINT64_FORMAT,
6005 demux->common.offset);
6006 /* seeks are from the beginning of the segment,
6007 * after the segment ID/length */
6008 demux->common.ebml_segment_start = demux->common.offset;
6009 demux->common.state = GST_MATROSKA_READ_STATE_HEADER;
6012 GST_WARNING_OBJECT (demux,
6013 "Expected a Segment ID (0x%x), but received 0x%x!",
6014 GST_MATROSKA_ID_SEGMENT, id);
6015 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
6019 case GST_MATROSKA_READ_STATE_SCANNING:
6020 if (id != GST_MATROSKA_ID_CLUSTER &&
6021 id != GST_MATROSKA_ID_CLUSTERTIMECODE)
6024 case GST_MATROSKA_READ_STATE_HEADER:
6025 case GST_MATROSKA_READ_STATE_DATA:
6026 case GST_MATROSKA_READ_STATE_SEEK:
6028 case GST_MATROSKA_ID_CLUSTER:
6029 if (G_UNLIKELY (!demux->tracks_parsed)) {
6030 if (demux->streaming) {
6031 GST_DEBUG_OBJECT (demux, "Cluster before Track");
6032 goto not_streamable;
6034 ret = gst_matroska_demux_trickplay_find_tracks (demux);
6035 if (!demux->tracks_parsed)
6039 if (G_UNLIKELY (demux->common.state == GST_MATROSKA_READ_STATE_HEADER)) {
6040 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
6041 demux->first_cluster_offset = demux->common.offset;
6042 GST_DEBUG_OBJECT (demux, "signaling no more pads");
6043 gst_element_no_more_pads (GST_ELEMENT (demux));
6044 /* send initial newsegment */
6045 gst_matroska_demux_send_event (demux,
6046 gst_event_new_new_segment (FALSE, 1.0,
6048 (demux->common.segment.duration >
6049 0) ? demux->common.segment.duration : -1, 0));
6051 demux->cluster_time = GST_CLOCK_TIME_NONE;
6052 demux->cluster_offset = demux->common.offset;
6053 if (G_UNLIKELY (!demux->seek_first && demux->seek_block)) {
6054 GST_DEBUG_OBJECT (demux, "seek target block %" G_GUINT64_FORMAT
6055 " not found in Cluster, trying next Cluster's first block instead",
6057 demux->seek_block = 0;
6059 demux->seek_first = FALSE;
6060 /* record next cluster for recovery */
6061 if (read != G_MAXUINT64)
6062 demux->next_cluster_offset = demux->cluster_offset + read;
6063 /* eat cluster prefix */
6064 gst_matroska_demux_flush (demux, needed);
6066 case GST_MATROSKA_ID_CLUSTERTIMECODE: {
6069 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
6070 if ((ret = gst_ebml_read_uint (&ebml, &id, &num)) != GST_FLOW_OK)
6072 GST_DEBUG_OBJECT (demux, "ClusterTimeCode: %" G_GUINT64_FORMAT, num);
6073 demux->cluster_time = num;
6074 if (demux->common.element_index) {
6075 if (demux->common.element_index_writer_id == -1)
6076 gst_index_get_writer_id (demux->common.element_index,
6077 GST_OBJECT (demux), &demux->common.element_index_writer_id);
6078 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
6079 G_GUINT64_FORMAT " for writer id %d",
6080 GST_TIME_ARGS (demux->cluster_time), demux->cluster_offset,
6081 demux->common.element_index_writer_id);
6082 gst_index_add_association (demux->common.element_index,
6083 demux->common.element_index_writer_id, GST_ASSOCIATION_FLAG_KEY_UNIT,
6084 GST_FORMAT_TIME, demux->cluster_time,
6085 GST_FORMAT_BYTES, demux->cluster_offset, NULL);
6089 case GST_MATROSKA_ID_BLOCKGROUP:
6090 if (!gst_matroska_demux_seek_block (demux))
6092 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
6093 DEBUG_ELEMENT_START (demux, &ebml, "BlockGroup");
6094 if ((ret = gst_ebml_read_master (&ebml, &id)) == GST_FLOW_OK) {
6095 ret = gst_matroska_demux_trickplay_parse_blockgroup_or_simpleblock (demux,
6096 &ebml, demux->cluster_time, demux->cluster_offset, FALSE);
6098 DEBUG_ELEMENT_STOP (demux, &ebml, "BlockGroup", ret);
6100 case GST_MATROSKA_ID_SIMPLEBLOCK:
6101 if (!gst_matroska_demux_seek_block (demux))
6103 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
6104 DEBUG_ELEMENT_START (demux, &ebml, "SimpleBlock");
6105 ret = gst_matroska_demux_trickplay_parse_blockgroup_or_simpleblock (demux,
6106 &ebml, demux->cluster_time, demux->cluster_offset, TRUE);
6107 DEBUG_ELEMENT_STOP (demux, &ebml, "SimpleBlock", ret);
6109 case GST_MATROSKA_ID_SEGMENTINFO:
6110 case GST_MATROSKA_ID_TRACKS:
6111 case GST_MATROSKA_ID_ATTACHMENTS:
6112 case GST_MATROSKA_ID_TAGS:
6113 case GST_MATROSKA_ID_CHAPTERS:
6114 case GST_MATROSKA_ID_SEEKHEAD:
6115 case GST_MATROSKA_ID_CUES:
6116 case GST_MATROSKA_ID_POSITION:
6117 case GST_MATROSKA_ID_PREVSIZE:
6118 case GST_MATROSKA_ID_ENCRYPTEDBLOCK:
6119 case GST_MATROSKA_ID_SILENTTRACKS:
6120 GST_DEBUG_OBJECT (demux,
6121 "Skipping Cluster subelement 0x%x - ignoring", id);
6125 GST_DEBUG_OBJECT (demux, "skipping Element 0x%x", id);
6126 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
6132 if (ret == GST_FLOW_PARSE)
6136 gst_ebml_read_clear (&ebml);
6142 /* simply exit, maybe not enough data yet */
6143 /* no ebml to clear if read error */
6148 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
6149 ("Failed to parse Element 0x%x", id));
6150 ret = GST_FLOW_ERROR;
6155 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
6156 ("File layout does not permit streaming"));
6157 ret = GST_FLOW_ERROR;
6162 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
6163 ("No Tracks element found"));
6164 ret = GST_FLOW_ERROR;
6169 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Invalid header"));
6170 ret = GST_FLOW_ERROR;
6175 static GstFlowReturn
6176 gst_matroska_demux_trickplay_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux,
6177 GstEbmlRead * ebml, guint64 cluster_time, guint64 cluster_offset,
6178 gboolean is_simpleblock)
6180 GstMatroskaTrackContext *stream = NULL;
6181 GstFlowReturn ret = GST_FLOW_OK;
6182 gboolean readblock = FALSE;
6184 guint64 block_duration = 0;
6185 GstBuffer *buf = NULL;
6186 gint stream_num = -1, n, laces = 0;
6190 gint64 referenceblock = 0;
6193 offset = gst_ebml_read_get_offset (ebml);
6195 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
6196 if (!is_simpleblock) {
6197 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK) {
6201 id = GST_MATROSKA_ID_SIMPLEBLOCK;
6205 /* one block inside the group. Note, block parsing is one
6206 * of the harder things, so this code is a bit complicated.
6207 * See http://www.matroska.org/ for documentation. */
6208 case GST_MATROSKA_ID_SIMPLEBLOCK:
6209 case GST_MATROSKA_ID_BLOCK: {
6214 gst_buffer_unref (buf);
6217 if ((ret = gst_ebml_read_buffer (ebml, &id, &buf)) != GST_FLOW_OK)
6220 data = GST_BUFFER_DATA (buf);
6221 size = GST_BUFFER_SIZE (buf);
6223 /* first byte(s): blocknum */
6224 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
6229 /* fetch stream from num */
6230 stream_num = gst_matroska_read_common_stream_from_num (&demux->common, num);
6231 if (G_UNLIKELY (size < 3)) {
6232 GST_WARNING_OBJECT (demux, "Invalid size %u", size);
6233 /* non-fatal, try next block(group) */
6236 } else if (G_UNLIKELY (stream_num < 0 ||
6237 stream_num >= demux->common.num_streams)) {
6238 /* let's not give up on a stray invalid track number */
6239 GST_WARNING_OBJECT (demux,
6240 "Invalid stream %d for track number %" G_GUINT64_FORMAT
6241 "; ignoring block", stream_num, num);
6245 stream = g_ptr_array_index (demux->common.src, stream_num);
6247 /* time (relative to cluster time) */
6248 time = ((gint16) GST_READ_UINT16_BE (data));
6251 flags = GST_READ_UINT8 (data);
6255 GST_LOG_OBJECT (demux, "time %" G_GUINT64_FORMAT ", flags %d", time,
6258 switch ((flags & 0x06) >> 1) {
6259 case 0x0: /* no lacing */
6263 case 0x1: /* xiph lacing */
6264 case 0x2: /* fixed-size lacing */
6265 case 0x3: /* EBML lacing */
6267 goto invalid_lacing;
6268 laces = GST_READ_UINT8 (data) + 1;
6273 if (ret != GST_FLOW_OK)
6280 case GST_MATROSKA_ID_BLOCKDURATION: {
6281 ret = gst_ebml_read_uint (ebml, &id, &block_duration);
6282 GST_DEBUG_OBJECT (demux, "BlockDuration: %" G_GUINT64_FORMAT,
6287 case GST_MATROSKA_ID_REFERENCEBLOCK: {
6288 ret = gst_ebml_read_sint (ebml, &id, &referenceblock);
6289 GST_DEBUG_OBJECT (demux, "ReferenceBlock: %" G_GINT64_FORMAT,
6295 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml, "BlockGroup", id);
6298 case GST_MATROSKA_ID_BLOCKVIRTUAL:
6299 case GST_MATROSKA_ID_BLOCKADDITIONS:
6300 case GST_MATROSKA_ID_REFERENCEPRIORITY:
6301 case GST_MATROSKA_ID_REFERENCEVIRTUAL:
6302 case GST_MATROSKA_ID_SLICES:
6303 GST_DEBUG_OBJECT (demux,
6304 "Skipping BlockGroup subelement 0x%x - ignoring", id);
6305 ret = gst_ebml_read_skip (ebml);
6313 /* reading a number or so could have failed */
6314 if (ret != GST_FLOW_OK)
6317 if (ret == GST_FLOW_OK && readblock) {
6318 gint64 lace_time = 0;
6319 gboolean delta_unit;
6321 stream = g_ptr_array_index (demux->common.src, stream_num);
6323 if (cluster_time != GST_CLOCK_TIME_NONE) {
6324 /* FIXME: What to do with negative timestamps? Give timestamp 0 or -1?
6325 * Drop unless the lace contains timestamp 0? */
6326 if (time < 0 && (-time) > cluster_time) {
6329 if (stream->timecodescale == 1.0)
6330 lace_time = (cluster_time + time) * demux->common.time_scale;
6333 gst_util_guint64_to_gdouble ((cluster_time + time) *
6334 demux->common.time_scale) * stream->timecodescale;
6337 lace_time = GST_CLOCK_TIME_NONE;
6340 /* else duration is diff between timecode of this and next block */
6342 /* For SimpleBlock, look at the keyframe bit in flags. Otherwise,
6343 a ReferenceBlock implies that this is not a keyframe. In either
6344 case, it only makes sense for video streams. */
6345 delta_unit = stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
6346 ((is_simpleblock && !(flags & 0x80)) || referenceblock);
6348 if (delta_unit && stream->set_discont) {
6349 /* When doing seeks or such, we need to restart on key frames or
6350 * decoders might choke. */
6351 GST_DEBUG_OBJECT (demux, "skipping delta unit");
6355 /* last_ts used for EOS in trickplay */
6356 stream->last_ts = lace_time;
6358 if (stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
6359 stream->num_frames_bw_keyframes++;
6360 if (delta_unit == FALSE) {
6361 stream->found_next_kframe = TRUE;
6362 demux->next_key_cluster_time = demux->cluster_time;
6363 stream->next_kframe_timestamp = lace_time;
6364 demux->common.segment.last_stop = lace_time - 0.5* GST_SECOND;
6366 } else if (stream->type == GST_MATROSKA_TRACK_TYPE_AUDIO) {
6367 stream->num_frames_bw_keyframes = stream->num_frames_bw_keyframes + laces;
6373 gst_buffer_unref (buf);
6379 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Invalid lacing size"));
6380 /* non-fatal, try next block(group) */
6386 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Data error"));
6387 /* non-fatal, try next block(group) */
6394 gst_matroska_demux_trickplay_nframes2show_bw_keyframes (GstMatroskaDemux* demux, GstMatroskaTrackContext * stream)
6396 GstFlowReturn ret = GST_FLOW_OK;
6400 gint prev_offset = demux->common.offset;
6401 gint next_keyframe_offset = 0;
6402 guint64 prev_cluster_time = demux->cluster_time;
6403 guint64 prev_cluster_offset = demux->cluster_offset;
6406 while (stream->found_next_kframe == FALSE) {
6407 next_keyframe_offset = demux->common.offset;
6409 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
6410 GST_ELEMENT_CAST (demux), &id, &length, &needed);
6411 if (ret == GST_FLOW_UNEXPECTED) {
6412 stream->next_kframe_timestamp = stream->last_ts;
6413 stream->found_next_kframe = TRUE;
6416 GST_LOG_OBJECT (demux, "trickplay : Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
6417 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
6420 if (ret != GST_FLOW_OK) {
6421 GST_WARNING_OBJECT (demux, "Error in id_length_pull flow ret...reason : %s\n", gst_flow_get_name (ret));
6425 ret = gst_matroska_demux_trickplay_parse_id (demux, id, length, needed);
6426 if (ret == GST_FLOW_UNEXPECTED) {
6427 stream->next_kframe_timestamp = stream->last_ts;
6428 stream->found_next_kframe = TRUE;
6432 if (ret != GST_FLOW_OK) {
6433 GST_WARNING_OBJECT (demux, "Error in parse_id flow ret...reason : %s\n", gst_flow_get_name (ret));
6438 if (stream->found_next_kframe == TRUE) {
6439 demux->next_key_frame_offset = next_keyframe_offset;
6442 for (i = 0; i < demux->common.src->len; i++) {
6443 GstMatroskaTrackContext *context = g_ptr_array_index (demux->common.src, i);
6444 if (context->type <= GST_MATROSKA_TRACK_TYPE_AUDIO) {
6445 context->frames_to_show_bw_keyframes = context->num_frames_bw_keyframes / demux->common.segment.rate;
6449 /* keeping previous offset values for normal operation */
6450 demux->common.offset = prev_offset;
6451 demux->cluster_offset = prev_cluster_offset;
6452 demux->cluster_time = prev_cluster_time;
6454 return stream->num_frames_bw_keyframes;
6457 static GstFlowReturn
6458 gst_matroska_demux_backward_trickplay (GstMatroskaDemux* demux, GstMatroskaTrackContext * stream, GstBuffer* sub)
6460 GstFlowReturn ret = GST_FLOW_OK;
6462 if (((stream->type == GST_MATROSKA_TRACK_TYPE_AUDIO) || (!GST_BUFFER_FLAG_IS_SET (sub, GST_BUFFER_FLAG_DELTA_UNIT)))
6463 && (demux->prev_keyframe_ts <= (GST_BUFFER_TIMESTAMP (sub)) <= demux->next_keyframe_ts)) {
6465 if(stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO && !demux->video_keyframe_pushed) {
6466 demux->video_keyframe_pushed = TRUE;
6467 } else if(stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO && demux->video_keyframe_pushed){
6468 GST_INFO("unreffing the video frame (already sent one keyframe)");
6469 gst_buffer_unref (sub);
6473 if(demux->prev_keyframe_ts == demux->next_keyframe_ts || demux->prev_keyframe_ts > demux->next_keyframe_ts) {
6474 GST_INFO("Unreffing the already pushed buffer");
6475 gst_buffer_unref (sub);
6479 GST_DEBUG_OBJECT (demux, "Pushing data of size %d for stream %d, time=%"GST_TIME_FORMAT
6480 " and duration=%" GST_TIME_FORMAT,
6481 GST_BUFFER_SIZE (sub), stream->type,
6482 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (sub)),
6483 GST_TIME_ARGS (GST_BUFFER_DURATION (sub)));
6485 g_assert (stream->alignment <= G_MEM_ALIGN);
6486 if (((guintptr) GST_BUFFER_DATA (sub)) & (stream->alignment - 1)) {
6487 GST_INFO("in if alignment log");
6488 GstBuffer *buffer = gst_buffer_new_and_alloc (GST_BUFFER_SIZE (sub));
6489 memcpy (GST_BUFFER_DATA (buffer), GST_BUFFER_DATA (sub),
6490 GST_BUFFER_SIZE (sub));
6491 gst_buffer_copy_metadata (buffer, sub, GST_BUFFER_COPY_ALL);
6492 GST_DEBUG_OBJECT (demux, "We want output aligned on %d, reallocated", stream->alignment);
6493 gst_buffer_unref (sub);
6497 ret = gst_pad_push(stream->pad, sub);
6499 if (ret != GST_FLOW_OK) {
6500 GST_DEBUG_OBJECT (demux, "Error in pad_push. Reason : %s\n", gst_flow_get_name (ret));
6502 } else if(GST_BUFFER_FLAG_IS_SET (sub, GST_BUFFER_FLAG_DELTA_UNIT)) {
6503 gst_buffer_unref (sub);
6508 static GstFlowReturn
6509 gst_matroska_demux_forward_trickplay (GstMatroskaDemux* demux, GstMatroskaTrackContext * stream, GstBuffer *buffer, gboolean *skip)
6511 GstFlowReturn ret = GST_FLOW_OK;
6512 guint64 time_escalation = 0;
6515 if (stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
6516 if ((stream->found_next_kframe == FALSE) && (!GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT))) {
6517 GST_INFO("Finding the no of frames b/w keyframe");
6518 g_assert (!GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT));
6519 gst_matroska_demux_trickplay_nframes2show_bw_keyframes (demux, stream);
6520 stream->prev_kframe_timestamp = GST_BUFFER_TIMESTAMP (buffer);
6521 GST_INFO("next keyframe timestamp is %"GST_TIME_FORMAT" and previous keyframe timestamp is %"GST_TIME_FORMAT,
6522 GST_TIME_ARGS(stream->next_kframe_timestamp), GST_TIME_ARGS(stream->prev_kframe_timestamp));
6523 stream->avg_duration_bw_keyframes = (stream->next_kframe_timestamp - stream->prev_kframe_timestamp) / stream->num_frames_bw_keyframes;
6524 GST_INFO_OBJECT (demux, "Number of frames between key frames = %d and frames to show between key frames = %d", stream->num_frames_bw_keyframes, stream->frames_to_show_bw_keyframes);
6525 GST_DEBUG_OBJECT (demux, "average duration of frames = %"GST_TIME_FORMAT, GST_TIME_ARGS(stream->avg_duration_bw_keyframes));
6527 for (i = 0; i < demux->common.src->len; i++) {
6528 GstMatroskaTrackContext *context = g_ptr_array_index (demux->common.src, i);
6529 if (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO) {
6530 context->num_frames_bw_keyframes = 0;
6534 if (stream->frames_to_show_bw_keyframes == 0) {
6535 stream->found_next_kframe = FALSE;
6536 demux->cluster_time = demux->next_key_cluster_time;
6537 demux->common.offset = demux->next_key_frame_offset;
6538 stream->num_frames_bw_keyframes = 0;
6539 GST_DEBUG_OBJECT (demux, "next key cluster time = %"GST_TIME_FORMAT" and offset = %u...\n", GST_TIME_ARGS(demux->cluster_time), demux->common.offset);
6542 if(stream->num_frames_bw_keyframes == 0)
6545 if(stream->frames_to_show_bw_keyframes > 0) {
6546 GST_INFO("Time stamp modification %"GST_TIME_FORMAT,GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(buffer)));
6548 time_escalation = ((stream->num_frames_bw_keyframes/demux->common.segment.rate) - stream->frames_to_show_bw_keyframes) * stream->avg_duration_bw_keyframes * demux->common.segment.rate;
6550 GST_BUFFER_TIMESTAMP(buffer) = stream->prev_kframe_timestamp + time_escalation;
6551 GST_INFO("Time stamp modified %"GST_TIME_FORMAT,GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(buffer)));
6553 stream->frames_to_show_bw_keyframes--;
6555 } else if (stream->type == GST_MATROSKA_TRACK_TYPE_AUDIO) {
6556 if (stream->frames_to_show_bw_keyframes == 0) {
6558 stream->num_frames_bw_keyframes = 0;
6559 stream->frames_to_show_bw_keyframes = 0;
6561 stream->frames_to_show_bw_keyframes--;
6570 static GstStateChangeReturn
6571 gst_matroska_demux_change_state (GstElement * element,
6572 GstStateChange transition)
6574 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
6575 GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
6577 /* handle upwards state changes here */
6578 switch (transition) {
6583 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
6585 /* handle downwards state changes */
6586 switch (transition) {
6587 case GST_STATE_CHANGE_PAUSED_TO_READY:
6588 gst_matroska_demux_reset (GST_ELEMENT (demux));
6598 gst_matroska_demux_set_property (GObject * object,
6599 guint prop_id, const GValue * value, GParamSpec * pspec)
6601 GstMatroskaDemux *demux;
6603 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
6604 demux = GST_MATROSKA_DEMUX (object);
6607 case ARG_MAX_GAP_TIME:
6608 GST_OBJECT_LOCK (demux);
6609 demux->max_gap_time = g_value_get_uint64 (value);
6610 GST_OBJECT_UNLOCK (demux);
6613 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
6619 gst_matroska_demux_get_property (GObject * object,
6620 guint prop_id, GValue * value, GParamSpec * pspec)
6622 GstMatroskaDemux *demux;
6624 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
6625 demux = GST_MATROSKA_DEMUX (object);
6628 case ARG_MAX_GAP_TIME:
6629 GST_OBJECT_LOCK (demux);
6630 g_value_set_uint64 (value, demux->max_gap_time);
6631 GST_OBJECT_UNLOCK (demux);
6634 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
6640 gst_matroska_demux_plugin_init (GstPlugin * plugin)
6644 /* parser helper separate debug */
6645 GST_DEBUG_CATEGORY_INIT (ebmlread_debug, "ebmlread",
6646 0, "EBML stream helper class");
6648 /* create an elementfactory for the matroska_demux element */
6649 if (!gst_element_register (plugin, "matroskademux",
6650 GST_RANK_PRIMARY, GST_TYPE_MATROSKA_DEMUX))