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);
192 static gboolean gst_matroska_demux_create_index_table(GstMatroskaDemux* demux);
195 GType gst_matroska_demux_get_type (void);
196 GST_BOILERPLATE (GstMatroskaDemux, gst_matroska_demux, GstElement,
200 gst_matroska_demux_base_init (gpointer klass)
202 GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
204 gst_element_class_add_static_pad_template (element_class, &video_src_templ);
205 gst_element_class_add_static_pad_template (element_class, &audio_src_templ);
206 gst_element_class_add_static_pad_template (element_class,
207 &subtitle_src_templ);
208 gst_element_class_add_static_pad_template (element_class, &sink_templ);
210 gst_element_class_set_details_simple (element_class, "Matroska demuxer",
212 "Demuxes Matroska/WebM streams into video/audio/subtitles",
213 "GStreamer maintainers <gstreamer-devel@lists.sourceforge.net>");
217 gst_matroska_demux_finalize (GObject * object)
219 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (object);
221 if (demux->common.src) {
222 g_ptr_array_free (demux->common.src, TRUE);
223 demux->common.src = NULL;
226 if (demux->common.global_tags) {
227 gst_tag_list_free (demux->common.global_tags);
228 demux->common.global_tags = NULL;
231 g_object_unref (demux->common.adapter);
233 G_OBJECT_CLASS (parent_class)->finalize (object);
237 gst_matroska_demux_class_init (GstMatroskaDemuxClass * klass)
239 GObjectClass *gobject_class = (GObjectClass *) klass;
240 GstElementClass *gstelement_class = (GstElementClass *) klass;
242 GST_DEBUG_CATEGORY_INIT (matroskademux_debug, "matroskademux", 0,
245 gobject_class->finalize = gst_matroska_demux_finalize;
247 gobject_class->get_property = gst_matroska_demux_get_property;
248 gobject_class->set_property = gst_matroska_demux_set_property;
250 g_object_class_install_property (gobject_class, ARG_MAX_GAP_TIME,
251 g_param_spec_uint64 ("max-gap-time", "Maximum gap time",
252 "The demuxer sends out newsegment events for skipping "
253 "gaps longer than this (0 = disabled).", 0, G_MAXUINT64,
254 DEFAULT_MAX_GAP_TIME, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
256 gstelement_class->change_state =
257 GST_DEBUG_FUNCPTR (gst_matroska_demux_change_state);
258 gstelement_class->send_event =
259 GST_DEBUG_FUNCPTR (gst_matroska_demux_element_send_event);
260 gstelement_class->query =
261 GST_DEBUG_FUNCPTR (gst_matroska_demux_element_query);
263 gstelement_class->set_index =
264 GST_DEBUG_FUNCPTR (gst_matroska_demux_set_index);
265 gstelement_class->get_index =
266 GST_DEBUG_FUNCPTR (gst_matroska_demux_get_index);
270 gst_matroska_demux_init (GstMatroskaDemux * demux,
271 GstMatroskaDemuxClass * klass)
273 demux->common.sinkpad = gst_pad_new_from_static_template (&sink_templ,
275 gst_pad_set_activate_function (demux->common.sinkpad,
276 GST_DEBUG_FUNCPTR (gst_matroska_demux_sink_activate));
277 gst_pad_set_activatepull_function (demux->common.sinkpad,
278 GST_DEBUG_FUNCPTR (gst_matroska_demux_sink_activate_pull));
279 gst_pad_set_chain_function (demux->common.sinkpad,
280 GST_DEBUG_FUNCPTR (gst_matroska_demux_chain));
281 gst_pad_set_event_function (demux->common.sinkpad,
282 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_sink_event));
283 gst_element_add_pad (GST_ELEMENT (demux), demux->common.sinkpad);
285 /* initial stream no. */
286 demux->common.src = NULL;
288 demux->common.writing_app = NULL;
289 demux->common.muxing_app = NULL;
290 demux->common.index = NULL;
291 demux->common.global_tags = NULL;
293 demux->common.adapter = gst_adapter_new ();
295 #ifdef MKV_DEMUX_MODIFICATION
296 demux->found_videokeyframe = FALSE;
297 demux->found_audioframe = FALSE;
298 demux->is_eos_blockgroup = FALSE;
299 demux->is_eos_simpleblock = FALSE;
300 demux->video_keyframe_pushed = FALSE;
301 demux->seek_head_cluster_info_absent = FALSE;
302 demux->seek_head_cue_info_absent = FALSE;
303 demux->index_table_created = TRUE;
304 demux->index_table_array_creation = FALSE;
307 /* property defaults */
308 demux->max_gap_time = DEFAULT_MAX_GAP_TIME;
311 gst_matroska_demux_reset (GST_ELEMENT (demux));
315 gst_matroska_track_free (GstMatroskaTrackContext * track)
317 g_free (track->codec_id);
318 g_free (track->codec_name);
319 g_free (track->name);
320 g_free (track->language);
321 g_free (track->codec_priv);
322 g_free (track->codec_state);
324 #ifdef MKV_DEMUX_MODIFICATION
325 while (!g_queue_is_empty (track->queue)) {
326 GstBuffer* buf = g_queue_pop_head (track->queue);
327 gst_buffer_unref (buf);
329 g_queue_free (track->queue);
332 if (track->encodings != NULL) {
335 for (i = 0; i < track->encodings->len; ++i) {
336 GstMatroskaTrackEncoding *enc = &g_array_index (track->encodings,
337 GstMatroskaTrackEncoding,
340 g_free (enc->comp_settings);
342 g_array_free (track->encodings, TRUE);
345 if (track->pending_tags)
346 gst_tag_list_free (track->pending_tags);
348 if (track->index_table)
349 g_array_free (track->index_table, TRUE);
355 * Returns the aggregated GstFlowReturn.
358 gst_matroska_demux_combine_flows (GstMatroskaDemux * demux,
359 GstMatroskaTrackContext * track, GstFlowReturn ret)
363 /* store the value */
364 track->last_flow = ret;
366 /* any other error that is not-linked can be returned right away */
367 if (ret != GST_FLOW_NOT_LINKED)
370 /* only return NOT_LINKED if all other pads returned NOT_LINKED */
371 g_assert (demux->common.src->len == demux->common.num_streams);
372 for (i = 0; i < demux->common.src->len; i++) {
373 GstMatroskaTrackContext *ostream = g_ptr_array_index (demux->common.src,
379 ret = ostream->last_flow;
380 /* some other return value (must be SUCCESS but we can return
381 * other values as well) */
382 if (ret != GST_FLOW_NOT_LINKED)
385 /* if we get here, all other pads were unlinked and we return
388 GST_LOG_OBJECT (demux, "combined return %s", gst_flow_get_name (ret));
393 gst_matroska_demux_free_parsed_el (gpointer mem, gpointer user_data)
395 g_slice_free (guint64, mem);
399 gst_matroska_demux_reset (GstElement * element)
401 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
404 GST_DEBUG_OBJECT (demux, "Resetting state");
407 demux->common.state = GST_MATROSKA_READ_STATE_START;
409 /* clean up existing streams */
410 if (demux->common.src) {
411 g_assert (demux->common.src->len == demux->common.num_streams);
412 for (i = 0; i < demux->common.src->len; i++) {
413 GstMatroskaTrackContext *context = g_ptr_array_index (demux->common.src,
416 if (context->pad != NULL)
417 gst_element_remove_pad (GST_ELEMENT (demux), context->pad);
419 gst_caps_replace (&context->caps, NULL);
420 gst_matroska_track_free (context);
422 g_ptr_array_free (demux->common.src, TRUE);
424 demux->common.src = g_ptr_array_new ();
426 demux->common.num_streams = 0;
427 demux->num_a_streams = 0;
428 demux->num_t_streams = 0;
429 demux->num_v_streams = 0;
431 /* reset media info */
432 g_free (demux->common.writing_app);
433 demux->common.writing_app = NULL;
434 g_free (demux->common.muxing_app);
435 demux->common.muxing_app = NULL;
438 if (demux->common.index) {
439 g_array_free (demux->common.index, TRUE);
440 demux->common.index = NULL;
443 if (demux->clusters) {
444 g_array_free (demux->clusters, TRUE);
445 demux->clusters = NULL;
450 demux->common.time_scale = 1000000;
451 demux->common.created = G_MININT64;
453 demux->common.index_parsed = FALSE;
454 demux->tracks_parsed = FALSE;
455 demux->common.segmentinfo_parsed = FALSE;
456 demux->common.attachments_parsed = FALSE;
458 g_list_foreach (demux->common.tags_parsed,
459 (GFunc) gst_matroska_demux_free_parsed_el, NULL);
460 g_list_free (demux->common.tags_parsed);
461 demux->common.tags_parsed = NULL;
463 g_list_foreach (demux->seek_parsed,
464 (GFunc) gst_matroska_demux_free_parsed_el, NULL);
465 g_list_free (demux->seek_parsed);
466 demux->seek_parsed = NULL;
468 gst_segment_init (&demux->common.segment, GST_FORMAT_TIME);
469 demux->last_stop_end = GST_CLOCK_TIME_NONE;
470 demux->seek_block = 0;
471 demux->stream_start_time = GST_CLOCK_TIME_NONE;
473 demux->common.offset = 0;
474 demux->cluster_time = GST_CLOCK_TIME_NONE;
475 demux->cluster_offset = 0;
476 demux->next_cluster_offset = 0;
477 demux->index_offset = 0;
478 demux->seekable = FALSE;
479 demux->need_newsegment = FALSE;
480 demux->building_index = FALSE;
481 if (demux->seek_event) {
482 gst_event_unref (demux->seek_event);
483 demux->seek_event = NULL;
486 demux->seek_index = NULL;
487 demux->seek_entry = 0;
489 if (demux->close_segment) {
490 gst_event_unref (demux->close_segment);
491 demux->close_segment = NULL;
494 if (demux->new_segment) {
495 gst_event_unref (demux->new_segment);
496 demux->new_segment = NULL;
499 if (demux->common.element_index) {
500 gst_object_unref (demux->common.element_index);
501 demux->common.element_index = NULL;
503 demux->common.element_index_writer_id = -1;
505 if (demux->common.global_tags) {
506 gst_tag_list_free (demux->common.global_tags);
508 demux->common.global_tags = gst_tag_list_new ();
510 if (demux->common.cached_buffer) {
511 gst_buffer_unref (demux->common.cached_buffer);
512 demux->common.cached_buffer = NULL;
515 demux->invalid_duration = FALSE;
519 gst_matroska_decode_buffer (GstMatroskaTrackContext * context, GstBuffer * buf)
525 g_return_val_if_fail (GST_IS_BUFFER (buf), NULL);
527 GST_DEBUG ("decoding buffer %p", buf);
529 data = GST_BUFFER_DATA (buf);
530 size = GST_BUFFER_SIZE (buf);
532 g_return_val_if_fail (data != NULL && size > 0, buf);
534 if (gst_matroska_decode_data (context->encodings, &data, &size,
535 GST_MATROSKA_TRACK_ENCODING_SCOPE_FRAME, FALSE)) {
536 new_buf = gst_buffer_new ();
537 GST_BUFFER_MALLOCDATA (new_buf) = (guint8 *) data;
538 GST_BUFFER_DATA (new_buf) = (guint8 *) data;
539 GST_BUFFER_SIZE (new_buf) = size;
541 gst_buffer_unref (buf);
546 GST_DEBUG ("decode data failed");
547 gst_buffer_unref (buf);
553 gst_matroska_demux_add_stream (GstMatroskaDemux * demux, GstEbmlRead * ebml)
555 GstElementClass *klass = GST_ELEMENT_GET_CLASS (demux);
556 GstMatroskaTrackContext *context;
557 GstPadTemplate *templ = NULL;
558 GstCaps *caps = NULL;
559 gchar *padname = NULL;
561 guint32 id, riff_fourcc = 0;
562 guint16 riff_audio_fmt = 0;
563 GstTagList *list = NULL;
566 DEBUG_ELEMENT_START (demux, ebml, "TrackEntry");
568 /* start with the master */
569 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
570 DEBUG_ELEMENT_STOP (demux, ebml, "TrackEntry", ret);
574 /* allocate generic... if we know the type, we'll g_renew()
575 * with the precise type */
576 context = g_new0 (GstMatroskaTrackContext, 1);
577 g_ptr_array_add (demux->common.src, context);
578 context->index = demux->common.num_streams;
579 context->index_writer_id = -1;
580 context->type = 0; /* no type yet */
581 context->default_duration = 0;
583 #ifdef MKV_DEMUX_MODIFICATION
584 context->found_next_kframe = FALSE;
586 context->set_discont = TRUE;
587 context->timecodescale = 1.0;
589 GST_MATROSKA_TRACK_ENABLED | GST_MATROSKA_TRACK_DEFAULT |
590 GST_MATROSKA_TRACK_LACING;
591 context->last_flow = GST_FLOW_OK;
592 context->to_offset = G_MAXINT64;
593 context->alignment = 1;
594 demux->common.num_streams++;
595 g_assert (demux->common.src->len == demux->common.num_streams);
597 #ifdef MKV_DEMUX_MODIFICATION
598 context->queue = g_queue_new ();
599 // context->found_key_frame = FALSE;
600 context->last_ts = GST_CLOCK_TIME_NONE;
601 // context->avg_duration = GST_CLOCK_TIME_NONE;
602 // context->intra_gap = 0;
605 GST_DEBUG_OBJECT (demux, "Stream number %d", context->index);
607 /* try reading the trackentry headers */
608 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
609 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
613 /* track number (unique stream ID) */
614 case GST_MATROSKA_ID_TRACKNUMBER:{
617 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
621 GST_ERROR_OBJECT (demux, "Invalid TrackNumber 0");
622 ret = GST_FLOW_ERROR;
624 } else if (!gst_matroska_read_common_tracknumber_unique (&demux->common,
626 GST_ERROR_OBJECT (demux, "TrackNumber %" G_GUINT64_FORMAT
627 " is not unique", num);
628 ret = GST_FLOW_ERROR;
632 GST_DEBUG_OBJECT (demux, "TrackNumber: %" G_GUINT64_FORMAT, num);
636 /* track UID (unique identifier) */
637 case GST_MATROSKA_ID_TRACKUID:{
640 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
644 GST_ERROR_OBJECT (demux, "Invalid TrackUID 0");
645 ret = GST_FLOW_ERROR;
649 GST_DEBUG_OBJECT (demux, "TrackUID: %" G_GUINT64_FORMAT, num);
654 /* track type (video, audio, combined, subtitle, etc.) */
655 case GST_MATROSKA_ID_TRACKTYPE:{
658 if ((ret = gst_ebml_read_uint (ebml, &id, &track_type)) != GST_FLOW_OK) {
662 if (context->type != 0 && context->type != track_type) {
663 GST_WARNING_OBJECT (demux,
664 "More than one tracktype defined in a TrackEntry - skipping");
666 } else if (track_type < 1 || track_type > 254) {
667 GST_WARNING_OBJECT (demux, "Invalid TrackType %" G_GUINT64_FORMAT,
672 GST_DEBUG_OBJECT (demux, "TrackType: %" G_GUINT64_FORMAT, track_type);
674 /* ok, so we're actually going to reallocate this thing */
675 switch (track_type) {
676 case GST_MATROSKA_TRACK_TYPE_VIDEO:
677 gst_matroska_track_init_video_context (&context);
679 case GST_MATROSKA_TRACK_TYPE_AUDIO:
680 gst_matroska_track_init_audio_context (&context);
682 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
683 gst_matroska_track_init_subtitle_context (&context);
685 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
686 case GST_MATROSKA_TRACK_TYPE_LOGO:
687 case GST_MATROSKA_TRACK_TYPE_BUTTONS:
688 case GST_MATROSKA_TRACK_TYPE_CONTROL:
690 GST_WARNING_OBJECT (demux,
691 "Unknown or unsupported TrackType %" G_GUINT64_FORMAT,
696 g_ptr_array_index (demux->common.src, demux->common.num_streams - 1)
701 /* tracktype specific stuff for video */
702 case GST_MATROSKA_ID_TRACKVIDEO:{
703 GstMatroskaTrackVideoContext *videocontext;
705 DEBUG_ELEMENT_START (demux, ebml, "TrackVideo");
707 if (!gst_matroska_track_init_video_context (&context)) {
708 GST_WARNING_OBJECT (demux,
709 "TrackVideo element in non-video track - ignoring track");
710 ret = GST_FLOW_ERROR;
712 } else if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
715 videocontext = (GstMatroskaTrackVideoContext *) context;
716 g_ptr_array_index (demux->common.src, demux->common.num_streams - 1)
719 while (ret == GST_FLOW_OK &&
720 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
721 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
725 /* Should be one level up but some broken muxers write it here. */
726 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
729 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
733 GST_WARNING_OBJECT (demux, "Invalid TrackDefaultDuration 0");
737 GST_DEBUG_OBJECT (demux,
738 "TrackDefaultDuration: %" G_GUINT64_FORMAT, num);
739 context->default_duration = num;
743 /* video framerate */
744 /* NOTE: This one is here only for backward compatibility.
745 * Use _TRACKDEFAULDURATION one level up. */
746 case GST_MATROSKA_ID_VIDEOFRAMERATE:{
749 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
753 GST_WARNING_OBJECT (demux, "Invalid TrackVideoFPS %lf", num);
757 GST_DEBUG_OBJECT (demux, "TrackVideoFrameRate: %lf", num);
758 if (context->default_duration == 0)
759 context->default_duration =
760 gst_gdouble_to_guint64 ((gdouble) GST_SECOND * (1.0 / num));
761 videocontext->default_fps = num;
765 /* width of the size to display the video at */
766 case GST_MATROSKA_ID_VIDEODISPLAYWIDTH:{
769 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
773 GST_WARNING_OBJECT (demux, "Invalid TrackVideoDisplayWidth 0");
777 GST_DEBUG_OBJECT (demux,
778 "TrackVideoDisplayWidth: %" G_GUINT64_FORMAT, num);
779 videocontext->display_width = num;
783 /* height of the size to display the video at */
784 case GST_MATROSKA_ID_VIDEODISPLAYHEIGHT:{
787 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
791 GST_WARNING_OBJECT (demux, "Invalid TrackVideoDisplayHeight 0");
795 GST_DEBUG_OBJECT (demux,
796 "TrackVideoDisplayHeight: %" G_GUINT64_FORMAT, num);
797 videocontext->display_height = num;
801 /* width of the video in the file */
802 case GST_MATROSKA_ID_VIDEOPIXELWIDTH:{
805 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
809 GST_WARNING_OBJECT (demux, "Invalid TrackVideoPixelWidth 0");
813 GST_DEBUG_OBJECT (demux,
814 "TrackVideoPixelWidth: %" G_GUINT64_FORMAT, num);
815 videocontext->pixel_width = num;
819 /* height of the video in the file */
820 case GST_MATROSKA_ID_VIDEOPIXELHEIGHT:{
823 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
827 GST_WARNING_OBJECT (demux, "Invalid TrackVideoPixelHeight 0");
831 GST_DEBUG_OBJECT (demux,
832 "TrackVideoPixelHeight: %" G_GUINT64_FORMAT, num);
833 videocontext->pixel_height = num;
837 /* whether the video is interlaced */
838 case GST_MATROSKA_ID_VIDEOFLAGINTERLACED:{
841 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
845 context->flags |= GST_MATROSKA_VIDEOTRACK_INTERLACED;
847 context->flags &= ~GST_MATROSKA_VIDEOTRACK_INTERLACED;
848 GST_DEBUG_OBJECT (demux, "TrackVideoInterlaced: %d",
849 (context->flags & GST_MATROSKA_VIDEOTRACK_INTERLACED) ? 1 :
854 /* aspect ratio behaviour */
855 case GST_MATROSKA_ID_VIDEOASPECTRATIOTYPE:{
858 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
861 if (num != GST_MATROSKA_ASPECT_RATIO_MODE_FREE &&
862 num != GST_MATROSKA_ASPECT_RATIO_MODE_KEEP &&
863 num != GST_MATROSKA_ASPECT_RATIO_MODE_FIXED) {
864 GST_WARNING_OBJECT (demux,
865 "Unknown TrackVideoAspectRatioType 0x%x", (guint) num);
868 GST_DEBUG_OBJECT (demux,
869 "TrackVideoAspectRatioType: %" G_GUINT64_FORMAT, num);
870 videocontext->asr_mode = num;
874 /* colourspace (only matters for raw video) fourcc */
875 case GST_MATROSKA_ID_VIDEOCOLOURSPACE:{
880 gst_ebml_read_binary (ebml, &id, &data,
881 &datalen)) != GST_FLOW_OK)
886 GST_WARNING_OBJECT (demux,
887 "Invalid TrackVideoColourSpace length %" G_GUINT64_FORMAT,
892 memcpy (&videocontext->fourcc, data, 4);
893 GST_DEBUG_OBJECT (demux,
894 "TrackVideoColourSpace: %" GST_FOURCC_FORMAT,
895 GST_FOURCC_ARGS (videocontext->fourcc));
901 GST_WARNING_OBJECT (demux,
902 "Unknown TrackVideo subelement 0x%x - ignoring", id);
904 case GST_MATROSKA_ID_VIDEOSTEREOMODE:
905 case GST_MATROSKA_ID_VIDEODISPLAYUNIT:
906 case GST_MATROSKA_ID_VIDEOPIXELCROPBOTTOM:
907 case GST_MATROSKA_ID_VIDEOPIXELCROPTOP:
908 case GST_MATROSKA_ID_VIDEOPIXELCROPLEFT:
909 case GST_MATROSKA_ID_VIDEOPIXELCROPRIGHT:
910 case GST_MATROSKA_ID_VIDEOGAMMAVALUE:
911 ret = gst_ebml_read_skip (ebml);
916 DEBUG_ELEMENT_STOP (demux, ebml, "TrackVideo", ret);
920 /* tracktype specific stuff for audio */
921 case GST_MATROSKA_ID_TRACKAUDIO:{
922 GstMatroskaTrackAudioContext *audiocontext;
924 DEBUG_ELEMENT_START (demux, ebml, "TrackAudio");
926 if (!gst_matroska_track_init_audio_context (&context)) {
927 GST_WARNING_OBJECT (demux,
928 "TrackAudio element in non-audio track - ignoring track");
929 ret = GST_FLOW_ERROR;
933 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
936 audiocontext = (GstMatroskaTrackAudioContext *) context;
937 g_ptr_array_index (demux->common.src, demux->common.num_streams - 1)
940 while (ret == GST_FLOW_OK &&
941 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
942 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
947 case GST_MATROSKA_ID_AUDIOSAMPLINGFREQ:{
950 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
955 GST_WARNING_OBJECT (demux,
956 "Invalid TrackAudioSamplingFrequency %lf", num);
960 GST_DEBUG_OBJECT (demux, "TrackAudioSamplingFrequency: %lf", num);
961 audiocontext->samplerate = num;
966 case GST_MATROSKA_ID_AUDIOBITDEPTH:{
969 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
973 GST_WARNING_OBJECT (demux, "Invalid TrackAudioBitDepth 0");
977 GST_DEBUG_OBJECT (demux, "TrackAudioBitDepth: %" G_GUINT64_FORMAT,
979 audiocontext->bitdepth = num;
984 case GST_MATROSKA_ID_AUDIOCHANNELS:{
987 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
991 GST_WARNING_OBJECT (demux, "Invalid TrackAudioChannels 0");
995 GST_DEBUG_OBJECT (demux, "TrackAudioChannels: %" G_GUINT64_FORMAT,
997 audiocontext->channels = num;
1002 GST_WARNING_OBJECT (demux,
1003 "Unknown TrackAudio subelement 0x%x - ignoring", id);
1005 case GST_MATROSKA_ID_AUDIOCHANNELPOSITIONS:
1006 case GST_MATROSKA_ID_AUDIOOUTPUTSAMPLINGFREQ:
1007 ret = gst_ebml_read_skip (ebml);
1012 DEBUG_ELEMENT_STOP (demux, ebml, "TrackAudio", ret);
1017 /* codec identifier */
1018 case GST_MATROSKA_ID_CODECID:{
1021 if ((ret = gst_ebml_read_ascii (ebml, &id, &text)) != GST_FLOW_OK)
1024 GST_DEBUG_OBJECT (demux, "CodecID: %s", GST_STR_NULL (text));
1025 context->codec_id = text;
1029 /* codec private data */
1030 case GST_MATROSKA_ID_CODECPRIVATE:{
1035 gst_ebml_read_binary (ebml, &id, &data, &size)) != GST_FLOW_OK)
1038 context->codec_priv = data;
1039 context->codec_priv_size = size;
1041 GST_DEBUG_OBJECT (demux, "CodecPrivate of size %" G_GUINT64_FORMAT,
1046 /* name of the codec */
1047 case GST_MATROSKA_ID_CODECNAME:{
1050 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1053 GST_DEBUG_OBJECT (demux, "CodecName: %s", GST_STR_NULL (text));
1054 context->codec_name = text;
1058 /* name of this track */
1059 case GST_MATROSKA_ID_TRACKNAME:{
1062 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1065 context->name = text;
1066 GST_DEBUG_OBJECT (demux, "TrackName: %s", GST_STR_NULL (text));
1070 /* language (matters for audio/subtitles, mostly) */
1071 case GST_MATROSKA_ID_TRACKLANGUAGE:{
1074 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1078 context->language = text;
1081 if (strlen (context->language) >= 4 && context->language[3] == '-')
1082 context->language[3] = '\0';
1084 GST_DEBUG_OBJECT (demux, "TrackLanguage: %s",
1085 GST_STR_NULL (context->language));
1089 /* whether this is actually used */
1090 case GST_MATROSKA_ID_TRACKFLAGENABLED:{
1093 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1097 context->flags |= GST_MATROSKA_TRACK_ENABLED;
1099 context->flags &= ~GST_MATROSKA_TRACK_ENABLED;
1101 GST_DEBUG_OBJECT (demux, "TrackEnabled: %d",
1102 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
1106 /* whether it's the default for this track type */
1107 case GST_MATROSKA_ID_TRACKFLAGDEFAULT:{
1110 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1114 context->flags |= GST_MATROSKA_TRACK_DEFAULT;
1116 context->flags &= ~GST_MATROSKA_TRACK_DEFAULT;
1118 GST_DEBUG_OBJECT (demux, "TrackDefault: %d",
1119 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
1123 /* whether the track must be used during playback */
1124 case GST_MATROSKA_ID_TRACKFLAGFORCED:{
1127 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1131 context->flags |= GST_MATROSKA_TRACK_FORCED;
1133 context->flags &= ~GST_MATROSKA_TRACK_FORCED;
1135 GST_DEBUG_OBJECT (demux, "TrackForced: %d",
1136 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
1140 /* lacing (like MPEG, where blocks don't end/start on frame
1142 case GST_MATROSKA_ID_TRACKFLAGLACING:{
1145 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1149 context->flags |= GST_MATROSKA_TRACK_LACING;
1151 context->flags &= ~GST_MATROSKA_TRACK_LACING;
1153 GST_DEBUG_OBJECT (demux, "TrackLacing: %d",
1154 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
1158 /* default length (in time) of one data block in this track */
1159 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
1162 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1167 GST_WARNING_OBJECT (demux, "Invalid TrackDefaultDuration 0");
1171 GST_DEBUG_OBJECT (demux, "TrackDefaultDuration: %" G_GUINT64_FORMAT,
1173 context->default_duration = num;
1177 case GST_MATROSKA_ID_CONTENTENCODINGS:{
1178 ret = gst_matroska_read_common_read_track_encodings (&demux->common,
1183 case GST_MATROSKA_ID_TRACKTIMECODESCALE:{
1186 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
1190 GST_WARNING_OBJECT (demux, "Invalid TrackTimeCodeScale %lf", num);
1194 GST_DEBUG_OBJECT (demux, "TrackTimeCodeScale: %lf", num);
1195 context->timecodescale = num;
1200 GST_WARNING ("Unknown TrackEntry subelement 0x%x - ignoring", id);
1203 /* we ignore these because they're nothing useful (i.e. crap)
1204 * or simply not implemented yet. */
1205 case GST_MATROSKA_ID_TRACKMINCACHE:
1206 case GST_MATROSKA_ID_TRACKMAXCACHE:
1207 case GST_MATROSKA_ID_MAXBLOCKADDITIONID:
1208 case GST_MATROSKA_ID_TRACKATTACHMENTLINK:
1209 case GST_MATROSKA_ID_TRACKOVERLAY:
1210 case GST_MATROSKA_ID_TRACKTRANSLATE:
1211 case GST_MATROSKA_ID_TRACKOFFSET:
1212 case GST_MATROSKA_ID_CODECSETTINGS:
1213 case GST_MATROSKA_ID_CODECINFOURL:
1214 case GST_MATROSKA_ID_CODECDOWNLOADURL:
1215 case GST_MATROSKA_ID_CODECDECODEALL:
1216 ret = gst_ebml_read_skip (ebml);
1221 DEBUG_ELEMENT_STOP (demux, ebml, "TrackEntry", ret);
1223 /* Decode codec private data if necessary */
1224 if (context->encodings && context->encodings->len > 0 && context->codec_priv
1225 && context->codec_priv_size > 0) {
1226 if (!gst_matroska_decode_data (context->encodings,
1227 &context->codec_priv, &context->codec_priv_size,
1228 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
1229 GST_WARNING_OBJECT (demux, "Decoding codec private data failed");
1230 ret = GST_FLOW_ERROR;
1234 if (context->type == 0 || context->codec_id == NULL || (ret != GST_FLOW_OK
1235 && ret != GST_FLOW_UNEXPECTED)) {
1236 if (ret == GST_FLOW_OK || ret == GST_FLOW_UNEXPECTED)
1237 GST_WARNING_OBJECT (ebml, "Unknown stream/codec in track entry header");
1239 demux->common.num_streams--;
1240 g_ptr_array_remove_index (demux->common.src, demux->common.num_streams);
1241 g_assert (demux->common.src->len == demux->common.num_streams);
1243 gst_matroska_track_free (context);
1249 /* now create the GStreamer connectivity */
1250 switch (context->type) {
1251 case GST_MATROSKA_TRACK_TYPE_VIDEO:{
1252 GstMatroskaTrackVideoContext *videocontext =
1253 (GstMatroskaTrackVideoContext *) context;
1255 padname = g_strdup_printf ("video_%02d", demux->num_v_streams++);
1256 templ = gst_element_class_get_pad_template (klass, "video_%02d");
1257 caps = gst_matroska_demux_video_caps (videocontext,
1258 context->codec_id, (guint8 *) context->codec_priv,
1259 context->codec_priv_size, &codec, &riff_fourcc);
1262 list = gst_tag_list_new ();
1263 gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
1264 GST_TAG_VIDEO_CODEC, codec, NULL);
1270 case GST_MATROSKA_TRACK_TYPE_AUDIO:{
1271 GstMatroskaTrackAudioContext *audiocontext =
1272 (GstMatroskaTrackAudioContext *) context;
1274 padname = g_strdup_printf ("audio_%02d", demux->num_a_streams++);
1275 templ = gst_element_class_get_pad_template (klass, "audio_%02d");
1276 caps = gst_matroska_demux_audio_caps (audiocontext,
1277 context->codec_id, context->codec_priv, context->codec_priv_size,
1278 &codec, &riff_audio_fmt);
1281 list = gst_tag_list_new ();
1282 gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
1283 GST_TAG_AUDIO_CODEC, codec, NULL);
1289 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:{
1290 GstMatroskaTrackSubtitleContext *subtitlecontext =
1291 (GstMatroskaTrackSubtitleContext *) context;
1293 padname = g_strdup_printf ("subtitle_%02d", demux->num_t_streams++);
1294 templ = gst_element_class_get_pad_template (klass, "subtitle_%02d");
1295 caps = gst_matroska_demux_subtitle_caps (subtitlecontext,
1296 context->codec_id, context->codec_priv, context->codec_priv_size);
1300 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1301 case GST_MATROSKA_TRACK_TYPE_LOGO:
1302 case GST_MATROSKA_TRACK_TYPE_BUTTONS:
1303 case GST_MATROSKA_TRACK_TYPE_CONTROL:
1305 /* we should already have quit by now */
1306 g_assert_not_reached ();
1309 if ((context->language == NULL || *context->language == '\0') &&
1310 (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO ||
1311 context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
1312 GST_LOG ("stream %d: language=eng (assuming default)", context->index);
1313 context->language = g_strdup ("eng");
1316 if (context->language) {
1320 list = gst_tag_list_new ();
1322 /* Matroska contains ISO 639-2B codes, we want ISO 639-1 */
1323 lang = gst_tag_get_language_code (context->language);
1324 gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
1325 GST_TAG_LANGUAGE_CODE, (lang) ? lang : context->language, NULL);
1329 GST_WARNING_OBJECT (demux, "could not determine caps for stream with "
1330 "codec_id='%s'", context->codec_id);
1331 switch (context->type) {
1332 case GST_MATROSKA_TRACK_TYPE_VIDEO:
1333 caps = gst_caps_new_simple ("video/x-unknown", NULL);
1335 case GST_MATROSKA_TRACK_TYPE_AUDIO:
1336 caps = gst_caps_new_simple ("audio/x-unknown", NULL);
1338 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
1339 caps = gst_caps_new_simple ("application/x-subtitle-unknown", NULL);
1341 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1343 caps = gst_caps_new_simple ("application/x-matroska-unknown", NULL);
1346 gst_caps_set_simple (caps, "codec-id", G_TYPE_STRING, context->codec_id,
1349 /* add any unrecognised riff fourcc / audio format, but after codec-id */
1350 if (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO && riff_audio_fmt != 0)
1351 gst_caps_set_simple (caps, "format", G_TYPE_INT, riff_audio_fmt, NULL);
1352 else if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO && riff_fourcc != 0)
1353 gst_caps_set_simple (caps, "fourcc", GST_TYPE_FOURCC, riff_fourcc, NULL);
1356 /* the pad in here */
1357 context->pad = gst_pad_new_from_template (templ, padname);
1358 context->caps = caps;
1360 gst_pad_set_event_function (context->pad,
1361 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_event));
1362 gst_pad_set_query_type_function (context->pad,
1363 GST_DEBUG_FUNCPTR (gst_matroska_demux_get_src_query_types));
1364 gst_pad_set_query_function (context->pad,
1365 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_query));
1367 GST_INFO_OBJECT (demux, "Adding pad '%s' with caps %" GST_PTR_FORMAT,
1370 context->pending_tags = list;
1372 gst_pad_set_element_private (context->pad, context);
1374 gst_pad_use_fixed_caps (context->pad);
1375 gst_pad_set_caps (context->pad, context->caps);
1376 gst_pad_set_active (context->pad, TRUE);
1377 gst_element_add_pad (GST_ELEMENT (demux), context->pad);
1381 #ifdef MKV_DEMUX_MODIFICATION
1382 if (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO)
1383 demux->audio_stream = context;
1384 if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO)
1385 demux->video = TRUE;
1392 static const GstQueryType *
1393 gst_matroska_demux_get_src_query_types (GstPad * pad)
1395 static const GstQueryType query_types[] = {
1406 gst_matroska_demux_query (GstMatroskaDemux * demux, GstPad * pad,
1409 gboolean res = FALSE;
1410 GstMatroskaTrackContext *context = NULL;
1413 context = gst_pad_get_element_private (pad);
1416 switch (GST_QUERY_TYPE (query)) {
1417 case GST_QUERY_POSITION:
1421 gst_query_parse_position (query, &format, NULL);
1423 if (format == GST_FORMAT_TIME) {
1424 GST_OBJECT_LOCK (demux);
1426 gst_query_set_position (query, GST_FORMAT_TIME,
1427 MAX (context->pos, demux->stream_start_time) -
1428 demux->stream_start_time);
1430 gst_query_set_position (query, GST_FORMAT_TIME,
1431 MAX (demux->common.segment.last_stop, demux->stream_start_time) -
1432 demux->stream_start_time);
1433 GST_OBJECT_UNLOCK (demux);
1434 } else if (format == GST_FORMAT_DEFAULT && context
1435 && context->default_duration) {
1436 GST_OBJECT_LOCK (demux);
1437 gst_query_set_position (query, GST_FORMAT_DEFAULT,
1438 context->pos / context->default_duration);
1439 GST_OBJECT_UNLOCK (demux);
1441 GST_DEBUG_OBJECT (demux,
1442 "only position query in TIME and DEFAULT format is supported");
1448 case GST_QUERY_DURATION:
1452 gst_query_parse_duration (query, &format, NULL);
1454 if (format == GST_FORMAT_TIME) {
1455 GST_OBJECT_LOCK (demux);
1456 gst_query_set_duration (query, GST_FORMAT_TIME,
1457 demux->common.segment.duration);
1458 GST_OBJECT_UNLOCK (demux);
1459 } else if (format == GST_FORMAT_DEFAULT && context
1460 && context->default_duration) {
1461 GST_OBJECT_LOCK (demux);
1462 gst_query_set_duration (query, GST_FORMAT_DEFAULT,
1463 demux->common.segment.duration / context->default_duration);
1464 GST_OBJECT_UNLOCK (demux);
1466 GST_DEBUG_OBJECT (demux,
1467 "only duration query in TIME and DEFAULT format is supported");
1474 case GST_QUERY_SEEKING:
1478 gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
1479 GST_OBJECT_LOCK (demux);
1480 if (fmt == GST_FORMAT_TIME) {
1483 if (demux->streaming) {
1484 /* assuming we'll be able to get an index ... */
1485 seekable = demux->seekable;
1490 gst_query_set_seeking (query, GST_FORMAT_TIME, seekable,
1491 0, demux->common.segment.duration);
1494 GST_OBJECT_UNLOCK (demux);
1498 res = gst_pad_query_default (pad, query);
1506 gst_matroska_demux_element_query (GstElement * element, GstQuery * query)
1508 return gst_matroska_demux_query (GST_MATROSKA_DEMUX (element), NULL, query);
1512 gst_matroska_demux_handle_src_query (GstPad * pad, GstQuery * query)
1515 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (gst_pad_get_parent (pad));
1517 ret = gst_matroska_demux_query (demux, pad, query);
1519 gst_object_unref (demux);
1524 /* returns FALSE if there are no pads to deliver event to,
1525 * otherwise TRUE (whatever the outcome of event sending),
1526 * takes ownership of the passed event! */
1528 gst_matroska_demux_send_event (GstMatroskaDemux * demux, GstEvent * event)
1530 gboolean is_newsegment;
1531 gboolean ret = FALSE;
1534 g_return_val_if_fail (event != NULL, FALSE);
1536 GST_DEBUG_OBJECT (demux, "Sending event of type %s to all source pads",
1537 GST_EVENT_TYPE_NAME (event));
1539 is_newsegment = (GST_EVENT_TYPE (event) == GST_EVENT_NEWSEGMENT);
1541 g_assert (demux->common.src->len == demux->common.num_streams);
1542 for (i = 0; i < demux->common.src->len; i++) {
1543 GstMatroskaTrackContext *stream;
1545 stream = g_ptr_array_index (demux->common.src, i);
1546 gst_event_ref (event);
1547 gst_pad_push_event (stream->pad, event);
1550 /* FIXME: send global tags before stream tags */
1551 if (G_UNLIKELY (is_newsegment && stream->pending_tags != NULL)) {
1552 GST_DEBUG_OBJECT (demux, "Sending pending_tags %p for pad %s:%s : %"
1553 GST_PTR_FORMAT, stream->pending_tags,
1554 GST_DEBUG_PAD_NAME (stream->pad), stream->pending_tags);
1555 gst_element_found_tags_for_pad (GST_ELEMENT (demux), stream->pad,
1556 stream->pending_tags);
1557 stream->pending_tags = NULL;
1561 if (G_UNLIKELY (is_newsegment && demux->common.global_tags != NULL)) {
1562 gst_tag_list_add (demux->common.global_tags, GST_TAG_MERGE_REPLACE,
1563 GST_TAG_CONTAINER_FORMAT, "Matroska", NULL);
1564 GST_DEBUG_OBJECT (demux, "Sending global_tags %p : %" GST_PTR_FORMAT,
1565 demux->common.global_tags, demux->common.global_tags);
1566 gst_element_found_tags (GST_ELEMENT (demux), demux->common.global_tags);
1567 demux->common.global_tags = NULL;
1570 gst_event_unref (event);
1575 gst_matroska_demux_element_send_event (GstElement * element, GstEvent * event)
1577 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
1580 g_return_val_if_fail (event != NULL, FALSE);
1582 if (GST_EVENT_TYPE (event) == GST_EVENT_SEEK) {
1583 res = gst_matroska_demux_handle_seek_event (demux, NULL, event);
1585 GST_WARNING_OBJECT (demux, "Unhandled event of type %s",
1586 GST_EVENT_TYPE_NAME (event));
1589 gst_event_unref (event);
1594 gst_matroska_demux_move_to_entry (GstMatroskaDemux * demux,
1595 GstMatroskaIndex * entry, gboolean reset)
1599 GST_OBJECT_LOCK (demux);
1601 /* seek (relative to matroska segment) */
1602 /* position might be invalid; will error when streaming resumes ... */
1603 demux->common.offset = entry->pos + demux->common.ebml_segment_start;
1605 GST_DEBUG_OBJECT (demux, "Seeked to offset %" G_GUINT64_FORMAT ", block %d, "
1606 "time %" GST_TIME_FORMAT, entry->pos + demux->common.ebml_segment_start,
1607 entry->block, GST_TIME_ARGS (entry->time));
1609 /* update the time */
1610 gst_matroska_read_common_reset_streams (&demux->common, entry->time, TRUE);
1611 demux->common.segment.last_stop = entry->time;
1612 demux->seek_block = entry->block;
1613 demux->seek_first = TRUE;
1614 demux->last_stop_end = GST_CLOCK_TIME_NONE;
1616 for (i = 0; i < demux->common.src->len; i++) {
1617 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
1620 stream->to_offset = G_MAXINT64;
1622 if (stream->from_offset != -1)
1623 stream->to_offset = stream->from_offset;
1625 stream->from_offset = -1;
1628 GST_OBJECT_UNLOCK (demux);
1634 gst_matroska_cluster_compare (gint64 * i1, gint64 * i2)
1644 /* searches for a cluster start from @pos,
1645 * return GST_FLOW_OK and cluster position in @pos if found */
1646 static GstFlowReturn
1647 gst_matroska_demux_search_cluster (GstMatroskaDemux * demux, gint64 * pos)
1649 gint64 newpos = *pos;
1651 GstFlowReturn ret = GST_FLOW_OK;
1652 const guint chunk = 64 * 1024;
1653 GstBuffer *buf = NULL;
1658 orig_offset = demux->common.offset;
1660 GST_LOG_OBJECT (demux, "searching cluster following offset %" G_GINT64_FORMAT,
1663 if (demux->clusters) {
1666 cpos = gst_util_array_binary_search (demux->clusters->data,
1667 demux->clusters->len, sizeof (gint64),
1668 (GCompareDataFunc) gst_matroska_cluster_compare,
1669 GST_SEARCH_MODE_AFTER, pos, NULL);
1672 GST_DEBUG_OBJECT (demux,
1673 "cluster reported at offset %" G_GINT64_FORMAT, *cpos);
1674 demux->common.offset = *cpos;
1675 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1676 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1677 if (ret == GST_FLOW_OK && id == GST_MATROSKA_ID_CLUSTER) {
1684 /* read in at newpos and scan for ebml cluster id */
1686 GstByteReader reader;
1690 gst_buffer_unref (buf);
1693 ret = gst_pad_pull_range (demux->common.sinkpad, newpos, chunk, &buf);
1694 if (ret != GST_FLOW_OK)
1696 GST_DEBUG_OBJECT (demux, "read buffer size %d at offset %" G_GINT64_FORMAT,
1697 GST_BUFFER_SIZE (buf), newpos);
1698 gst_byte_reader_init_from_buffer (&reader, buf);
1700 cluster_pos = gst_byte_reader_masked_scan_uint32 (&reader, 0xffffffff,
1701 GST_MATROSKA_ID_CLUSTER, 0, gst_byte_reader_get_remaining (&reader));
1702 if (cluster_pos >= 0) {
1703 newpos += cluster_pos;
1704 /* prepare resuming at next byte */
1705 gst_byte_reader_skip (&reader, cluster_pos + 1);
1706 GST_DEBUG_OBJECT (demux,
1707 "found cluster ebml id at offset %" G_GINT64_FORMAT, newpos);
1708 /* extra checks whether we really sync'ed to a cluster:
1709 * - either it is the first and only cluster
1710 * - either there is a cluster after this one
1711 * - either cluster length is undefined
1713 /* ok if first cluster (there may not a subsequent one) */
1714 if (newpos == demux->first_cluster_offset) {
1715 GST_DEBUG_OBJECT (demux, "cluster is first cluster -> OK");
1718 demux->common.offset = newpos;
1719 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1720 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1721 if (ret != GST_FLOW_OK) {
1722 GST_DEBUG_OBJECT (demux, "need more data -> continue");
1725 g_assert (id == GST_MATROSKA_ID_CLUSTER);
1726 GST_DEBUG_OBJECT (demux, "cluster size %" G_GUINT64_FORMAT ", prefix %d",
1728 /* ok if undefined length or first cluster */
1729 if (length == GST_EBML_SIZE_UNKNOWN || length == G_MAXUINT64) {
1730 GST_DEBUG_OBJECT (demux, "cluster has undefined length -> OK");
1734 demux->common.offset += length + needed;
1735 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1736 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1737 if (ret != GST_FLOW_OK)
1739 GST_DEBUG_OBJECT (demux, "next element is %scluster",
1740 id == GST_MATROSKA_ID_CLUSTER ? "" : "not ");
1741 if (id == GST_MATROSKA_ID_CLUSTER)
1743 /* not ok, resume */
1746 /* partial cluster id may have been in tail of buffer */
1747 newpos += MAX (gst_byte_reader_get_remaining (&reader), 4) - 3;
1752 gst_buffer_unref (buf);
1757 demux->common.offset = orig_offset;
1762 /* bisect and scan through file for cluster starting before @time,
1763 * returns fake index entry with corresponding info on cluster */
1764 static GstMatroskaIndex *
1765 gst_matroska_demux_search_pos (GstMatroskaDemux * demux, GstClockTime time)
1767 GstMatroskaIndex *entry = NULL;
1768 GstMatroskaReadState current_state;
1769 GstClockTime otime, prev_cluster_time, current_cluster_time, cluster_time;
1770 gint64 opos, newpos, startpos = 0, current_offset;
1771 gint64 prev_cluster_offset = -1, current_cluster_offset, cluster_offset;
1772 const guint chunk = 64 * 1024;
1778 /* (under)estimate new position, resync using cluster ebml id,
1779 * and scan forward to appropriate cluster
1780 * (and re-estimate if need to go backward) */
1782 prev_cluster_time = GST_CLOCK_TIME_NONE;
1784 /* store some current state */
1785 current_state = demux->common.state;
1786 g_return_val_if_fail (current_state == GST_MATROSKA_READ_STATE_DATA, NULL);
1788 current_cluster_offset = demux->cluster_offset;
1789 current_cluster_time = demux->cluster_time;
1790 current_offset = demux->common.offset;
1792 demux->common.state = GST_MATROSKA_READ_STATE_SCANNING;
1794 /* estimate using start and current position */
1795 GST_OBJECT_LOCK (demux);
1796 opos = demux->common.offset - demux->common.ebml_segment_start;
1797 otime = demux->common.segment.last_stop;
1798 GST_OBJECT_UNLOCK (demux);
1801 time = MAX (time, demux->stream_start_time);
1803 /* avoid division by zero in first estimation below */
1804 if (otime <= demux->stream_start_time)
1808 GST_LOG_OBJECT (demux,
1809 "opos: %" G_GUINT64_FORMAT ", otime: %" GST_TIME_FORMAT ", %"
1810 GST_TIME_FORMAT " in stream time (start %" GST_TIME_FORMAT "), time %"
1811 GST_TIME_FORMAT, opos, GST_TIME_ARGS (otime),
1812 GST_TIME_ARGS (otime - demux->stream_start_time),
1813 GST_TIME_ARGS (demux->stream_start_time), GST_TIME_ARGS (time));
1815 gst_util_uint64_scale (opos - demux->common.ebml_segment_start,
1816 time - demux->stream_start_time,
1817 otime - demux->stream_start_time) - chunk;
1820 /* favour undershoot */
1821 newpos = newpos * 90 / 100;
1822 newpos += demux->common.ebml_segment_start;
1824 GST_DEBUG_OBJECT (demux,
1825 "estimated offset for %" GST_TIME_FORMAT ": %" G_GINT64_FORMAT,
1826 GST_TIME_ARGS (time), newpos);
1828 /* and at least start scanning before previous scan start to avoid looping */
1829 startpos = startpos * 90 / 100;
1830 if (startpos && startpos < newpos)
1833 /* read in at newpos and scan for ebml cluster id */
1837 ret = gst_matroska_demux_search_cluster (demux, &newpos);
1838 if (ret == GST_FLOW_UNEXPECTED) {
1839 /* heuristic HACK */
1840 newpos = startpos * 80 / 100;
1841 GST_DEBUG_OBJECT (demux, "EOS; "
1842 "new estimated offset for %" GST_TIME_FORMAT ": %" G_GINT64_FORMAT,
1843 GST_TIME_ARGS (time), newpos);
1846 } else if (ret != GST_FLOW_OK) {
1853 /* then start scanning and parsing for cluster time,
1854 * re-estimate if overshoot, otherwise next cluster and so on */
1855 demux->common.offset = newpos;
1856 demux->cluster_time = cluster_time = GST_CLOCK_TIME_NONE;
1858 guint64 cluster_size = 0;
1860 /* peek and parse some elements */
1861 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1862 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1863 if (ret != GST_FLOW_OK)
1865 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
1866 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
1868 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
1869 if (ret != GST_FLOW_OK)
1872 if (id == GST_MATROSKA_ID_CLUSTER) {
1873 cluster_time = GST_CLOCK_TIME_NONE;
1874 if (length == G_MAXUINT64)
1877 cluster_size = length + needed;
1879 if (demux->cluster_time != GST_CLOCK_TIME_NONE &&
1880 cluster_time == GST_CLOCK_TIME_NONE) {
1881 cluster_time = demux->cluster_time * demux->common.time_scale;
1882 cluster_offset = demux->cluster_offset;
1883 GST_DEBUG_OBJECT (demux, "found cluster at offset %" G_GINT64_FORMAT
1884 " with time %" GST_TIME_FORMAT, cluster_offset,
1885 GST_TIME_ARGS (cluster_time));
1886 if (cluster_time > time) {
1887 GST_DEBUG_OBJECT (demux, "overshot target");
1888 /* cluster overshoots */
1889 if (cluster_offset == demux->first_cluster_offset) {
1890 /* but no prev one */
1891 GST_DEBUG_OBJECT (demux, "but using first cluster anyway");
1892 prev_cluster_time = cluster_time;
1893 prev_cluster_offset = cluster_offset;
1896 if (prev_cluster_time != GST_CLOCK_TIME_NONE) {
1897 /* prev cluster did not overshoot, so prev cluster is target */
1900 /* re-estimate using this new position info */
1901 opos = cluster_offset;
1902 otime = cluster_time;
1906 /* cluster undershoots, goto next one */
1907 prev_cluster_time = cluster_time;
1908 prev_cluster_offset = cluster_offset;
1909 /* skip cluster if length is defined,
1910 * otherwise will be skippingly parsed into */
1912 GST_DEBUG_OBJECT (demux, "skipping to next cluster");
1913 demux->common.offset = cluster_offset + cluster_size;
1914 demux->cluster_time = GST_CLOCK_TIME_NONE;
1916 GST_DEBUG_OBJECT (demux, "parsing/skipping cluster elements");
1923 if (ret == GST_FLOW_UNEXPECTED) {
1924 if (prev_cluster_time != GST_CLOCK_TIME_NONE)
1930 entry = g_new0 (GstMatroskaIndex, 1);
1931 entry->time = prev_cluster_time;
1932 entry->pos = prev_cluster_offset - demux->common.ebml_segment_start;
1933 GST_DEBUG_OBJECT (demux, "simulated index entry; time %" GST_TIME_FORMAT
1934 ", pos %" G_GUINT64_FORMAT, GST_TIME_ARGS (entry->time), entry->pos);
1938 /* restore some state */
1939 demux->cluster_offset = current_cluster_offset;
1940 demux->cluster_time = current_cluster_time;
1941 demux->common.offset = current_offset;
1942 demux->common.state = current_state;
1948 gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
1949 GstPad * pad, GstEvent * event)
1951 GstMatroskaIndex *entry = NULL;
1952 GstMatroskaIndex scan_entry;
1953 #ifdef MKV_DEMUX_MODIFICATION
1954 GstMatroskaIndex *next_entry = NULL;
1957 GstSeekType cur_type, stop_type;
1959 gboolean flush, keyunit;
1962 GstMatroskaTrackContext *track = NULL;
1963 GstSegment seeksegment = { 0, };
1964 gboolean update = TRUE;
1967 track = gst_pad_get_element_private (pad);
1969 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
1972 /* we can only seek on time */
1973 if (format != GST_FORMAT_TIME) {
1974 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
1978 #ifndef MKV_DEMUX_MODIFICATION
1979 /* cannot yet do backwards playback */
1981 GST_DEBUG_OBJECT (demux, "Can only seek with positive rate");
1986 /* copy segment, we need this because we still need the old
1987 * segment when we close the current segment. */
1988 memcpy (&seeksegment, &demux->common.segment, sizeof (GstSegment));
1990 #ifdef MKV_DEMUX_MODIFICATION
1991 gst_segment_set_last_stop (&seeksegment, GST_FORMAT_TIME, cur);
1994 /* pull mode without index means that the actual duration is not known,
1995 * we might be playing a file that's still being recorded
1996 * so, invalidate our current duration, which is only a moving target,
1997 * and should not be used to clamp anything */
1998 if (!demux->streaming && !demux->common.index &&
1999 demux->invalid_duration) {
2000 gst_segment_set_duration (&seeksegment, GST_FORMAT_TIME,
2001 GST_CLOCK_TIME_NONE);
2005 GST_DEBUG_OBJECT (demux, "configuring seek");
2006 gst_segment_set_seek (&seeksegment, rate, format, flags,
2007 cur_type, cur, stop_type, stop, &update);
2008 /* compensate for clip start time */
2009 if (GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
2010 seeksegment.last_stop += demux->stream_start_time;
2011 seeksegment.start += demux->stream_start_time;
2012 if (GST_CLOCK_TIME_IS_VALID (seeksegment.stop))
2013 seeksegment.stop += demux->stream_start_time;
2014 /* note that time should stay at indicated position */
2018 /* restore segment duration (if any effect),
2019 * would be determined again when parsing, but anyway ... */
2020 #ifndef MKV_DEMUX_MODIFICATION
2021 gst_segment_set_duration (&seeksegment, GST_FORMAT_TIME,
2022 demux->common.segment.duration);
2025 flush = ! !(flags & GST_SEEK_FLAG_FLUSH);
2026 keyunit = ! !(flags & GST_SEEK_FLAG_KEY_UNIT);
2028 GST_DEBUG_OBJECT (demux, "New segment %" GST_SEGMENT_FORMAT, &seeksegment);
2030 #ifndef MKV_DEMUX_MODIFICATION
2032 /* only have to update some segment,
2033 * but also still have to honour flush and so on */
2034 GST_DEBUG_OBJECT (demux, "... no update");
2035 /* bad goto, bad ... */
2040 /* check sanity before we start flushing and all that */
2041 GST_OBJECT_LOCK (demux);
2042 track = gst_matroska_read_common_get_seek_track (&demux->common, track);
2043 if ((entry = gst_matroska_read_common_do_index_seek (&demux->common, track,
2044 seeksegment.last_stop, &demux->seek_index, &demux->seek_entry)) ==
2046 /* pull mode without index can scan later on */
2047 if (demux->streaming) {
2048 GST_DEBUG_OBJECT (demux, "No matching seek entry in index");
2049 GST_OBJECT_UNLOCK (demux);
2052 #ifdef MKV_DEMUX_MODIFICATION
2054 GST_INFO_OBJECT (demux, "Entry Details are");
2055 GST_INFO_OBJECT (demux, "entry->block %u", (guint)entry->block);
2056 GST_INFO_OBJECT (demux, "entry->pos %"G_GUINT64_FORMAT, entry->pos);
2057 GST_INFO_OBJECT (demux, "entry->time %"GST_TIME_FORMAT, GST_TIME_ARGS(entry->time));
2058 GST_INFO_OBJECT (demux, "entry->track %u", (guint)entry->track);
2062 #ifdef MKV_DEMUX_MODIFICATION
2063 if (entry == NULL) {
2064 GST_OBJECT_UNLOCK (demux);
2068 if (seeksegment.rate < 0.0) {
2069 GST_INFO("Current Index is %"GST_TIME_FORMAT, GST_TIME_ARGS(entry->time));
2070 next_entry = gst_matroska_demux_get_next_index (demux, track, entry);
2071 if (next_entry == NULL) {
2072 GST_ERROR ("Entry Not found....");
2073 GST_OBJECT_UNLOCK (demux);
2076 GST_INFO("Next Index is %"GST_TIME_FORMAT, GST_TIME_ARGS(next_entry->time));
2080 GST_DEBUG_OBJECT (demux, "Seek position looks sane");
2081 GST_OBJECT_UNLOCK (demux);
2083 if (demux->streaming) {
2084 /* need to seek to cluster start to pick up cluster time */
2085 /* upstream takes care of flushing and all that
2086 * ... and newsegment event handling takes care of the rest */
2087 return perform_seek_to_offset (demux,
2088 entry->pos + demux->common.ebml_segment_start);
2091 #ifdef MKV_DEMUX_MODIFICATION
2092 keyunit = TRUE;//intentionally making it as true. need to check
2097 GST_DEBUG_OBJECT (demux, "Starting flush");
2098 gst_pad_push_event (demux->common.sinkpad, gst_event_new_flush_start ());
2099 gst_matroska_demux_send_event (demux, gst_event_new_flush_start ());
2101 GST_DEBUG_OBJECT (demux, "Non-flushing seek, pausing task");
2102 gst_pad_pause_task (demux->common.sinkpad);
2105 #ifndef MKV_DEMUX_MODIFICATION
2111 /* now grab the stream lock so that streaming cannot continue, for
2112 * non flushing seeks when the element is in PAUSED this could block
2114 GST_DEBUG_OBJECT (demux, "Waiting for streaming to stop");
2115 GST_PAD_STREAM_LOCK (demux->common.sinkpad);
2117 /* pull mode without index can do some scanning */
2118 if (!demux->streaming && !entry) {
2119 /* need to stop flushing upstream as we need it next */
2121 gst_pad_push_event (demux->common.sinkpad, gst_event_new_flush_stop ());
2122 entry = gst_matroska_demux_search_pos (demux, seeksegment.last_stop);
2123 /* keep local copy */
2125 scan_entry = *entry;
2127 entry = &scan_entry;
2129 GST_DEBUG_OBJECT (demux, "Scan failed to find matching position");
2131 gst_matroska_demux_send_event (demux, gst_event_new_flush_stop ());
2137 GST_DEBUG_OBJECT (demux, "seek to key unit, adjusting segment start to %"
2138 GST_TIME_FORMAT, GST_TIME_ARGS (entry->time));
2139 #ifdef MKV_DEMUX_MODIFICATION
2140 if (seeksegment.stop == -1) {
2141 seeksegment.stop = seeksegment.duration;
2143 if (seeksegment.rate > 0.0) {
2144 seeksegment.start = cur;
2145 seeksegment.time = cur;
2146 seeksegment.last_stop = cur;
2147 seeksegment.stop = seeksegment.duration;
2148 } else if (seeksegment.rate < 0.0) {/* Reverse trick play */
2149 seeksegment.start = 0.0;
2150 seeksegment.stop = next_entry->time;
2151 seeksegment.last_stop = cur + GST_MSECOND;
2152 seeksegment.time = 0.0;
2153 demux->next_keyframe_ts = cur;
2154 GST_INFO("next_keyframe_ts %"GST_TIME_FORMAT, GST_TIME_ARGS(demux->next_keyframe_ts));
2157 seeksegment.start = MAX (entry->time, demux->stream_start_time);
2158 seeksegment.last_stop = seeksegment.start;
2159 seeksegment.time = seeksegment.start - demux->stream_start_time;
2165 GST_DEBUG_OBJECT (demux, "Stopping flush");
2166 gst_pad_push_event (demux->common.sinkpad, gst_event_new_flush_stop ());
2167 gst_matroska_demux_send_event (demux, gst_event_new_flush_stop ());
2168 #ifdef MKV_DEMUX_MODIFICATION
2169 } else if (demux->segment_running) {
2171 } else if (demux->segment_running && update) {
2173 GST_DEBUG_OBJECT (demux, "Closing currently running segment");
2175 GST_OBJECT_LOCK (demux);
2176 if (demux->close_segment)
2177 gst_event_unref (demux->close_segment);
2179 demux->close_segment = gst_event_new_new_segment (TRUE,
2180 demux->common.segment.rate, GST_FORMAT_TIME,
2181 demux->common.segment.start, demux->common.segment.last_stop,
2182 demux->common.segment.time);
2183 GST_OBJECT_UNLOCK (demux);
2186 GST_OBJECT_LOCK (demux);
2187 /* now update the real segment info */
2188 GST_DEBUG_OBJECT (demux, "Committing new seek segment");
2189 memcpy (&demux->common.segment, &seeksegment, sizeof (GstSegment));
2190 GST_OBJECT_UNLOCK (demux);
2192 /* update some (segment) state */
2193 #ifdef MKV_DEMUX_MODIFICATION
2194 if (!gst_matroska_demux_move_to_entry (demux, entry, TRUE))
2196 if (update && !gst_matroska_demux_move_to_entry (demux, entry, TRUE))
2200 /* notify start of new segment */
2201 if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
2204 msg = gst_message_new_segment_start (GST_OBJECT (demux),
2205 GST_FORMAT_TIME, demux->common.segment.start);
2206 gst_element_post_message (GST_ELEMENT (demux), msg);
2209 GST_OBJECT_LOCK (demux);
2210 if (demux->new_segment)
2211 gst_event_unref (demux->new_segment);
2212 #ifdef MKV_DEMUX_MODIFICATION
2213 if (demux->common.segment.rate > 0.0) {
2214 demux->new_segment = gst_event_new_new_segment_full (FALSE,
2215 demux->common.segment.rate, demux->common.segment.applied_rate,
2216 demux->common.segment.format, seeksegment.last_stop,
2217 demux->common.segment.stop, demux->common.segment.time);
2219 } else if (demux->common.segment.rate < 0.0) {
2220 /* Reverse trick play */
2221 demux->new_segment = gst_event_new_new_segment_full (FALSE,
2222 demux->common.segment.rate, demux->common.segment.applied_rate,
2223 demux->common.segment.format, demux->common.segment.start,
2224 seeksegment.last_stop, demux->common.segment.time);
2227 demux->new_segment = gst_event_new_new_segment_full (!update,
2228 demux->common.segment.rate, demux->common.segment.applied_rate,
2229 demux->common.segment.format, demux->common.segment.start,
2230 demux->common.segment.stop, demux->common.segment.time);
2232 GST_OBJECT_UNLOCK (demux);
2234 #ifdef MKV_DEMUX_MODIFICATION
2235 if (demux->common.segment.rate > 0.0) {
2236 demux->common.segment.last_stop = entry->time;
2237 } else if (demux->common.segment.rate < 0.0) {
2238 demux->common.segment.last_stop = next_entry->time;
2242 /* restart our task since it might have been stopped when we did the
2244 demux->segment_running = TRUE;
2245 gst_pad_start_task (demux->common.sinkpad,
2246 (GstTaskFunction) gst_matroska_demux_loop, demux->common.sinkpad);
2248 #ifdef MKV_DEMUX_MODIFICATION
2249 while (!g_queue_is_empty (track->queue)) {
2250 GstBuffer* buf = g_queue_pop_head (track->queue);
2251 gst_buffer_unref (buf);
2255 /* streaming can continue now */
2256 GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
2262 GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
2263 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Got a seek error"));
2269 * Handle whether we can perform the seek event or if we have to let the chain
2270 * function handle seeks to build the seek indexes first.
2273 gst_matroska_demux_handle_seek_push (GstMatroskaDemux * demux, GstPad * pad,
2277 GstSeekType cur_type, stop_type;
2282 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
2287 /* we can only seek on time */
2288 if (format != GST_FORMAT_TIME) {
2289 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
2293 if (stop_type != GST_SEEK_TYPE_NONE && stop != GST_CLOCK_TIME_NONE) {
2294 GST_DEBUG_OBJECT (demux, "Seek end-time not supported in streaming mode");
2298 if (!(flags & GST_SEEK_FLAG_FLUSH)) {
2299 GST_DEBUG_OBJECT (demux,
2300 "Non-flushing seek not supported in streaming mode");
2304 if (flags & GST_SEEK_FLAG_SEGMENT) {
2305 GST_DEBUG_OBJECT (demux, "Segment seek not supported in streaming mode");
2309 /* check for having parsed index already */
2310 if (!demux->common.index_parsed) {
2311 gboolean building_index;
2314 if (!demux->index_offset) {
2315 GST_DEBUG_OBJECT (demux, "no index (location); no seek in push mode");
2319 GST_OBJECT_LOCK (demux);
2320 /* handle the seek event in the chain function */
2321 demux->common.state = GST_MATROSKA_READ_STATE_SEEK;
2322 /* no more seek can be issued until state reset to _DATA */
2324 /* copy the event */
2325 if (demux->seek_event)
2326 gst_event_unref (demux->seek_event);
2327 demux->seek_event = gst_event_ref (event);
2329 /* set the building_index flag so that only one thread can setup the
2330 * structures for index seeking. */
2331 building_index = demux->building_index;
2332 if (!building_index) {
2333 demux->building_index = TRUE;
2334 offset = demux->index_offset;
2336 GST_OBJECT_UNLOCK (demux);
2338 if (!building_index) {
2339 /* seek to the first subindex or legacy index */
2340 GST_INFO_OBJECT (demux, "Seeking to Cues at %" G_GUINT64_FORMAT, offset);
2341 return perform_seek_to_offset (demux, offset);
2344 /* well, we are handling it already */
2348 /* delegate to tweaked regular seek */
2349 return gst_matroska_demux_handle_seek_event (demux, pad, event);
2353 gst_matroska_demux_handle_src_event (GstPad * pad, GstEvent * event)
2355 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (gst_pad_get_parent (pad));
2356 gboolean res = TRUE;
2358 switch (GST_EVENT_TYPE (event)) {
2359 case GST_EVENT_SEEK:
2360 /* no seeking until we are (safely) ready */
2361 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
2362 GST_DEBUG_OBJECT (demux, "not ready for seeking yet");
2365 if (!demux->streaming)
2366 res = gst_matroska_demux_handle_seek_event (demux, pad, event);
2368 res = gst_matroska_demux_handle_seek_push (demux, pad, event);
2369 gst_event_unref (event);
2374 GstMatroskaTrackContext *context = gst_pad_get_element_private (pad);
2375 if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
2376 GstMatroskaTrackVideoContext *videocontext =
2377 (GstMatroskaTrackVideoContext *) context;
2379 GstClockTimeDiff diff;
2380 GstClockTime timestamp;
2382 gst_event_parse_qos (event, &proportion, &diff, ×tamp);
2384 GST_OBJECT_LOCK (demux);
2385 videocontext->earliest_time = timestamp + diff;
2386 GST_OBJECT_UNLOCK (demux);
2389 gst_event_unref (event);
2393 /* events we don't need to handle */
2394 case GST_EVENT_NAVIGATION:
2395 gst_event_unref (event);
2399 case GST_EVENT_LATENCY:
2401 res = gst_pad_push_event (demux->common.sinkpad, event);
2405 gst_object_unref (demux);
2410 static GstFlowReturn
2411 gst_matroska_demux_seek_to_previous_keyframe (GstMatroskaDemux * demux)
2413 GstFlowReturn ret = GST_FLOW_UNEXPECTED;
2414 gboolean done = TRUE;
2417 g_return_val_if_fail (demux->seek_index, GST_FLOW_UNEXPECTED);
2418 g_return_val_if_fail (demux->seek_entry < demux->seek_index->len,
2419 GST_FLOW_UNEXPECTED);
2421 GST_DEBUG_OBJECT (demux, "locating previous keyframe");
2423 if (!demux->seek_entry) {
2424 GST_DEBUG_OBJECT (demux, "no earlier index entry");
2428 for (i = 0; i < demux->common.src->len; i++) {
2429 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
2431 GST_DEBUG_OBJECT (demux, "segment start %" GST_TIME_FORMAT
2432 ", stream %d at %" GST_TIME_FORMAT,
2433 GST_TIME_ARGS (demux->common.segment.start), stream->index,
2434 GST_TIME_ARGS (stream->from_time));
2435 if (GST_CLOCK_TIME_IS_VALID (stream->from_time)) {
2436 if (stream->from_time > demux->common.segment.start) {
2437 GST_DEBUG_OBJECT (demux, "stream %d not finished yet", stream->index);
2441 /* nothing pushed for this stream;
2442 * likely seek entry did not start at keyframe, so all was skipped.
2443 * So we need an earlier entry */
2449 GstMatroskaIndex *entry;
2451 entry = &g_array_index (demux->seek_index, GstMatroskaIndex,
2452 --demux->seek_entry);
2453 if (!gst_matroska_demux_move_to_entry (demux, entry, FALSE))
2463 static GstFlowReturn
2464 gst_matroska_demux_parse_tracks (GstMatroskaDemux * demux, GstEbmlRead * ebml)
2466 GstFlowReturn ret = GST_FLOW_OK;
2469 DEBUG_ELEMENT_START (demux, ebml, "Tracks");
2471 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2472 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
2476 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
2477 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
2481 /* one track within the "all-tracks" header */
2482 case GST_MATROSKA_ID_TRACKENTRY:
2483 ret = gst_matroska_demux_add_stream (demux, ebml);
2487 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
2492 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
2494 demux->tracks_parsed = TRUE;
2500 * Read signed/unsigned "EBML" numbers.
2501 * Return: number of bytes processed.
2505 gst_matroska_ebmlnum_uint (guint8 * data, guint size, guint64 * num)
2507 gint len_mask = 0x80, read = 1, n = 1, num_ffs = 0;
2515 while (read <= 8 && !(total & len_mask)) {
2522 if ((total &= (len_mask - 1)) == len_mask - 1)
2527 if (data[n] == 0xff)
2529 total = (total << 8) | data[n];
2533 if (read == num_ffs && total != 0)
2542 gst_matroska_ebmlnum_sint (guint8 * data, guint size, gint64 * num)
2547 /* read as unsigned number first */
2548 if ((res = gst_matroska_ebmlnum_uint (data, size, &unum)) < 0)
2552 if (unum == G_MAXUINT64)
2555 *num = unum - ((1 << ((7 * res) - 1)) - 1);
2561 * Mostly used for subtitles. We add void filler data for each
2562 * lagging stream to make sure we don't deadlock.
2566 gst_matroska_demux_sync_streams (GstMatroskaDemux * demux)
2570 GST_OBJECT_LOCK (demux);
2572 GST_LOG_OBJECT (demux, "Sync to %" GST_TIME_FORMAT,
2573 GST_TIME_ARGS (demux->common.segment.last_stop));
2575 g_assert (demux->common.num_streams == demux->common.src->len);
2576 for (stream_nr = 0; stream_nr < demux->common.src->len; stream_nr++) {
2577 GstMatroskaTrackContext *context;
2579 context = g_ptr_array_index (demux->common.src, stream_nr);
2581 GST_LOG_OBJECT (demux,
2582 "Checking for resync on stream %d (%" GST_TIME_FORMAT ")", stream_nr,
2583 GST_TIME_ARGS (context->pos));
2585 if (G_LIKELY (context->type != GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
2586 GST_LOG_OBJECT (demux, "Skipping sync on non-subtitle stream");
2589 #ifndef MKV_DEMUX_MODIFICATION
2590 /* does it lag? 0.5 seconds is a random threshold...
2591 * lag need only be considered if we have advanced into requested segment */
2592 if (GST_CLOCK_TIME_IS_VALID (context->pos) &&
2593 GST_CLOCK_TIME_IS_VALID (demux->common.segment.last_stop) &&
2594 demux->common.segment.last_stop > demux->common.segment.start &&
2595 context->pos + (GST_SECOND / 2) < demux->common.segment.last_stop) {
2599 new_start = demux->common.segment.last_stop - (GST_SECOND / 2);
2600 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop))
2601 new_start = MIN (new_start, demux->common.segment.stop);
2602 GST_DEBUG_OBJECT (demux,
2603 "Synchronizing stream %d with others by advancing time " "from %"
2604 GST_TIME_FORMAT " to %" GST_TIME_FORMAT, stream_nr,
2605 GST_TIME_ARGS (context->pos), GST_TIME_ARGS (new_start));
2607 context->pos = new_start;
2609 /* advance stream time */
2610 event = gst_event_new_new_segment (TRUE, demux->common.segment.rate,
2611 demux->common.segment.format, new_start, demux->common.segment.stop,
2613 GST_OBJECT_UNLOCK (demux);
2614 gst_pad_push_event (context->pad, event);
2615 GST_OBJECT_LOCK (demux);
2620 GST_OBJECT_UNLOCK (demux);
2623 static GstFlowReturn
2624 gst_matroska_demux_push_hdr_buf (GstMatroskaDemux * demux,
2625 GstMatroskaTrackContext * stream, guint8 * data, guint len)
2627 GstFlowReturn ret, cret;
2628 GstBuffer *header_buf;
2630 header_buf = gst_buffer_new_and_alloc (len);
2631 gst_buffer_set_caps (header_buf, stream->caps);
2632 memcpy (GST_BUFFER_DATA (header_buf), data, len);
2634 if (stream->set_discont) {
2635 GST_BUFFER_FLAG_SET (header_buf, GST_BUFFER_FLAG_DISCONT);
2636 stream->set_discont = FALSE;
2639 ret = gst_pad_push (stream->pad, header_buf);
2642 cret = gst_matroska_demux_combine_flows (demux, stream, ret);
2647 static GstFlowReturn
2648 gst_matroska_demux_push_flac_codec_priv_data (GstMatroskaDemux * demux,
2649 GstMatroskaTrackContext * stream)
2655 GST_LOG_OBJECT (demux, "priv data size = %u", stream->codec_priv_size);
2657 pdata = (guint8 *) stream->codec_priv;
2659 /* need at least 'fLaC' marker + STREAMINFO metadata block */
2660 if (stream->codec_priv_size < ((4) + (4 + 34))) {
2661 GST_WARNING_OBJECT (demux, "not enough codec priv data for flac headers");
2662 return GST_FLOW_ERROR;
2665 if (memcmp (pdata, "fLaC", 4) != 0) {
2666 GST_WARNING_OBJECT (demux, "no flac marker at start of stream headers");
2667 return GST_FLOW_ERROR;
2670 ret = gst_matroska_demux_push_hdr_buf (demux, stream, pdata, 4);
2671 if (ret != GST_FLOW_OK)
2674 off = 4; /* skip fLaC marker */
2675 while (off < stream->codec_priv_size) {
2676 len = GST_READ_UINT8 (pdata + off + 1) << 16;
2677 len |= GST_READ_UINT8 (pdata + off + 2) << 8;
2678 len |= GST_READ_UINT8 (pdata + off + 3);
2680 GST_DEBUG_OBJECT (demux, "header packet: len=%u bytes, flags=0x%02x",
2681 len, (guint) pdata[off]);
2683 ret = gst_matroska_demux_push_hdr_buf (demux, stream, pdata + off, len + 4);
2684 if (ret != GST_FLOW_OK)
2692 static GstFlowReturn
2693 gst_matroska_demux_push_speex_codec_priv_data (GstMatroskaDemux * demux,
2694 GstMatroskaTrackContext * stream)
2699 GST_LOG_OBJECT (demux, "priv data size = %u", stream->codec_priv_size);
2701 pdata = (guint8 *) stream->codec_priv;
2703 /* need at least 'fLaC' marker + STREAMINFO metadata block */
2704 if (stream->codec_priv_size < 80) {
2705 GST_WARNING_OBJECT (demux, "not enough codec priv data for speex headers");
2706 return GST_FLOW_ERROR;
2709 if (memcmp (pdata, "Speex ", 8) != 0) {
2710 GST_WARNING_OBJECT (demux, "no Speex marker at start of stream headers");
2711 return GST_FLOW_ERROR;
2714 ret = gst_matroska_demux_push_hdr_buf (demux, stream, pdata, 80);
2715 if (ret != GST_FLOW_OK)
2718 if (stream->codec_priv_size == 80)
2721 return gst_matroska_demux_push_hdr_buf (demux, stream, pdata + 80,
2722 stream->codec_priv_size - 80);
2725 static GstFlowReturn
2726 gst_matroska_demux_push_xiph_codec_priv_data (GstMatroskaDemux * demux,
2727 GstMatroskaTrackContext * stream)
2730 guint8 *p = (guint8 *) stream->codec_priv;
2731 gint i, offset, num_packets;
2732 guint *length, last;
2734 if (stream->codec_priv == NULL || stream->codec_priv_size == 0) {
2735 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
2736 ("Missing codec private data for xiph headers, broken file"));
2737 return GST_FLOW_ERROR;
2740 /* start of the stream and vorbis audio or theora video, need to
2741 * send the codec_priv data as first three packets */
2742 num_packets = p[0] + 1;
2743 GST_DEBUG_OBJECT (demux, "%u stream headers, total length=%u bytes",
2744 (guint) num_packets, stream->codec_priv_size);
2746 length = g_alloca (num_packets * sizeof (guint));
2750 /* first packets, read length values */
2751 for (i = 0; i < num_packets - 1; i++) {
2753 while (offset < stream->codec_priv_size) {
2754 length[i] += p[offset];
2755 if (p[offset++] != 0xff)
2760 if (offset + last > stream->codec_priv_size)
2761 return GST_FLOW_ERROR;
2763 /* last packet is the remaining size */
2764 length[i] = stream->codec_priv_size - offset - last;
2766 for (i = 0; i < num_packets; i++) {
2767 GST_DEBUG_OBJECT (demux, "buffer %d: length=%u bytes", i,
2769 if (offset + length[i] > stream->codec_priv_size)
2770 return GST_FLOW_ERROR;
2773 gst_matroska_demux_push_hdr_buf (demux, stream, p + offset, length[i]);
2774 if (ret != GST_FLOW_OK)
2777 offset += length[i];
2783 gst_matroska_demux_push_dvd_clut_change_event (GstMatroskaDemux * demux,
2784 GstMatroskaTrackContext * stream)
2788 g_assert (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB));
2790 if (!stream->codec_priv)
2793 /* ideally, VobSub private data should be parsed and stored more convenient
2794 * elsewhere, but for now, only interested in a small part */
2796 /* make sure we have terminating 0 */
2797 buf = g_strndup ((gchar *) stream->codec_priv, stream->codec_priv_size);
2799 /* just locate and parse palette part */
2800 start = strstr (buf, "palette:");
2805 guint8 r, g, b, y, u, v;
2808 while (g_ascii_isspace (*start))
2810 for (i = 0; i < 16; i++) {
2811 if (sscanf (start, "%06x", &col) != 1)
2814 while ((*start == ',') || g_ascii_isspace (*start))
2816 /* sigh, need to convert this from vobsub pseudo-RGB to YUV */
2817 r = (col >> 16) & 0xff;
2818 g = (col >> 8) & 0xff;
2820 y = CLAMP ((0.1494 * r + 0.6061 * g + 0.2445 * b) * 219 / 255 + 16, 0,
2822 u = CLAMP (0.6066 * r - 0.4322 * g - 0.1744 * b + 128, 0, 255);
2823 v = CLAMP (-0.08435 * r - 0.3422 * g + 0.4266 * b + 128, 0, 255);
2824 clut[i] = (y << 16) | (u << 8) | v;
2827 /* got them all without problems; build and send event */
2831 s = gst_structure_new ("application/x-gst-dvd", "event", G_TYPE_STRING,
2832 "dvd-spu-clut-change", "clut00", G_TYPE_INT, clut[0], "clut01",
2833 G_TYPE_INT, clut[1], "clut02", G_TYPE_INT, clut[2], "clut03",
2834 G_TYPE_INT, clut[3], "clut04", G_TYPE_INT, clut[4], "clut05",
2835 G_TYPE_INT, clut[5], "clut06", G_TYPE_INT, clut[6], "clut07",
2836 G_TYPE_INT, clut[7], "clut08", G_TYPE_INT, clut[8], "clut09",
2837 G_TYPE_INT, clut[9], "clut10", G_TYPE_INT, clut[10], "clut11",
2838 G_TYPE_INT, clut[11], "clut12", G_TYPE_INT, clut[12], "clut13",
2839 G_TYPE_INT, clut[13], "clut14", G_TYPE_INT, clut[14], "clut15",
2840 G_TYPE_INT, clut[15], NULL);
2842 gst_pad_push_event (stream->pad,
2843 gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM, s));
2849 static GstFlowReturn
2850 gst_matroska_demux_add_mpeg_seq_header (GstElement * element,
2851 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2854 guint seq_header_len;
2857 if (stream->codec_state) {
2858 seq_header = stream->codec_state;
2859 seq_header_len = stream->codec_state_size;
2860 } else if (stream->codec_priv) {
2861 seq_header = stream->codec_priv;
2862 seq_header_len = stream->codec_priv_size;
2867 /* Sequence header only needed for keyframes */
2868 if (GST_BUFFER_FLAG_IS_SET (*buf, GST_BUFFER_FLAG_DELTA_UNIT))
2871 if (GST_BUFFER_SIZE (*buf) < 4)
2874 header = GST_READ_UINT32_BE (GST_BUFFER_DATA (*buf));
2875 /* Sequence start code, if not found prepend */
2876 if (header != 0x000001b3) {
2879 newbuf = gst_buffer_new_and_alloc (GST_BUFFER_SIZE (*buf) + seq_header_len);
2880 gst_buffer_set_caps (newbuf, stream->caps);
2882 GST_DEBUG_OBJECT (element, "Prepending MPEG sequence header");
2883 gst_buffer_copy_metadata (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
2884 GST_BUFFER_COPY_FLAGS);
2885 g_memmove (GST_BUFFER_DATA (newbuf), seq_header, seq_header_len);
2886 g_memmove (GST_BUFFER_DATA (newbuf) + seq_header_len,
2887 GST_BUFFER_DATA (*buf), GST_BUFFER_SIZE (*buf));
2888 gst_buffer_unref (*buf);
2895 static GstFlowReturn
2896 gst_matroska_demux_add_wvpk_header (GstElement * element,
2897 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2899 GstMatroskaTrackAudioContext *audiocontext =
2900 (GstMatroskaTrackAudioContext *) stream;
2901 GstBuffer *newbuf = NULL;
2911 wvh.version = GST_READ_UINT16_LE (stream->codec_priv);
2914 wvh.total_samples = -1;
2915 wvh.block_index = audiocontext->wvpk_block_index;
2917 if (audiocontext->channels <= 2) {
2918 guint32 block_samples;
2920 block_samples = GST_READ_UINT32_LE (GST_BUFFER_DATA (*buf));
2921 /* we need to reconstruct the header of the wavpack block */
2923 /* -20 because ck_size is the size of the wavpack block -8
2924 * and lace_size is the size of the wavpack block + 12
2925 * (the three guint32 of the header that already are in the buffer) */
2926 wvh.ck_size = GST_BUFFER_SIZE (*buf) + sizeof (Wavpack4Header) - 20;
2928 /* block_samples, flags and crc are already in the buffer */
2929 newlen = GST_BUFFER_SIZE (*buf) + sizeof (Wavpack4Header) - 12;
2930 newbuf = gst_buffer_new_and_alloc (newlen);
2931 gst_buffer_set_caps (newbuf, stream->caps);
2933 data = GST_BUFFER_DATA (newbuf);
2938 GST_WRITE_UINT32_LE (data + 4, wvh.ck_size);
2939 GST_WRITE_UINT16_LE (data + 8, wvh.version);
2940 GST_WRITE_UINT8 (data + 10, wvh.track_no);
2941 GST_WRITE_UINT8 (data + 11, wvh.index_no);
2942 GST_WRITE_UINT32_LE (data + 12, wvh.total_samples);
2943 GST_WRITE_UINT32_LE (data + 16, wvh.block_index);
2944 g_memmove (data + 20, GST_BUFFER_DATA (*buf), GST_BUFFER_SIZE (*buf));
2945 gst_buffer_copy_metadata (newbuf, *buf,
2946 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS);
2947 gst_buffer_unref (*buf);
2949 audiocontext->wvpk_block_index += block_samples;
2954 guint32 block_samples, flags, crc, blocksize;
2956 data = GST_BUFFER_DATA (*buf);
2957 size = GST_BUFFER_SIZE (*buf);
2960 GST_ERROR_OBJECT (element, "Too small wavpack buffer");
2961 return GST_FLOW_ERROR;
2964 block_samples = GST_READ_UINT32_LE (data);
2969 flags = GST_READ_UINT32_LE (data);
2972 crc = GST_READ_UINT32_LE (data);
2975 blocksize = GST_READ_UINT32_LE (data);
2979 if (blocksize == 0 || size < blocksize)
2982 if (newbuf == NULL) {
2983 newbuf = gst_buffer_new_and_alloc (sizeof (Wavpack4Header) + blocksize);
2984 gst_buffer_set_caps (newbuf, stream->caps);
2986 gst_buffer_copy_metadata (newbuf, *buf,
2987 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS);
2990 outdata = GST_BUFFER_DATA (newbuf);
2992 GST_BUFFER_SIZE (newbuf) += sizeof (Wavpack4Header) + blocksize;
2993 GST_BUFFER_DATA (newbuf) =
2994 g_realloc (GST_BUFFER_DATA (newbuf), GST_BUFFER_SIZE (newbuf));
2995 GST_BUFFER_MALLOCDATA (newbuf) = GST_BUFFER_DATA (newbuf);
2996 outdata = GST_BUFFER_DATA (newbuf);
2999 outdata[outpos] = 'w';
3000 outdata[outpos + 1] = 'v';
3001 outdata[outpos + 2] = 'p';
3002 outdata[outpos + 3] = 'k';
3005 GST_WRITE_UINT32_LE (outdata + outpos,
3006 blocksize + sizeof (Wavpack4Header) - 8);
3007 GST_WRITE_UINT16_LE (outdata + outpos + 4, wvh.version);
3008 GST_WRITE_UINT8 (outdata + outpos + 6, wvh.track_no);
3009 GST_WRITE_UINT8 (outdata + outpos + 7, wvh.index_no);
3010 GST_WRITE_UINT32_LE (outdata + outpos + 8, wvh.total_samples);
3011 GST_WRITE_UINT32_LE (outdata + outpos + 12, wvh.block_index);
3012 GST_WRITE_UINT32_LE (outdata + outpos + 16, block_samples);
3013 GST_WRITE_UINT32_LE (outdata + outpos + 20, flags);
3014 GST_WRITE_UINT32_LE (outdata + outpos + 24, crc);
3017 g_memmove (outdata + outpos, data, blocksize);
3018 outpos += blocksize;
3022 gst_buffer_unref (*buf);
3024 audiocontext->wvpk_block_index += block_samples;
3030 /* @text must be null-terminated */
3032 gst_matroska_demux_subtitle_chunk_has_tag (GstElement * element,
3037 /* yes, this might all lead to false positives ... */
3038 tag = (gchar *) text;
3039 while ((tag = strchr (tag, '<'))) {
3041 if (*tag != '\0' && *(tag + 1) == '>') {
3042 /* some common convenience ones */
3043 /* maybe any character will do here ? */
3056 if (strstr (text, "<span"))
3062 static GstFlowReturn
3063 gst_matroska_demux_check_subtitle_buffer (GstElement * element,
3064 GstMatroskaTrackContext * stream, GstBuffer ** buf)
3066 GstMatroskaTrackSubtitleContext *sub_stream;
3067 const gchar *encoding, *data;
3073 sub_stream = (GstMatroskaTrackSubtitleContext *) stream;
3075 data = (const gchar *) GST_BUFFER_DATA (*buf);
3076 size = GST_BUFFER_SIZE (*buf);
3078 if (!sub_stream->invalid_utf8) {
3079 if (g_utf8_validate (data, size, NULL)) {
3082 GST_WARNING_OBJECT (element, "subtitle stream %d is not valid UTF-8, this "
3083 "is broken according to the matroska specification", stream->num);
3084 sub_stream->invalid_utf8 = TRUE;
3087 /* file with broken non-UTF8 subtitle, do the best we can do to fix it */
3088 encoding = g_getenv ("GST_SUBTITLE_ENCODING");
3089 if (encoding == NULL || *encoding == '\0') {
3090 /* if local encoding is UTF-8 and no encoding specified
3091 * via the environment variable, assume ISO-8859-15 */
3092 if (g_get_charset (&encoding)) {
3093 encoding = "ISO-8859-15";
3097 utf8 = g_convert_with_fallback (data, size, "UTF-8", encoding, (char *) "*",
3101 GST_LOG_OBJECT (element, "could not convert string from '%s' to UTF-8: %s",
3102 encoding, err->message);
3106 /* invalid input encoding, fall back to ISO-8859-15 (always succeeds) */
3107 encoding = "ISO-8859-15";
3108 utf8 = g_convert_with_fallback (data, size, "UTF-8", encoding, (char *) "*",
3112 GST_LOG_OBJECT (element, "converted subtitle text from %s to UTF-8 %s",
3113 encoding, (err) ? "(using ISO-8859-15 as fallback)" : "");
3116 utf8 = g_strdup ("invalid subtitle");
3118 newbuf = gst_buffer_new ();
3119 GST_BUFFER_MALLOCDATA (newbuf) = (guint8 *) utf8;
3120 GST_BUFFER_DATA (newbuf) = (guint8 *) utf8;
3121 GST_BUFFER_SIZE (newbuf) = strlen (utf8);
3122 gst_buffer_copy_metadata (newbuf, *buf, GST_BUFFER_COPY_ALL);
3123 gst_buffer_unref (*buf);
3126 data = (const gchar *) GST_BUFFER_DATA (*buf);
3127 size = GST_BUFFER_SIZE (*buf);
3131 if (sub_stream->check_markup) {
3132 /* caps claim markup text, so we need to escape text,
3133 * except if text is already markup and then needs no further escaping */
3134 sub_stream->seen_markup_tag = sub_stream->seen_markup_tag ||
3135 gst_matroska_demux_subtitle_chunk_has_tag (element, data);
3137 if (!sub_stream->seen_markup_tag) {
3138 utf8 = g_markup_escape_text (data, size);
3140 newbuf = gst_buffer_new ();
3141 GST_BUFFER_MALLOCDATA (newbuf) = (guint8 *) utf8;
3142 GST_BUFFER_DATA (newbuf) = (guint8 *) utf8;
3143 GST_BUFFER_SIZE (newbuf) = strlen (utf8);
3144 gst_buffer_copy_metadata (newbuf, *buf, GST_BUFFER_COPY_ALL);
3145 gst_buffer_unref (*buf);
3154 static GstFlowReturn
3155 gst_matroska_demux_check_aac (GstElement * element,
3156 GstMatroskaTrackContext * stream, GstBuffer ** buf)
3161 data = GST_BUFFER_DATA (*buf);
3162 size = GST_BUFFER_SIZE (*buf);
3164 if (size > 2 && data[0] == 0xff && (data[1] >> 4 == 0x0f)) {
3168 /* tss, ADTS data, remove codec_data
3169 * still assume it is at least parsed */
3170 new_caps = gst_caps_copy (stream->caps);
3171 s = gst_caps_get_structure (new_caps, 0);
3173 gst_structure_remove_field (s, "codec_data");
3174 gst_caps_replace (&stream->caps, new_caps);
3175 gst_pad_set_caps (stream->pad, new_caps);
3176 gst_buffer_set_caps (*buf, new_caps);
3177 GST_DEBUG_OBJECT (element, "ADTS AAC audio data; removing codec-data, "
3178 "new caps: %" GST_PTR_FORMAT, new_caps);
3179 gst_caps_unref (new_caps);
3182 /* disable subsequent checking */
3183 stream->postprocess_frame = NULL;
3188 static GstFlowReturn
3189 gst_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux,
3190 GstEbmlRead * ebml, guint64 cluster_time, guint64 cluster_offset,
3191 gboolean is_simpleblock)
3193 GstMatroskaTrackContext *stream = NULL;
3194 GstFlowReturn ret = GST_FLOW_OK;
3195 gboolean readblock = FALSE;
3197 guint64 block_duration = -1;
3198 GstBuffer *buf = NULL;
3199 gint stream_num = -1, n, laces = 0;
3201 gint *lace_size = NULL;
3204 gint64 referenceblock = 0;
3207 offset = gst_ebml_read_get_offset (ebml);
3209 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3210 if (!is_simpleblock) {
3211 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK) {
3215 id = GST_MATROSKA_ID_SIMPLEBLOCK;
3219 /* one block inside the group. Note, block parsing is one
3220 * of the harder things, so this code is a bit complicated.
3221 * See http://www.matroska.org/ for documentation. */
3222 case GST_MATROSKA_ID_SIMPLEBLOCK:
3223 case GST_MATROSKA_ID_BLOCK:
3229 gst_buffer_unref (buf);
3232 if ((ret = gst_ebml_read_buffer (ebml, &id, &buf)) != GST_FLOW_OK)
3235 data = GST_BUFFER_DATA (buf);
3236 size = GST_BUFFER_SIZE (buf);
3238 /* first byte(s): blocknum */
3239 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
3244 /* fetch stream from num */
3245 stream_num = gst_matroska_read_common_stream_from_num (&demux->common,
3247 if (G_UNLIKELY (size < 3)) {
3248 GST_WARNING_OBJECT (demux, "Invalid size %u", size);
3249 /* non-fatal, try next block(group) */
3252 } else if (G_UNLIKELY (stream_num < 0 ||
3253 stream_num >= demux->common.num_streams)) {
3254 /* let's not give up on a stray invalid track number */
3255 GST_WARNING_OBJECT (demux,
3256 "Invalid stream %d for track number %" G_GUINT64_FORMAT
3257 "; ignoring block", stream_num, num);
3261 stream = g_ptr_array_index (demux->common.src, stream_num);
3263 #ifdef MKV_DEMUX_MODIFICATION
3264 if (demux->common.segment.rate < 0.0) {
3265 if ((stream_num+1) == GST_MATROSKA_TRACK_TYPE_AUDIO) {
3266 /* found at least one audio block */
3267 demux->found_audioframe = TRUE;
3272 /* time (relative to cluster time) */
3273 time = ((gint16) GST_READ_UINT16_BE (data));
3276 flags = GST_READ_UINT8 (data);
3280 GST_LOG_OBJECT (demux, "time %" G_GUINT64_FORMAT ", flags %d", time,
3283 switch ((flags & 0x06) >> 1) {
3284 case 0x0: /* no lacing */
3286 lace_size = g_new (gint, 1);
3287 lace_size[0] = size;
3290 case 0x1: /* xiph lacing */
3291 case 0x2: /* fixed-size lacing */
3292 case 0x3: /* EBML lacing */
3294 goto invalid_lacing;
3295 laces = GST_READ_UINT8 (data) + 1;
3298 lace_size = g_new0 (gint, laces);
3300 switch ((flags & 0x06) >> 1) {
3301 case 0x1: /* xiph lacing */ {
3302 guint temp, total = 0;
3304 for (n = 0; ret == GST_FLOW_OK && n < laces - 1; n++) {
3307 goto invalid_lacing;
3308 temp = GST_READ_UINT8 (data);
3309 lace_size[n] += temp;
3315 total += lace_size[n];
3317 lace_size[n] = size - total;
3321 case 0x2: /* fixed-size lacing */
3322 for (n = 0; n < laces; n++)
3323 lace_size[n] = size / laces;
3326 case 0x3: /* EBML lacing */ {
3329 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
3333 total = lace_size[0] = num;
3334 for (n = 1; ret == GST_FLOW_OK && n < laces - 1; n++) {
3338 if ((r = gst_matroska_ebmlnum_sint (data, size, &snum)) < 0)
3342 lace_size[n] = lace_size[n - 1] + snum;
3343 total += lace_size[n];
3346 lace_size[n] = size - total;
3353 if (stream->send_xiph_headers) {
3354 ret = gst_matroska_demux_push_xiph_codec_priv_data (demux, stream);
3355 stream->send_xiph_headers = FALSE;
3358 if (stream->send_flac_headers) {
3359 ret = gst_matroska_demux_push_flac_codec_priv_data (demux, stream);
3360 stream->send_flac_headers = FALSE;
3363 if (stream->send_speex_headers) {
3364 ret = gst_matroska_demux_push_speex_codec_priv_data (demux, stream);
3365 stream->send_speex_headers = FALSE;
3368 if (stream->send_dvd_event) {
3369 gst_matroska_demux_push_dvd_clut_change_event (demux, stream);
3370 /* FIXME: should we send this event again after (flushing) seek ? */
3371 stream->send_dvd_event = FALSE;
3374 if (ret != GST_FLOW_OK)
3381 case GST_MATROSKA_ID_BLOCKDURATION:{
3382 ret = gst_ebml_read_uint (ebml, &id, &block_duration);
3383 GST_DEBUG_OBJECT (demux, "BlockDuration: %" G_GUINT64_FORMAT,
3388 case GST_MATROSKA_ID_REFERENCEBLOCK:{
3389 ret = gst_ebml_read_sint (ebml, &id, &referenceblock);
3390 GST_DEBUG_OBJECT (demux, "ReferenceBlock: %" G_GINT64_FORMAT,
3395 case GST_MATROSKA_ID_CODECSTATE:{
3397 guint64 data_len = 0;
3400 gst_ebml_read_binary (ebml, &id, &data,
3401 &data_len)) != GST_FLOW_OK)
3404 if (G_UNLIKELY (stream == NULL)) {
3405 GST_WARNING_OBJECT (demux,
3406 "Unexpected CodecState subelement - ignoring");
3410 g_free (stream->codec_state);
3411 stream->codec_state = data;
3412 stream->codec_state_size = data_len;
3414 /* Decode if necessary */
3415 if (stream->encodings && stream->encodings->len > 0
3416 && stream->codec_state && stream->codec_state_size > 0) {
3417 if (!gst_matroska_decode_data (stream->encodings,
3418 &stream->codec_state, &stream->codec_state_size,
3419 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
3420 GST_WARNING_OBJECT (demux, "Decoding codec state failed");
3424 GST_DEBUG_OBJECT (demux, "CodecState of %u bytes",
3425 stream->codec_state_size);
3430 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3434 case GST_MATROSKA_ID_BLOCKVIRTUAL:
3435 case GST_MATROSKA_ID_BLOCKADDITIONS:
3436 case GST_MATROSKA_ID_REFERENCEPRIORITY:
3437 case GST_MATROSKA_ID_REFERENCEVIRTUAL:
3438 case GST_MATROSKA_ID_SLICES:
3439 GST_DEBUG_OBJECT (demux,
3440 "Skipping BlockGroup subelement 0x%x - ignoring", id);
3441 ret = gst_ebml_read_skip (ebml);
3449 /* reading a number or so could have failed */
3450 if (ret != GST_FLOW_OK)
3453 if (ret == GST_FLOW_OK && readblock) {
3454 guint64 duration = 0;
3455 gint64 lace_time = 0;
3456 gboolean delta_unit;
3458 stream = g_ptr_array_index (demux->common.src, stream_num);
3460 if (cluster_time != GST_CLOCK_TIME_NONE) {
3461 /* FIXME: What to do with negative timestamps? Give timestamp 0 or -1?
3462 * Drop unless the lace contains timestamp 0? */
3463 if (time < 0 && (-time) > cluster_time) {
3466 if (stream->timecodescale == 1.0)
3467 lace_time = (cluster_time + time) * demux->common.time_scale;
3470 gst_util_guint64_to_gdouble ((cluster_time + time) *
3471 demux->common.time_scale) * stream->timecodescale;
3474 lace_time = GST_CLOCK_TIME_NONE;
3477 /* need to refresh segment info ASAP */
3478 if (GST_CLOCK_TIME_IS_VALID (lace_time) && demux->need_newsegment) {
3481 GST_DEBUG_OBJECT (demux,
3482 "generating segment starting at %" GST_TIME_FORMAT,
3483 GST_TIME_ARGS (lace_time));
3484 if (!GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
3485 demux->stream_start_time = lace_time;
3486 GST_DEBUG_OBJECT (demux,
3487 "Setting stream start time to %" GST_TIME_FORMAT,
3488 GST_TIME_ARGS (lace_time));
3490 clace_time = MAX (lace_time, demux->stream_start_time);
3491 gst_segment_set_newsegment (&demux->common.segment, FALSE,
3492 demux->common.segment.rate, GST_FORMAT_TIME, clace_time,
3493 GST_CLOCK_TIME_NONE, clace_time - demux->stream_start_time);
3494 /* now convey our segment notion downstream */
3495 gst_matroska_demux_send_event (demux, gst_event_new_new_segment (FALSE,
3496 demux->common.segment.rate, demux->common.segment.format,
3497 demux->common.segment.start, demux->common.segment.stop,
3498 demux->common.segment.start));
3499 demux->need_newsegment = FALSE;
3502 if (block_duration != -1) {
3503 if (stream->timecodescale == 1.0)
3504 duration = gst_util_uint64_scale (block_duration,
3505 demux->common.time_scale, 1);
3508 gst_util_gdouble_to_guint64 (gst_util_guint64_to_gdouble
3509 (gst_util_uint64_scale (block_duration, demux->common.time_scale,
3510 1)) * stream->timecodescale);
3511 } else if (stream->default_duration) {
3512 duration = stream->default_duration * laces;
3514 /* else duration is diff between timecode of this and next block */
3516 /* For SimpleBlock, look at the keyframe bit in flags. Otherwise,
3517 a ReferenceBlock implies that this is not a keyframe. In either
3518 case, it only makes sense for video streams. */
3519 delta_unit = stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
3520 ((is_simpleblock && !(flags & 0x80)) || referenceblock);
3522 if (delta_unit && stream->set_discont) {
3523 /* When doing seeks or such, we need to restart on key frames or
3524 * decoders might choke. */
3525 GST_DEBUG_OBJECT (demux, "skipping delta unit");
3529 for (n = 0; n < laces; n++) {
3531 #ifdef MKV_DEMUX_MODIFICATION
3532 gboolean skip_flag = FALSE;
3535 if (G_UNLIKELY (lace_size[n] > size)) {
3536 GST_WARNING_OBJECT (demux, "Invalid lace size");
3540 /* QoS for video track with an index. the assumption is that
3541 index entries point to keyframes, but if that is not true we
3542 will instad skip until the next keyframe. */
3543 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
3544 stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
3545 stream->index_table && demux->common.segment.rate > 0.0) {
3546 GstMatroskaTrackVideoContext *videocontext =
3547 (GstMatroskaTrackVideoContext *) stream;
3548 GstClockTime earliest_time;
3549 GstClockTime earliest_stream_time;
3551 GST_OBJECT_LOCK (demux);
3552 earliest_time = videocontext->earliest_time;
3553 GST_OBJECT_UNLOCK (demux);
3554 earliest_stream_time = gst_segment_to_position (&demux->common.segment,
3555 GST_FORMAT_TIME, earliest_time);
3557 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
3558 GST_CLOCK_TIME_IS_VALID (earliest_stream_time) &&
3559 lace_time <= earliest_stream_time) {
3560 /* find index entry (keyframe) <= earliest_stream_time */
3561 GstMatroskaIndex *entry =
3562 gst_util_array_binary_search (stream->index_table->data,
3563 stream->index_table->len, sizeof (GstMatroskaIndex),
3564 (GCompareDataFunc) gst_matroska_index_seek_find,
3565 GST_SEARCH_MODE_BEFORE, &earliest_stream_time, NULL);
3567 /* if that entry (keyframe) is after the current the current
3568 buffer, we can skip pushing (and thus decoding) all
3569 buffers until that keyframe. */
3570 if (entry && GST_CLOCK_TIME_IS_VALID (entry->time) &&
3571 entry->time > lace_time) {
3572 GST_LOG_OBJECT (demux, "Skipping lace before late keyframe");
3573 stream->set_discont = TRUE;
3579 sub = gst_buffer_create_sub (buf,
3580 GST_BUFFER_SIZE (buf) - size, lace_size[n]);
3581 GST_DEBUG_OBJECT (demux, "created subbuffer %p", sub);
3582 #ifdef MKV_DEMUX_MODIFICATION
3583 if(demux->index_table_created == FALSE) {
3584 demux->common.segment.duration = 0;
3589 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
3591 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
3593 if (stream->encodings != NULL && stream->encodings->len > 0)
3594 sub = gst_matroska_decode_buffer (stream, sub);
3597 GST_WARNING_OBJECT (demux, "Decoding buffer failed");
3601 GST_BUFFER_TIMESTAMP (sub) = lace_time;
3603 if (GST_CLOCK_TIME_IS_VALID (lace_time)) {
3604 GstClockTime last_stop_end;
3606 #ifndef MKV_DEMUX_MODIFICATION
3607 /* Check if this stream is after segment stop */
3608 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop) &&
3609 lace_time >= demux->common.segment.stop) {
3610 GST_DEBUG_OBJECT (demux,
3611 "Stream %d after segment stop %" GST_TIME_FORMAT, stream->index,
3612 GST_TIME_ARGS (demux->common.segment.stop));
3613 gst_buffer_unref (sub);
3616 if (offset >= stream->to_offset) {
3617 GST_DEBUG_OBJECT (demux, "Stream %d after playback section",
3619 gst_buffer_unref (sub);
3624 /* handle gaps, e.g. non-zero start-time, or an cue index entry
3625 * that landed us with timestamps not quite intended */
3626 GST_OBJECT_LOCK (demux);
3627 if (demux->max_gap_time &&
3628 #ifdef MKV_DEMUX_MODIFICATION
3629 GST_CLOCK_TIME_IS_VALID (/*demux->last_stop_end*/demux->common.segment.last_stop) &&
3630 demux->common.segment.rate > 0.0) {
3632 GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) &&
3633 demux->common.segment.rate > 0.0) {
3636 GstClockTimeDiff diff;
3637 GstEvent *event1, *event2;
3639 /* only send newsegments with increasing start times,
3640 * otherwise if these go back and forth downstream (sinks) increase
3641 * accumulated time and running_time */
3642 #ifdef MKV_DEMUX_MODIFICATION
3643 diff = GST_CLOCK_DIFF (/*demux->last_stop_end*/demux->common.segment.last_stop, lace_time);
3645 diff = GST_CLOCK_DIFF (demux->last_stop_end, lace_time);
3647 if (diff > 0 && diff > demux->max_gap_time
3648 && lace_time > demux->common.segment.start
3649 && (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop)
3650 || lace_time < demux->common.segment.stop)) {
3651 GST_DEBUG_OBJECT (demux,
3652 "Gap of %" G_GINT64_FORMAT " ns detected in"
3653 "stream %d (%" GST_TIME_FORMAT " -> %" GST_TIME_FORMAT "). "
3654 "Sending updated NEWSEGMENT events", diff,
3655 stream->index, GST_TIME_ARGS (stream->pos),
3656 GST_TIME_ARGS (lace_time));
3657 /* send newsegment events such that the gap is not accounted in
3658 * accum time, hence running_time */
3659 /* close ahead of gap */
3660 event1 = gst_event_new_new_segment (TRUE,
3661 demux->common.segment.rate, demux->common.segment.format,
3662 demux->last_stop_end, demux->last_stop_end,
3663 demux->last_stop_end);
3665 event2 = gst_event_new_new_segment (FALSE,
3666 demux->common.segment.rate,
3667 demux->common.segment.format, lace_time,
3668 demux->common.segment.stop, lace_time);
3669 GST_OBJECT_UNLOCK (demux);
3670 gst_matroska_demux_send_event (demux, event1);
3671 gst_matroska_demux_send_event (demux, event2);
3672 GST_OBJECT_LOCK (demux);
3673 /* align segment view with downstream,
3674 * prevents double-counting accum when closing segment */
3675 gst_segment_set_newsegment (&demux->common.segment, FALSE,
3676 demux->common.segment.rate, demux->common.segment.format,
3677 lace_time, demux->common.segment.stop, lace_time);
3678 demux->common.segment.last_stop = lace_time;
3682 if (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.last_stop)
3683 || demux->common.segment.last_stop < lace_time) {
3684 demux->common.segment.last_stop = lace_time;
3686 GST_OBJECT_UNLOCK (demux);
3688 last_stop_end = lace_time;
3690 GST_BUFFER_DURATION (sub) = duration / laces;
3691 last_stop_end += GST_BUFFER_DURATION (sub);
3694 if (!GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) ||
3695 demux->last_stop_end < last_stop_end)
3696 demux->last_stop_end = last_stop_end;
3698 GST_OBJECT_LOCK (demux);
3699 #ifdef MKV_DEMUX_MODIFICATION
3700 if ((demux->common.segment.duration == -1 ||
3701 demux->stream_start_time + demux->common.segment.duration <
3702 last_stop_end) && demux->index_table_created == TRUE) {
3704 if (demux->common.segment.duration == -1 ||
3705 demux->stream_start_time + demux->common.segment.duration <
3708 gst_segment_set_duration (&demux->common.segment, GST_FORMAT_TIME,
3709 last_stop_end - demux->stream_start_time);
3710 GST_OBJECT_UNLOCK (demux);
3711 if (!demux->invalid_duration) {
3712 gst_element_post_message (GST_ELEMENT_CAST (demux),
3713 gst_message_new_duration (GST_OBJECT_CAST (demux),
3714 GST_FORMAT_TIME, GST_CLOCK_TIME_NONE));
3715 demux->invalid_duration = TRUE;
3718 GST_OBJECT_UNLOCK (demux);
3722 stream->pos = lace_time;
3724 gst_matroska_demux_sync_streams (demux);
3726 if (stream->set_discont) {
3727 GST_DEBUG_OBJECT (demux, "marking DISCONT");
3728 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DISCONT);
3729 stream->set_discont = FALSE;
3732 /* reverse playback book-keeping */
3733 if (!GST_CLOCK_TIME_IS_VALID (stream->from_time))
3734 stream->from_time = lace_time;
3735 if (stream->from_offset == -1)
3736 stream->from_offset = offset;
3738 #ifdef MKV_DEMUX_MODIFICATION
3739 if ((demux->common.segment.rate < 0.0) && ((stream_num+1) == GST_MATROSKA_TRACK_TYPE_VIDEO)) {
3740 if (GST_BUFFER_FLAG_IS_SET (sub, GST_BUFFER_FLAG_DELTA_UNIT)) {
3741 GST_DEBUG_OBJECT (demux, "skipping delta unit");
3742 gst_buffer_unref (sub);
3745 /* found key frame*/
3746 demux->found_videokeyframe = TRUE;
3749 demux->current_ts = GST_BUFFER_TIMESTAMP (sub);
3752 GST_DEBUG_OBJECT (demux,
3753 "Pushing lace %d, data of size %d for stream %d, time=%"
3754 GST_TIME_FORMAT " and duration=%" GST_TIME_FORMAT, n,
3755 GST_BUFFER_SIZE (sub), stream_num,
3756 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (sub)),
3757 GST_TIME_ARGS (GST_BUFFER_DURATION (sub)));
3759 if (demux->common.element_index) {
3760 if (stream->index_writer_id == -1)
3761 gst_index_get_writer_id (demux->common.element_index,
3762 GST_OBJECT (stream->pad), &stream->index_writer_id);
3764 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
3765 G_GUINT64_FORMAT " for writer id %d",
3766 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (sub)), cluster_offset,
3767 stream->index_writer_id);
3768 gst_index_add_association (demux->common.element_index,
3769 stream->index_writer_id, GST_BUFFER_FLAG_IS_SET (sub,
3770 GST_BUFFER_FLAG_DELTA_UNIT) ? 0 : GST_ASSOCIATION_FLAG_KEY_UNIT,
3771 GST_FORMAT_TIME, GST_BUFFER_TIMESTAMP (sub), GST_FORMAT_BYTES,
3772 cluster_offset, NULL);
3775 gst_buffer_set_caps (sub, GST_PAD_CAPS (stream->pad));
3777 /* Postprocess the buffers depending on the codec used */
3778 if (stream->postprocess_frame) {
3779 GST_LOG_OBJECT (demux, "running post process");
3780 ret = stream->postprocess_frame (GST_ELEMENT (demux), stream, &sub);
3783 #ifdef MKV_DEMUX_MODIFICATION
3784 if (demux->video && demux->common.segment.rate > 1.0
3785 && stream->type <= GST_MATROSKA_TRACK_TYPE_AUDIO) {
3787 if(GST_BUFFER_TIMESTAMP(sub) >= demux->common.segment.start) {
3788 GST_BUFFER_FLAG_UNSET(sub, GST_BUFFER_FLAG_DELTA_UNIT);
3789 GST_INFO("Entering into forward Trickplay");
3790 ret = gst_matroska_demux_forward_trickplay (demux, stream, sub, &skip_flag);
3792 if (skip_flag == FALSE) {
3793 GST_INFO("buffer pushed %"GST_TIME_FORMAT, GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(sub)));
3794 ret = gst_pad_push (stream->pad, sub);
3796 GST_INFO("Unreffing the buffer %"GST_TIME_FORMAT, GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(sub)));
3797 gst_buffer_unref (sub);
3799 } else if (demux->common.segment.rate < 0.0) {
3800 ret = gst_matroska_demux_backward_trickplay (demux, stream, sub);
3804 /* At this point, we have a sub-buffer pointing at data within a larger
3805 buffer. This data might not be aligned with anything. If the data is
3806 raw samples though, we want it aligned to the raw type (eg, 4 bytes
3807 for 32 bit samples, etc), or bad things will happen downstream as
3808 elements typically assume minimal alignment.
3809 Therefore, create an aligned copy if necessary. */
3810 g_assert (stream->alignment <= G_MEM_ALIGN);
3811 if (((guintptr) GST_BUFFER_DATA (sub)) & (stream->alignment - 1)) {
3812 GstBuffer *buffer = gst_buffer_new_and_alloc (GST_BUFFER_SIZE (sub));
3813 memcpy (GST_BUFFER_DATA (buffer), GST_BUFFER_DATA (sub),
3814 GST_BUFFER_SIZE (sub));
3815 gst_buffer_copy_metadata (buffer, sub, GST_BUFFER_COPY_ALL);
3816 GST_DEBUG_OBJECT (demux, "We want output aligned on %d, reallocated",
3818 gst_buffer_unref (sub);
3821 #ifdef MKV_DEMUX_MODIFICATION
3822 if(demux->index_table_created == FALSE) {
3823 // flag checking sufficient for simple block and delta unit for Block group
3824 if(flags == 128 || (!delta_unit && stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO)) {
3825 GST_INFO("Keyframe Found");
3827 //Information required for index table creation
3828 GstMatroskaIndex *idx = NULL;
3829 idx = (GstMatroskaIndex*)malloc(sizeof(GstMatroskaIndex));
3831 GST_INFO("Unable to create memory");
3832 ret = GST_FLOW_UNEXPECTED;
3835 idx->pos = (cluster_offset - demux->initial_offset);
3837 idx->time = GST_BUFFER_TIMESTAMP(sub);
3840 // Creating new/Over-Writing index table
3841 if(!demux->index_table_array_creation) {
3842 GST_INFO("Keyframe time stamp is %"GST_TIME_FORMAT"pos %"G_GUINT64_FORMAT, GST_TIME_ARGS(idx->time), idx->pos);
3843 GST_INFO("Index table creation first time");
3844 demux->common.index = NULL;//g_array_unref(demux->common.index);
3845 demux->common.index = g_array_new(FALSE, FALSE, sizeof(GstMatroskaIndex));
3846 g_array_append_val(demux->common.index, *idx);
3847 GST_INFO("size of the index is %d",demux->common.index->len);
3848 demux->index_table_array_creation = TRUE;
3850 GST_INFO("Adding Keyframe info to index table");
3851 GST_INFO("Keyframe time stamp is %"GST_TIME_FORMAT"pos %"G_GUINT64_FORMAT, GST_TIME_ARGS(idx->time), idx->pos);
3852 g_array_append_val(demux->common.index, *idx);
3853 GST_INFO("size of the index is %d",demux->common.index->len);
3856 //demux->common.segment.duration = (GST_BUFFER_TIMESTAMP(sub) + GST_BUFFER_DURATION (sub));
3857 demux->duration = GST_BUFFER_TIMESTAMP(sub) + GST_BUFFER_DURATION (sub);
3858 GST_INFO("duration is in capturing not setting%"GST_TIME_FORMAT, GST_TIME_ARGS(demux->duration));
3859 GST_INFO("duration in segment duration still not set%"GST_TIME_FORMAT, GST_TIME_ARGS(demux->common.segment.duration));
3862 ret = gst_pad_push (stream->pad, sub);
3865 ret = gst_pad_push (stream->pad, sub);
3869 if (demux->common.segment.rate < 0) {
3870 if (lace_time > demux->common.segment.stop
3871 && ret == GST_FLOW_UNEXPECTED) {
3872 /* In reverse playback we can get a GST_FLOW_UNEXPECTED when
3873 * we are at the end of the segment, so we just need to jump
3874 * back to the previous section. */
3875 GST_DEBUG_OBJECT (demux, "downstream has reached end of segment");
3880 ret = gst_matroska_demux_combine_flows (demux, stream, ret);
3883 size -= lace_size[n];
3884 if (lace_time != GST_CLOCK_TIME_NONE && duration)
3885 lace_time += duration / laces;
3887 lace_time = GST_CLOCK_TIME_NONE;
3893 gst_buffer_unref (buf);
3904 ret = gst_matroska_demux_combine_flows (demux, stream, ret);
3909 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Invalid lacing size"));
3910 /* non-fatal, try next block(group) */
3916 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Data error"));
3917 /* non-fatal, try next block(group) */
3923 /* return FALSE if block(group) should be skipped (due to a seek) */
3924 static inline gboolean
3925 gst_matroska_demux_seek_block (GstMatroskaDemux * demux)
3927 if (G_UNLIKELY (demux->seek_block)) {
3928 if (!(--demux->seek_block)) {
3931 GST_LOG_OBJECT (demux, "should skip block due to seek");
3939 static GstFlowReturn
3940 gst_matroska_demux_parse_contents_seekentry (GstMatroskaDemux * demux,
3944 guint64 seek_pos = (guint64) - 1;
3945 guint32 seek_id = 0;
3948 DEBUG_ELEMENT_START (demux, ebml, "Seek");
3950 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3951 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
3955 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3956 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3960 case GST_MATROSKA_ID_SEEKID:
3964 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
3967 GST_DEBUG_OBJECT (demux, "SeekID: %" G_GUINT64_FORMAT, t);
3972 case GST_MATROSKA_ID_SEEKPOSITION:
3976 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
3979 if (t > G_MAXINT64) {
3980 GST_WARNING_OBJECT (demux,
3981 "Too large SeekPosition %" G_GUINT64_FORMAT, t);
3985 GST_DEBUG_OBJECT (demux, "SeekPosition: %" G_GUINT64_FORMAT, t);
3991 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3997 if (ret != GST_FLOW_OK && ret != GST_FLOW_UNEXPECTED)
4000 if (!seek_id || seek_pos == (guint64) - 1) {
4001 GST_WARNING_OBJECT (demux, "Incomplete seekhead entry (0x%x/%"
4002 G_GUINT64_FORMAT ")", seek_id, seek_pos);
4007 case GST_MATROSKA_ID_SEEKHEAD:
4010 case GST_MATROSKA_ID_CUES:
4011 case GST_MATROSKA_ID_TAGS:
4012 case GST_MATROSKA_ID_TRACKS:
4013 case GST_MATROSKA_ID_SEGMENTINFO:
4014 case GST_MATROSKA_ID_ATTACHMENTS:
4015 case GST_MATROSKA_ID_CHAPTERS:
4017 guint64 before_pos, length;
4021 length = gst_matroska_read_common_get_length (&demux->common);
4022 before_pos = demux->common.offset;
4024 if (length == (guint64) - 1) {
4025 GST_DEBUG_OBJECT (demux, "no upstream length, skipping SeakHead entry");
4029 /* check for validity */
4030 if (seek_pos + demux->common.ebml_segment_start + 12 >= length) {
4031 GST_WARNING_OBJECT (demux,
4032 "SeekHead reference lies outside file!" " (%"
4033 G_GUINT64_FORMAT "+%" G_GUINT64_FORMAT "+12 >= %"
4034 G_GUINT64_FORMAT ")", seek_pos, demux->common.ebml_segment_start,
4036 #ifdef MKV_DEMUX_MODIFICATION
4037 demux->seek_head_cluster_info_absent = TRUE;
4038 demux->seek_head_cue_info_absent = TRUE;
4039 demux->index_table_created = FALSE;
4040 GST_INFO("Need to create index table this might take time");
4045 /* only pick up index location when streaming */
4046 if (demux->streaming) {
4047 if (seek_id == GST_MATROSKA_ID_CUES) {
4048 demux->index_offset = seek_pos + demux->common.ebml_segment_start;
4049 GST_DEBUG_OBJECT (demux, "Cues located at offset %" G_GUINT64_FORMAT,
4050 demux->index_offset);
4056 demux->common.offset = seek_pos + demux->common.ebml_segment_start;
4059 if ((ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4060 GST_ELEMENT_CAST (demux), &id, &length, &needed)) !=
4064 if (id != seek_id) {
4065 GST_WARNING_OBJECT (demux,
4066 "We looked for ID=0x%x but got ID=0x%x (pos=%" G_GUINT64_FORMAT ")",
4067 seek_id, id, seek_pos + demux->common.ebml_segment_start);
4070 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4075 demux->common.offset = before_pos;
4079 case GST_MATROSKA_ID_CLUSTER:
4081 guint64 pos = seek_pos + demux->common.ebml_segment_start;
4083 GST_LOG_OBJECT (demux, "Cluster position");
4084 if (G_UNLIKELY (!demux->clusters))
4085 demux->clusters = g_array_sized_new (TRUE, TRUE, sizeof (guint64), 100);
4086 g_array_append_val (demux->clusters, pos);
4091 GST_DEBUG_OBJECT (demux, "Ignoring Seek entry for ID=0x%x", seek_id);
4094 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
4099 static GstFlowReturn
4100 gst_matroska_demux_parse_contents (GstMatroskaDemux * demux, GstEbmlRead * ebml)
4102 GstFlowReturn ret = GST_FLOW_OK;
4105 DEBUG_ELEMENT_START (demux, ebml, "SeekHead");
4107 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
4108 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
4112 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
4113 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
4117 case GST_MATROSKA_ID_SEEKENTRY:
4119 ret = gst_matroska_demux_parse_contents_seekentry (demux, ebml);
4120 /* Ignore EOS and errors here */
4121 if (ret != GST_FLOW_OK) {
4122 GST_DEBUG_OBJECT (demux, "Ignoring %s", gst_flow_get_name (ret));
4129 ret = gst_matroska_read_common_parse_skip (&demux->common,
4130 ebml, "SeekHead", id);
4135 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
4137 /* Sort clusters by position for easier searching */
4138 if (demux->clusters)
4139 g_array_sort (demux->clusters, (GCompareFunc) gst_matroska_cluster_compare);
4144 #define GST_FLOW_OVERFLOW GST_FLOW_CUSTOM_ERROR
4146 #define MAX_BLOCK_SIZE (15 * 1024 * 1024)
4148 static inline GstFlowReturn
4149 gst_matroska_demux_check_read_size (GstMatroskaDemux * demux, guint64 bytes)
4151 if (G_UNLIKELY (bytes > MAX_BLOCK_SIZE)) {
4152 /* only a few blocks are expected/allowed to be large,
4153 * and will be recursed into, whereas others will be read and must fit */
4154 if (demux->streaming) {
4155 /* fatal in streaming case, as we can't step over easily */
4156 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4157 ("reading large block of size %" G_GUINT64_FORMAT " not supported; "
4158 "file might be corrupt.", bytes));
4159 return GST_FLOW_ERROR;
4161 /* indicate higher level to quietly give up */
4162 GST_DEBUG_OBJECT (demux,
4163 "too large block of size %" G_GUINT64_FORMAT, bytes);
4164 return GST_FLOW_ERROR;
4171 /* returns TRUE if we truely are in error state, and should give up */
4172 static inline gboolean
4173 gst_matroska_demux_check_parse_error (GstMatroskaDemux * demux)
4175 if (!demux->streaming && demux->next_cluster_offset > 0) {
4176 /* just repositioning to where next cluster should be and try from there */
4177 GST_WARNING_OBJECT (demux, "parse error, trying next cluster expected at %"
4178 G_GUINT64_FORMAT, demux->next_cluster_offset);
4179 demux->common.offset = demux->next_cluster_offset;
4180 demux->next_cluster_offset = 0;
4185 /* sigh, one last attempt above and beyond call of duty ...;
4186 * search for cluster mark following current pos */
4187 pos = demux->common.offset;
4188 GST_WARNING_OBJECT (demux, "parse error, looking for next cluster");
4189 if (gst_matroska_demux_search_cluster (demux, &pos) != GST_FLOW_OK) {
4190 /* did not work, give up */
4193 GST_DEBUG_OBJECT (demux, "... found at %" G_GUINT64_FORMAT, pos);
4194 /* try that position */
4195 demux->common.offset = pos;
4201 static inline GstFlowReturn
4202 gst_matroska_demux_flush (GstMatroskaDemux * demux, guint flush)
4204 GST_LOG_OBJECT (demux, "skipping %d bytes", flush);
4205 demux->common.offset += flush;
4206 if (demux->streaming) {
4209 /* hard to skip large blocks when streaming */
4210 ret = gst_matroska_demux_check_read_size (demux, flush);
4211 if (ret != GST_FLOW_OK)
4213 if (flush <= gst_adapter_available (demux->common.adapter))
4214 gst_adapter_flush (demux->common.adapter, flush);
4216 return GST_FLOW_UNEXPECTED;
4221 /* initializes @ebml with @bytes from input stream at current offset.
4222 * Returns UNEXPECTED if insufficient available,
4223 * ERROR if too much was attempted to read. */
4224 static inline GstFlowReturn
4225 gst_matroska_demux_take (GstMatroskaDemux * demux, guint64 bytes,
4228 GstBuffer *buffer = NULL;
4229 GstFlowReturn ret = GST_FLOW_OK;
4231 GST_LOG_OBJECT (demux, "taking %" G_GUINT64_FORMAT " bytes for parsing",
4233 ret = gst_matroska_demux_check_read_size (demux, bytes);
4234 if (G_UNLIKELY (ret != GST_FLOW_OK)) {
4235 if (!demux->streaming) {
4236 /* in pull mode, we can skip */
4237 if ((ret = gst_matroska_demux_flush (demux, bytes)) == GST_FLOW_OK)
4238 ret = GST_FLOW_OVERFLOW;
4240 /* otherwise fatal */
4241 ret = GST_FLOW_ERROR;
4245 if (demux->streaming) {
4246 if (gst_adapter_available (demux->common.adapter) >= bytes)
4247 buffer = gst_adapter_take_buffer (demux->common.adapter, bytes);
4249 ret = GST_FLOW_UNEXPECTED;
4251 ret = gst_matroska_read_common_peek_bytes (&demux->common,
4252 demux->common.offset, bytes, &buffer, NULL);
4253 if (G_LIKELY (buffer)) {
4254 gst_ebml_read_init (ebml, GST_ELEMENT_CAST (demux), buffer,
4255 demux->common.offset);
4256 demux->common.offset += bytes;
4263 gst_matroska_demux_check_seekability (GstMatroskaDemux * demux)
4266 gboolean seekable = FALSE;
4267 gint64 start = -1, stop = -1;
4269 query = gst_query_new_seeking (GST_FORMAT_BYTES);
4270 if (!gst_pad_peer_query (demux->common.sinkpad, query)) {
4271 GST_DEBUG_OBJECT (demux, "seeking query failed");
4275 gst_query_parse_seeking (query, NULL, &seekable, &start, &stop);
4277 /* try harder to query upstream size if we didn't get it the first time */
4278 if (seekable && stop == -1) {
4279 GstFormat fmt = GST_FORMAT_BYTES;
4281 GST_DEBUG_OBJECT (demux, "doing duration query to fix up unset stop");
4282 gst_pad_query_peer_duration (demux->common.sinkpad, &fmt, &stop);
4285 /* if upstream doesn't know the size, it's likely that it's not seekable in
4286 * practice even if it technically may be seekable */
4287 if (seekable && (start != 0 || stop <= start)) {
4288 GST_DEBUG_OBJECT (demux, "seekable but unknown start/stop -> disable");
4293 GST_INFO_OBJECT (demux, "seekable: %d (%" G_GUINT64_FORMAT " - %"
4294 G_GUINT64_FORMAT ")", seekable, start, stop);
4295 demux->seekable = seekable;
4297 gst_query_unref (query);
4300 static GstFlowReturn
4301 gst_matroska_demux_find_tracks (GstMatroskaDemux * demux)
4307 GstFlowReturn ret = GST_FLOW_OK;
4309 GST_WARNING_OBJECT (demux,
4310 "Found Cluster element before Tracks, searching Tracks");
4313 before_pos = demux->common.offset;
4315 /* Search Tracks element */
4317 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4318 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4319 if (ret != GST_FLOW_OK)
4322 if (id != GST_MATROSKA_ID_TRACKS) {
4323 /* we may be skipping large cluster here, so forego size check etc */
4324 /* ... but we can't skip undefined size; force error */
4325 if (length == G_MAXUINT64) {
4326 ret = gst_matroska_demux_check_read_size (demux, length);
4329 demux->common.offset += needed;
4330 demux->common.offset += length;
4335 /* will lead to track parsing ... */
4336 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4341 demux->common.offset = before_pos;
4346 #define GST_READ_CHECK(stmt) \
4348 if (G_UNLIKELY ((ret = (stmt)) != GST_FLOW_OK)) { \
4349 if (ret == GST_FLOW_OVERFLOW) { \
4350 ret = GST_FLOW_OK; \
4356 static GstFlowReturn
4357 gst_matroska_demux_parse_id (GstMatroskaDemux * demux, guint32 id,
4358 guint64 length, guint needed)
4360 GstEbmlRead ebml = { 0, };
4361 GstFlowReturn ret = GST_FLOW_OK;
4364 GST_LOG_OBJECT (demux, "Parsing Element id 0x%x, "
4365 "size %" G_GUINT64_FORMAT ", prefix %d", id, length, needed);
4367 /* if we plan to read and parse this element, we need prefix (id + length)
4368 * and the contents */
4369 /* mind about overflow wrap-around when dealing with undefined size */
4371 if (G_LIKELY (length != G_MAXUINT64))
4374 switch (demux->common.state) {
4375 case GST_MATROSKA_READ_STATE_START:
4377 case GST_EBML_ID_HEADER:
4378 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4379 ret = gst_matroska_read_common_parse_header (&demux->common, &ebml);
4380 if (ret != GST_FLOW_OK)
4382 demux->common.state = GST_MATROSKA_READ_STATE_SEGMENT;
4383 gst_matroska_demux_check_seekability (demux);
4386 goto invalid_header;
4390 case GST_MATROSKA_READ_STATE_SEGMENT:
4392 case GST_MATROSKA_ID_SEGMENT:
4393 /* eat segment prefix */
4394 GST_READ_CHECK (gst_matroska_demux_flush (demux, needed));
4395 GST_DEBUG_OBJECT (demux,
4396 "Found Segment start at offset %" G_GUINT64_FORMAT,
4397 demux->common.offset);
4398 #ifdef MKV_DEMUX_MODIFICATION
4399 demux->initial_offset = demux->common.offset;
4400 GST_INFO("Initial offset storing is %u", demux->initial_offset);
4402 /* seeks are from the beginning of the segment,
4403 * after the segment ID/length */
4404 demux->common.ebml_segment_start = demux->common.offset;
4405 demux->common.state = GST_MATROSKA_READ_STATE_HEADER;
4408 GST_WARNING_OBJECT (demux,
4409 "Expected a Segment ID (0x%x), but received 0x%x!",
4410 GST_MATROSKA_ID_SEGMENT, id);
4411 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4415 case GST_MATROSKA_READ_STATE_SCANNING:
4416 if (id != GST_MATROSKA_ID_CLUSTER &&
4417 id != GST_MATROSKA_ID_CLUSTERTIMECODE)
4420 case GST_MATROSKA_READ_STATE_HEADER:
4421 case GST_MATROSKA_READ_STATE_DATA:
4422 case GST_MATROSKA_READ_STATE_SEEK:
4424 case GST_MATROSKA_ID_SEGMENTINFO:
4425 if (!demux->common.segmentinfo_parsed) {
4426 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4427 ret = gst_matroska_read_common_parse_info (&demux->common,
4428 GST_ELEMENT_CAST (demux), &ebml);
4429 #ifdef MKV_DEMUX_MODIFICATION
4430 demux->duration = demux->common.segment.duration; /* need to check */
4433 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4436 case GST_MATROSKA_ID_TRACKS:
4437 if (!demux->tracks_parsed) {
4438 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4439 ret = gst_matroska_demux_parse_tracks (demux, &ebml);
4441 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4444 case GST_MATROSKA_ID_CLUSTER:
4445 if (G_UNLIKELY (!demux->tracks_parsed)) {
4446 if (demux->streaming) {
4447 GST_DEBUG_OBJECT (demux, "Cluster before Track");
4448 goto not_streamable;
4450 ret = gst_matroska_demux_find_tracks (demux);
4451 if (!demux->tracks_parsed)
4455 if (G_UNLIKELY (demux->common.state
4456 == GST_MATROSKA_READ_STATE_HEADER)) {
4457 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
4458 demux->first_cluster_offset = demux->common.offset;
4459 GST_DEBUG_OBJECT (demux, "signaling no more pads");
4460 gst_element_no_more_pads (GST_ELEMENT (demux));
4461 /* send initial newsegment - we wait till we know the first
4462 incoming timestamp, so we can properly set the start of
4464 demux->need_newsegment = TRUE;
4466 demux->cluster_time = GST_CLOCK_TIME_NONE;
4467 demux->cluster_offset = demux->common.offset;
4468 if (G_UNLIKELY (!demux->seek_first && demux->seek_block)) {
4469 GST_DEBUG_OBJECT (demux, "seek target block %" G_GUINT64_FORMAT
4470 " not found in Cluster, trying next Cluster's first block instead",
4472 demux->seek_block = 0;
4474 demux->seek_first = FALSE;
4475 /* record next cluster for recovery */
4476 if (read != G_MAXUINT64)
4477 demux->next_cluster_offset = demux->cluster_offset + read;
4478 /* eat cluster prefix */
4479 gst_matroska_demux_flush (demux, needed);
4481 case GST_MATROSKA_ID_CLUSTERTIMECODE:
4485 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4486 if ((ret = gst_ebml_read_uint (&ebml, &id, &num)) != GST_FLOW_OK)
4488 GST_DEBUG_OBJECT (demux, "ClusterTimeCode: %" G_GUINT64_FORMAT, num);
4489 demux->cluster_time = num;
4490 if (demux->common.element_index) {
4491 if (demux->common.element_index_writer_id == -1)
4492 gst_index_get_writer_id (demux->common.element_index,
4493 GST_OBJECT (demux), &demux->common.element_index_writer_id);
4494 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
4495 G_GUINT64_FORMAT " for writer id %d",
4496 GST_TIME_ARGS (demux->cluster_time), demux->cluster_offset,
4497 demux->common.element_index_writer_id);
4498 gst_index_add_association (demux->common.element_index,
4499 demux->common.element_index_writer_id,
4500 GST_ASSOCIATION_FLAG_KEY_UNIT,
4501 GST_FORMAT_TIME, demux->cluster_time,
4502 GST_FORMAT_BYTES, demux->cluster_offset, NULL);
4506 case GST_MATROSKA_ID_BLOCKGROUP:
4507 if (!gst_matroska_demux_seek_block (demux))
4509 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4510 DEBUG_ELEMENT_START (demux, &ebml, "BlockGroup");
4511 if ((ret = gst_ebml_read_master (&ebml, &id)) == GST_FLOW_OK) {
4512 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4513 &ebml, demux->cluster_time, demux->cluster_offset, FALSE);
4516 #ifdef MKV_DEMUX_MODIFICATION
4517 if ((demux->common.segment.rate < 0.0) && (demux->found_videokeyframe == TRUE)
4518 && (demux->found_audioframe == TRUE) && (demux->current_ts >= demux->next_keyframe_ts) ) {
4519 /* we displayed at least one one audio block and one video key frame
4520 Now, goto previous cluster */
4523 guint64 duration = 0;
4524 GstClockTime time_position = 0;
4525 GstMatroskaIndex *entry = NULL;
4528 demux->next_keyframe_ts = demux->prev_keyframe_ts;
4529 GST_INFO("next_keyframe_ts is %"GST_TIME_FORMAT, GST_TIME_ARGS(demux->next_keyframe_ts));
4530 demux->video_keyframe_pushed = FALSE;
4531 for (i = 0; i < demux->common.src->len; i++) {
4532 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
4533 if (stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
4534 GST_DEBUG ("video track duration = %"G_GUINT64_FORMAT"position = %"GST_TIME_FORMAT"\n",
4535 stream->default_duration, GST_TIME_ARGS(stream->pos));
4536 duration = stream->default_duration;
4537 time_position = stream->pos;
4541 if((time_position - (minusone *demux->common.segment.rate)*((double)duration/1000000000))> 0) {
4542 time_position -= (minusone *demux->common.segment.rate)*((double)duration/1000000000);
4547 for (i = 0; i < demux->common.src->len; i++) {
4548 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
4551 GST_OBJECT_LOCK (demux);
4552 if (stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
4553 if ((entry = gst_matroska_read_common_do_index_seek (&demux->common, stream, time_position, NULL, NULL)) == NULL) {
4554 GST_DEBUG_OBJECT (demux, "No matching seek entry in index");
4556 GST_DEBUG_OBJECT (demux, "pos = %"G_GUINT64_FORMAT", track = %d, block = %d, time = %"GST_TIME_FORMAT"\n",
4557 entry->pos, entry->track, entry->block, GST_TIME_ARGS(entry->time));
4559 offset = entry->pos + demux->common.ebml_segment_start;
4560 if (offset >= gst_matroska_read_common_get_length(&demux->common)) {
4561 GST_INFO_OBJECT (demux, " Seek failed");
4564 demux->common.offset = offset;
4568 stream->set_discont = TRUE;
4569 stream->last_flow = GST_FLOW_OK;
4570 if (stream->pos > 0.0) {
4571 stream->eos = FALSE;
4573 if(demux->is_eos_blockgroup == FALSE) {
4574 demux->is_eos_blockgroup = TRUE;
4577 GST_INFO_OBJECT (demux, "Reached EOS.....");
4580 demux->common.segment.last_stop = time;
4582 GST_OBJECT_UNLOCK (demux);
4585 if (time == 0.0 && demux->is_eos_blockgroup == TRUE && demux->is_eos_simpleblock == TRUE) {
4586 gst_segment_init (&demux->common.segment, GST_FORMAT_TIME);
4587 gst_segment_set_duration (&demux->common.segment, GST_FORMAT_TIME, demux->duration);
4589 /* send new_segment event with start =0 and stop = duration */
4590 demux->new_segment = gst_event_new_new_segment_full (TRUE,
4591 demux->common.segment.rate, demux->common.segment.applied_rate, demux->common.segment.format,
4592 demux->common.segment.start, demux->common.segment.stop, demux->common.segment.time);
4595 demux->found_videokeyframe = FALSE;
4596 demux->found_audioframe = FALSE;
4597 demux->prev_keyframe_ts = time;
4598 GST_INFO("prev_keyframe in blockgroup is %"GST_TIME_FORMAT,GST_TIME_ARGS(demux->prev_keyframe_ts));
4603 DEBUG_ELEMENT_STOP (demux, &ebml, "BlockGroup", ret);
4605 case GST_MATROSKA_ID_SIMPLEBLOCK:
4606 if (!gst_matroska_demux_seek_block (demux))
4608 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4609 DEBUG_ELEMENT_START (demux, &ebml, "SimpleBlock");
4610 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4611 &ebml, demux->cluster_time, demux->cluster_offset, TRUE);
4613 #ifdef MKV_DEMUX_MODIFICATION
4614 if ((demux->common.segment.rate < 0.0) && (demux->found_videokeyframe == TRUE) && (demux->found_audioframe == TRUE)
4615 && (demux->current_ts >= demux->next_keyframe_ts) ) {
4616 /* we displayed at least one one audio block and one video key frame
4617 Now, goto previous cluster */
4620 guint64 duration = 0;
4621 GstClockTime time_position=0;
4622 GstMatroskaIndex *entry = NULL;
4624 demux->next_keyframe_ts = demux->prev_keyframe_ts;
4625 GST_INFO("next_keyframe_ts is %"GST_TIME_FORMAT, GST_TIME_ARGS(demux->next_keyframe_ts));
4626 demux->video_keyframe_pushed = FALSE;
4627 for (i = 0; i < demux->common.src->len; i++) {
4628 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
4629 if (stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
4630 GST_DEBUG ("video track duration = %"G_GUINT64_FORMAT"position = %"GST_TIME_FORMAT"\n",
4631 stream->default_duration, GST_TIME_ARGS(stream->pos));
4632 duration = stream->default_duration;
4633 time_position = stream->pos;
4637 if((time_position - (minusone *demux->common.segment.rate)*((double)duration/1000000000))> 0) {
4638 time_position -= (minusone *demux->common.segment.rate)*((double)duration/1000000000);
4643 for (i = 0; i < demux->common.src->len; i++) {
4644 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
4647 GST_OBJECT_LOCK (demux);
4648 if (stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
4649 if ((entry = gst_matroska_read_common_do_index_seek (&demux->common, stream, time_position, NULL, NULL)) == NULL) {
4650 GST_DEBUG_OBJECT (demux, "No matching seek entry in index");
4653 GST_DEBUG_OBJECT (demux, "pos = %"G_GUINT64_FORMAT", track = %d, block = %d, time = %"GST_TIME_FORMAT"\n",
4654 entry->pos, entry->track, entry->block, GST_TIME_ARGS(entry->time));
4656 /* seek (relative to matroska segment) */
4658 offset = entry->pos + demux->common.ebml_segment_start;
4659 if (offset >= gst_matroska_read_common_get_length(&demux->common)) {
4660 GST_INFO_OBJECT (demux, " Seek failed");
4661 GST_OBJECT_UNLOCK (demux);
4664 demux->common.offset = offset;
4667 stream->pos = entry->time;
4668 stream->set_discont = TRUE;
4669 stream->last_flow = GST_FLOW_OK;
4670 if (stream->pos > 0.0) {
4671 stream->eos = FALSE;
4673 if(demux->is_eos_simpleblock == FALSE) {
4674 demux->is_eos_simpleblock = TRUE;
4677 GST_INFO_OBJECT (demux, "Reached EOS.....");
4680 demux->common.segment.last_stop = entry->time;
4682 GST_OBJECT_UNLOCK (demux);
4685 if (entry->time == 0.0 && demux->is_eos_simpleblock == TRUE && demux->is_eos_blockgroup == TRUE) {
4686 gst_segment_init (&demux->common.segment, GST_FORMAT_TIME);
4687 gst_segment_set_duration (&demux->common.segment, GST_FORMAT_TIME, demux->duration);
4689 /* send new_segment event with start =0 and stop = duration */
4690 demux->new_segment = gst_event_new_new_segment_full (TRUE,
4691 demux->common.segment.rate, demux->common.segment.applied_rate, demux->common.segment.format,
4692 demux->common.segment.start, demux->common.segment.stop, demux->common.segment.time);
4695 demux->found_videokeyframe = FALSE;
4696 demux->found_audioframe = FALSE;
4697 demux->prev_keyframe_ts = entry->time;
4698 GST_INFO("prev_keyframe in simpleblock is %"GST_TIME_FORMAT,GST_TIME_ARGS(demux->prev_keyframe_ts));
4703 DEBUG_ELEMENT_STOP (demux, &ebml, "SimpleBlock", ret);
4705 case GST_MATROSKA_ID_ATTACHMENTS:
4706 if (!demux->common.attachments_parsed) {
4707 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4708 ret = gst_matroska_read_common_parse_attachments (&demux->common,
4709 GST_ELEMENT_CAST (demux), &ebml);
4711 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4714 case GST_MATROSKA_ID_TAGS:
4715 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4716 ret = gst_matroska_read_common_parse_metadata (&demux->common,
4717 GST_ELEMENT_CAST (demux), &ebml);
4719 case GST_MATROSKA_ID_CHAPTERS:
4720 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4721 ret = gst_matroska_read_common_parse_chapters (&demux->common, &ebml);
4723 case GST_MATROSKA_ID_SEEKHEAD:
4724 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4725 ret = gst_matroska_demux_parse_contents (demux, &ebml);
4727 case GST_MATROSKA_ID_CUES:
4728 if (demux->common.index_parsed) {
4729 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4732 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4733 ret = gst_matroska_read_common_parse_index (&demux->common, &ebml);
4734 /* only push based; delayed index building */
4735 if (ret == GST_FLOW_OK
4736 && demux->common.state == GST_MATROSKA_READ_STATE_SEEK) {
4739 GST_OBJECT_LOCK (demux);
4740 event = demux->seek_event;
4741 demux->seek_event = NULL;
4742 GST_OBJECT_UNLOCK (demux);
4745 /* unlikely to fail, since we managed to seek to this point */
4746 if (!gst_matroska_demux_handle_seek_event (demux, NULL, event))
4748 /* resume data handling, main thread clear to seek again */
4749 GST_OBJECT_LOCK (demux);
4750 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
4751 GST_OBJECT_UNLOCK (demux);
4754 case GST_MATROSKA_ID_POSITION:
4755 case GST_MATROSKA_ID_PREVSIZE:
4756 case GST_MATROSKA_ID_ENCRYPTEDBLOCK:
4757 case GST_MATROSKA_ID_SILENTTRACKS:
4758 GST_DEBUG_OBJECT (demux,
4759 "Skipping Cluster subelement 0x%x - ignoring", id);
4763 GST_DEBUG_OBJECT (demux, "skipping Element 0x%x", id);
4764 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4770 if (ret == GST_FLOW_PARSE)
4774 gst_ebml_read_clear (&ebml);
4780 /* simply exit, maybe not enough data yet */
4781 /* no ebml to clear if read error */
4786 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4787 ("Failed to parse Element 0x%x", id));
4788 ret = GST_FLOW_ERROR;
4793 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4794 ("File layout does not permit streaming"));
4795 ret = GST_FLOW_ERROR;
4800 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4801 ("No Tracks element found"));
4802 ret = GST_FLOW_ERROR;
4807 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Invalid header"));
4808 ret = GST_FLOW_ERROR;
4813 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Failed to seek"));
4814 ret = GST_FLOW_ERROR;
4820 gst_matroska_demux_loop (GstPad * pad)
4822 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (pad));
4828 /* If we have to close a segment, send a new segment to do this now */
4829 if (G_LIKELY (demux->common.state == GST_MATROSKA_READ_STATE_DATA)) {
4830 if (G_UNLIKELY (demux->close_segment)) {
4831 gst_matroska_demux_send_event (demux, demux->close_segment);
4832 demux->close_segment = NULL;
4834 if (G_UNLIKELY (demux->new_segment)) {
4835 gst_matroska_demux_send_event (demux, demux->new_segment);
4836 demux->new_segment = NULL;
4840 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4841 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4842 if (ret == GST_FLOW_UNEXPECTED)
4844 if (ret != GST_FLOW_OK) {
4845 if (gst_matroska_demux_check_parse_error (demux))
4851 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
4852 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
4855 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4856 if (ret == GST_FLOW_UNEXPECTED)
4858 if (ret != GST_FLOW_OK)
4861 /* check if we're at the end of a configured segment */
4862 if (G_LIKELY (demux->common.src->len)) {
4865 g_assert (demux->common.num_streams == demux->common.src->len);
4866 for (i = 0; i < demux->common.src->len; i++) {
4868 #ifdef MKV_DEMUX_MODIFICATION
4869 //Index table Creation Logic
4870 if((demux->seek_head_cluster_info_absent || demux->seek_head_cue_info_absent) && !demux->index_table_created) {
4871 GST_INFO("Index table needs to be created");
4873 guint64 index_offset = demux->common.offset;
4875 GST_INFO("offset index is %"G_GUINT64_FORMAT, demux->common.offset);
4876 demux->common.segment.duration = -1;
4877 gst_matroska_demux_create_index_table(demux);
4879 demux->common.offset = index_offset;
4880 demux->index_table_created = TRUE;
4881 demux->common.segment.last_stop = 0;
4882 demux->common.segment.duration = demux->duration;
4883 GST_INFO("index table creation completed");
4886 GstMatroskaTrackContext *context = g_ptr_array_index (demux->common.src, i);
4887 GST_DEBUG_OBJECT (context->pad, "pos %" GST_TIME_FORMAT,
4888 GST_TIME_ARGS (context->pos));
4889 if (context->eos == FALSE)
4893 GST_INFO_OBJECT (demux, "All streams are EOS");
4894 ret = GST_FLOW_UNEXPECTED;
4895 #ifdef MKV_DEMUX_MODIFICATION
4896 if(demux->is_eos_blockgroup || demux->is_eos_simpleblock) {
4897 demux->seek_entry = 0;
4904 if (G_UNLIKELY (demux->common.offset ==
4905 gst_matroska_read_common_get_length (&demux->common))) {
4906 GST_LOG_OBJECT (demux, "Reached end of stream");
4907 ret = GST_FLOW_UNEXPECTED;
4916 if (demux->common.segment.rate < 0.0) {
4917 ret = gst_matroska_demux_seek_to_previous_keyframe (demux);
4918 if (ret == GST_FLOW_OK)
4925 const gchar *reason = gst_flow_get_name (ret);
4926 gboolean push_eos = FALSE;
4928 GST_LOG_OBJECT (demux, "pausing task, reason %s", reason);
4929 demux->segment_running = FALSE;
4930 gst_pad_pause_task (demux->common.sinkpad);
4932 if (ret == GST_FLOW_UNEXPECTED) {
4933 /* perform EOS logic */
4935 /* If we were in the headers, make sure we send no-more-pads.
4936 This will ensure decodebin2 does not get stuck thinking
4937 the chain is not complete yet, and waiting indefinitely. */
4938 if (G_UNLIKELY (demux->common.state == GST_MATROSKA_READ_STATE_HEADER)) {
4939 if (demux->common.src->len == 0) {
4940 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
4941 ("No pads created"));
4943 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL),
4944 ("Failed to finish reading headers"));
4946 gst_element_no_more_pads (GST_ELEMENT (demux));
4949 /* Close the segment, i.e. update segment stop with the duration
4950 * if no stop was set */
4951 if (GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) &&
4952 !GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop) &&
4953 GST_CLOCK_TIME_IS_VALID (demux->common.segment.start) &&
4954 demux->last_stop_end > demux->common.segment.start) {
4955 /* arrange to accumulate duration downstream, but avoid sending
4956 * newsegment with decreasing start (w.r.t. sync newsegment events) */
4958 gst_event_new_new_segment_full (TRUE, demux->common.segment.rate,
4959 demux->common.segment.applied_rate, demux->common.segment.format,
4960 demux->last_stop_end, demux->last_stop_end,
4961 demux->common.segment.time + (demux->last_stop_end -
4962 demux->common.segment.start));
4963 gst_matroska_demux_send_event (demux, event);
4966 if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
4969 /* for segment playback we need to post when (in stream time)
4970 * we stopped, this is either stop (when set) or the duration. */
4971 if ((stop = demux->common.segment.stop) == -1)
4972 stop = demux->last_stop_end;
4974 GST_LOG_OBJECT (demux, "Sending segment done, at end of segment");
4975 gst_element_post_message (GST_ELEMENT (demux),
4976 gst_message_new_segment_done (GST_OBJECT (demux), GST_FORMAT_TIME,
4981 } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_UNEXPECTED) {
4982 /* for fatal errors we post an error message */
4983 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
4984 ("stream stopped, reason %s", reason));
4988 /* send EOS, and prevent hanging if no streams yet */
4989 GST_LOG_OBJECT (demux, "Sending EOS, at end of stream");
4990 if (!gst_matroska_demux_send_event (demux, gst_event_new_eos ()) &&
4991 (ret == GST_FLOW_UNEXPECTED)) {
4992 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4993 (NULL), ("got eos but no streams (yet)"));
5001 * Create and push a flushing seek event upstream
5004 perform_seek_to_offset (GstMatroskaDemux * demux, guint64 offset)
5009 GST_DEBUG_OBJECT (demux, "Seeking to %" G_GUINT64_FORMAT, offset);
5012 gst_event_new_seek (1.0, GST_FORMAT_BYTES,
5013 GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, GST_SEEK_TYPE_SET, offset,
5014 GST_SEEK_TYPE_NONE, -1);
5016 res = gst_pad_push_event (demux->common.sinkpad, event);
5018 /* newsegment event will update offset */
5022 static GstFlowReturn
5023 gst_matroska_demux_chain (GstPad * pad, GstBuffer * buffer)
5025 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (pad));
5027 GstFlowReturn ret = GST_FLOW_OK;
5032 if (G_UNLIKELY (GST_BUFFER_IS_DISCONT (buffer))) {
5033 GST_DEBUG_OBJECT (demux, "got DISCONT");
5034 gst_adapter_clear (demux->common.adapter);
5035 GST_OBJECT_LOCK (demux);
5036 gst_matroska_read_common_reset_streams (&demux->common,
5037 GST_CLOCK_TIME_NONE, FALSE);
5038 GST_OBJECT_UNLOCK (demux);
5041 gst_adapter_push (demux->common.adapter, buffer);
5045 available = gst_adapter_available (demux->common.adapter);
5047 ret = gst_matroska_read_common_peek_id_length_push (&demux->common,
5048 GST_ELEMENT_CAST (demux), &id, &length, &needed);
5049 if (G_UNLIKELY (ret != GST_FLOW_OK && ret != GST_FLOW_UNEXPECTED))
5052 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
5053 "size %" G_GUINT64_FORMAT ", needed %d, available %d",
5054 demux->common.offset, id, length, needed, available);
5056 if (needed > available)
5059 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
5060 if (ret == GST_FLOW_UNEXPECTED) {
5061 /* need more data */
5063 } else if (ret != GST_FLOW_OK) {
5070 gst_matroska_demux_handle_sink_event (GstPad * pad, GstEvent * event)
5072 gboolean res = TRUE;
5073 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (pad));
5075 GST_DEBUG_OBJECT (demux,
5076 "have event type %s: %p on sink pad", GST_EVENT_TYPE_NAME (event), event);
5078 switch (GST_EVENT_TYPE (event)) {
5079 case GST_EVENT_NEWSEGMENT:
5082 gdouble rate, arate;
5083 gint64 start, stop, time = 0;
5087 /* some debug output */
5088 gst_segment_init (&segment, GST_FORMAT_UNDEFINED);
5089 gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format,
5090 &start, &stop, &time);
5091 gst_segment_set_newsegment_full (&segment, update, rate, arate, format,
5093 GST_DEBUG_OBJECT (demux,
5094 "received format %d newsegment %" GST_SEGMENT_FORMAT, format,
5097 if (demux->common.state < GST_MATROSKA_READ_STATE_DATA) {
5098 GST_DEBUG_OBJECT (demux, "still starting");
5102 /* we only expect a BYTE segment, e.g. following a seek */
5103 if (format != GST_FORMAT_BYTES) {
5104 GST_DEBUG_OBJECT (demux, "unsupported segment format, ignoring");
5108 GST_DEBUG_OBJECT (demux, "clearing segment state");
5109 GST_OBJECT_LOCK (demux);
5110 /* clear current segment leftover */
5111 gst_adapter_clear (demux->common.adapter);
5112 /* and some streaming setup */
5113 demux->common.offset = start;
5114 /* do not know where we are;
5115 * need to come across a cluster and generate newsegment */
5116 demux->common.segment.last_stop = GST_CLOCK_TIME_NONE;
5117 demux->cluster_time = GST_CLOCK_TIME_NONE;
5118 demux->cluster_offset = 0;
5119 demux->need_newsegment = TRUE;
5120 /* but keep some of the upstream segment */
5121 demux->common.segment.rate = rate;
5122 GST_OBJECT_UNLOCK (demux);
5124 /* chain will send initial newsegment after pads have been added,
5125 * or otherwise come up with one */
5126 GST_DEBUG_OBJECT (demux, "eating event");
5127 gst_event_unref (event);
5133 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
5134 gst_event_unref (event);
5135 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
5136 (NULL), ("got eos and didn't receive a complete header object"));
5137 } else if (demux->common.num_streams == 0) {
5138 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
5139 (NULL), ("got eos but no streams (yet)"));
5141 gst_matroska_demux_send_event (demux, event);
5145 case GST_EVENT_FLUSH_STOP:
5147 gst_adapter_clear (demux->common.adapter);
5148 GST_OBJECT_LOCK (demux);
5149 gst_matroska_read_common_reset_streams (&demux->common,
5150 GST_CLOCK_TIME_NONE, TRUE);
5151 demux->common.segment.last_stop = GST_CLOCK_TIME_NONE;
5152 demux->cluster_time = GST_CLOCK_TIME_NONE;
5153 demux->cluster_offset = 0;
5154 GST_OBJECT_UNLOCK (demux);
5158 res = gst_pad_event_default (pad, event);
5166 gst_matroska_demux_sink_activate (GstPad * sinkpad)
5168 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (sinkpad));
5170 if (gst_pad_check_pull_range (sinkpad)) {
5171 GST_DEBUG ("going to pull mode");
5172 demux->streaming = FALSE;
5173 return gst_pad_activate_pull (sinkpad, TRUE);
5175 GST_DEBUG ("going to push (streaming) mode");
5176 demux->streaming = TRUE;
5177 return gst_pad_activate_push (sinkpad, TRUE);
5184 gst_matroska_demux_sink_activate_pull (GstPad * sinkpad, gboolean active)
5186 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (sinkpad));
5189 /* if we have a scheduler we can start the task */
5190 demux->segment_running = TRUE;
5191 gst_pad_start_task (sinkpad, (GstTaskFunction) gst_matroska_demux_loop,
5194 demux->segment_running = FALSE;
5195 gst_pad_stop_task (sinkpad);
5202 gst_duration_to_fraction (guint64 duration, gint * dest_n, gint * dest_d)
5204 static const int common_den[] = { 1, 2, 3, 4, 1001 };
5209 for (i = 0; i < G_N_ELEMENTS (common_den); i++) {
5211 n = floor (0.5 + (d * 1e9) / duration);
5212 a = gst_util_uint64_scale_int (1000000000, d, n);
5213 if (duration >= a - 1 && duration <= a + 1) {
5218 gst_util_double_to_fraction (1e9 / duration, &n, &d);
5227 gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext *
5228 videocontext, const gchar * codec_id, guint8 * data, guint size,
5229 gchar ** codec_name, guint32 * riff_fourcc)
5231 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) videocontext;
5232 GstCaps *caps = NULL;
5234 g_assert (videocontext != NULL);
5235 g_assert (codec_name != NULL);
5237 context->send_xiph_headers = FALSE;
5238 context->send_flac_headers = FALSE;
5239 context->send_speex_headers = FALSE;
5244 /* TODO: check if we have all codec types from matroska-ids.h
5245 * check if we have to do more special things with codec_private
5248 * GST_MATROSKA_CODEC_ID_VIDEO_QUICKTIME
5249 * GST_MATROSKA_CODEC_ID_VIDEO_SNOW
5252 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VFW_FOURCC)) {
5253 gst_riff_strf_vids *vids = NULL;
5256 GstBuffer *buf = NULL;
5258 vids = (gst_riff_strf_vids *) data;
5260 /* assure size is big enough */
5262 GST_WARNING ("Too small BITMAPINFOHEADER (%d bytes)", size);
5265 if (size < sizeof (gst_riff_strf_vids)) {
5266 vids = g_new (gst_riff_strf_vids, 1);
5267 memcpy (vids, data, size);
5270 /* little-endian -> byte-order */
5271 vids->size = GUINT32_FROM_LE (vids->size);
5272 vids->width = GUINT32_FROM_LE (vids->width);
5273 vids->height = GUINT32_FROM_LE (vids->height);
5274 vids->planes = GUINT16_FROM_LE (vids->planes);
5275 vids->bit_cnt = GUINT16_FROM_LE (vids->bit_cnt);
5276 vids->compression = GUINT32_FROM_LE (vids->compression);
5277 vids->image_size = GUINT32_FROM_LE (vids->image_size);
5278 vids->xpels_meter = GUINT32_FROM_LE (vids->xpels_meter);
5279 vids->ypels_meter = GUINT32_FROM_LE (vids->ypels_meter);
5280 vids->num_colors = GUINT32_FROM_LE (vids->num_colors);
5281 vids->imp_colors = GUINT32_FROM_LE (vids->imp_colors);
5283 if (size > sizeof (gst_riff_strf_vids)) { /* some extra_data */
5284 buf = gst_buffer_new_and_alloc (size - sizeof (gst_riff_strf_vids));
5285 memcpy (GST_BUFFER_DATA (buf),
5286 (guint8 *) vids + sizeof (gst_riff_strf_vids),
5287 GST_BUFFER_SIZE (buf));
5291 *riff_fourcc = vids->compression;
5293 caps = gst_riff_create_video_caps (vids->compression, NULL, vids,
5294 buf, NULL, codec_name);
5297 GST_WARNING ("Unhandled RIFF fourcc %" GST_FOURCC_FORMAT,
5298 GST_FOURCC_ARGS (vids->compression));
5302 gst_buffer_unref (buf);
5304 if (vids != (gst_riff_strf_vids *) data)
5307 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_UNCOMPRESSED)) {
5310 switch (videocontext->fourcc) {
5311 case GST_MAKE_FOURCC ('I', '4', '2', '0'):
5312 *codec_name = g_strdup ("Raw planar YUV 4:2:0");
5313 fourcc = videocontext->fourcc;
5315 case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
5316 *codec_name = g_strdup ("Raw packed YUV 4:2:2");
5317 fourcc = videocontext->fourcc;
5319 case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
5320 *codec_name = g_strdup ("Raw packed YUV 4:2:0");
5321 fourcc = videocontext->fourcc;
5323 case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
5324 *codec_name = g_strdup ("Raw packed YUV 4:2:2");
5325 fourcc = videocontext->fourcc;
5327 case GST_MAKE_FOURCC ('A', 'Y', 'U', 'V'):
5328 *codec_name = g_strdup ("Raw packed YUV 4:4:4 with alpha channel");
5329 fourcc = videocontext->fourcc;
5333 GST_DEBUG ("Unknown fourcc %" GST_FOURCC_FORMAT,
5334 GST_FOURCC_ARGS (videocontext->fourcc));
5338 caps = gst_caps_new_simple ("video/x-raw-yuv",
5339 "format", GST_TYPE_FOURCC, fourcc, NULL);
5340 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_SP)) {
5341 caps = gst_caps_new_simple ("video/x-divx",
5342 "divxversion", G_TYPE_INT, 4, NULL);
5343 *codec_name = g_strdup ("MPEG-4 simple profile");
5344 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP) ||
5345 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AP)) {
5347 caps = gst_caps_new_full (gst_structure_new ("video/x-divx",
5348 "divxversion", G_TYPE_INT, 5, NULL),
5349 gst_structure_new ("video/x-xvid", NULL),
5350 gst_structure_new ("video/mpeg",
5351 "mpegversion", G_TYPE_INT, 4,
5352 "systemstream", G_TYPE_BOOLEAN, FALSE, NULL), NULL);
5354 caps = gst_caps_new_simple ("video/mpeg",
5355 "mpegversion", G_TYPE_INT, 4,
5356 "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
5358 GstBuffer *priv = gst_buffer_new_and_alloc (size);
5360 memcpy (GST_BUFFER_DATA (priv), data, size);
5361 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5362 gst_buffer_unref (priv);
5364 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP))
5365 *codec_name = g_strdup ("MPEG-4 advanced simple profile");
5367 *codec_name = g_strdup ("MPEG-4 advanced profile");
5368 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MSMPEG4V3)) {
5370 caps = gst_caps_new_full (gst_structure_new ("video/x-divx",
5371 "divxversion", G_TYPE_INT, 3, NULL),
5372 gst_structure_new ("video/x-msmpeg",
5373 "msmpegversion", G_TYPE_INT, 43, NULL), NULL);
5375 caps = gst_caps_new_simple ("video/x-msmpeg",
5376 "msmpegversion", G_TYPE_INT, 43, NULL);
5377 *codec_name = g_strdup ("Microsoft MPEG-4 v.3");
5378 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1) ||
5379 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG2)) {
5382 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1))
5387 caps = gst_caps_new_simple ("video/mpeg",
5388 "systemstream", G_TYPE_BOOLEAN, FALSE,
5389 "mpegversion", G_TYPE_INT, mpegversion, NULL);
5390 *codec_name = g_strdup_printf ("MPEG-%d video", mpegversion);
5391 context->postprocess_frame = gst_matroska_demux_add_mpeg_seq_header;
5392 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MJPEG)) {
5393 caps = gst_caps_new_simple ("image/jpeg", NULL);
5394 *codec_name = g_strdup ("Motion-JPEG");
5395 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AVC)) {
5396 caps = gst_caps_new_simple ("video/x-h264", NULL);
5398 GstBuffer *priv = gst_buffer_new_and_alloc (size);
5400 /* First byte is the version, second is the profile indication, and third
5401 * is the 5 contraint_set_flags and 3 reserved bits. Fourth byte is the
5402 * level indication. */
5403 gst_codec_utils_h264_caps_set_level_and_profile (caps, data + 1,
5406 memcpy (GST_BUFFER_DATA (priv), data, size);
5407 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5408 gst_buffer_unref (priv);
5410 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "avc",
5411 "alignment", G_TYPE_STRING, "au", NULL);
5413 GST_WARNING ("No codec data found, assuming output is byte-stream");
5414 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
5417 *codec_name = g_strdup ("H264");
5418 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1)) ||
5419 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2)) ||
5420 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3)) ||
5421 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))) {
5422 gint rmversion = -1;
5424 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1))
5426 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2))
5428 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3))
5430 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))
5433 caps = gst_caps_new_simple ("video/x-pn-realvideo",
5434 "rmversion", G_TYPE_INT, rmversion, NULL);
5435 GST_DEBUG ("data:%p, size:0x%x", data, size);
5436 /* We need to extract the extradata ! */
5437 if (data && (size >= 0x22)) {
5442 subformat = GST_READ_UINT32_BE (data + 0x1a);
5443 rformat = GST_READ_UINT32_BE (data + 0x1e);
5445 priv = gst_buffer_new_and_alloc (size - 0x1a);
5447 memcpy (GST_BUFFER_DATA (priv), data + 0x1a, size - 0x1a);
5448 gst_caps_set_simple (caps,
5449 "codec_data", GST_TYPE_BUFFER, priv,
5450 "format", G_TYPE_INT, rformat,
5451 "subformat", G_TYPE_INT, subformat, NULL);
5452 gst_buffer_unref (priv);
5455 *codec_name = g_strdup_printf ("RealVideo %d.0", rmversion);
5456 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_THEORA)) {
5457 caps = gst_caps_new_simple ("video/x-theora", NULL);
5458 context->send_xiph_headers = TRUE;
5459 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_DIRAC)) {
5460 caps = gst_caps_new_simple ("video/x-dirac", NULL);
5461 *codec_name = g_strdup_printf ("Dirac");
5462 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8)) {
5463 caps = gst_caps_new_simple ("video/x-vp8", NULL);
5464 *codec_name = g_strdup_printf ("On2 VP8");
5466 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
5472 GstStructure *structure;
5474 for (i = 0; i < gst_caps_get_size (caps); i++) {
5475 structure = gst_caps_get_structure (caps, i);
5477 /* FIXME: use the real unit here! */
5478 GST_DEBUG ("video size %dx%d, target display size %dx%d (any unit)",
5479 videocontext->pixel_width,
5480 videocontext->pixel_height,
5481 videocontext->display_width, videocontext->display_height);
5483 /* pixel width and height are the w and h of the video in pixels */
5484 if (videocontext->pixel_width > 0 && videocontext->pixel_height > 0) {
5485 gint w = videocontext->pixel_width;
5486 gint h = videocontext->pixel_height;
5488 gst_structure_set (structure,
5489 "width", G_TYPE_INT, w, "height", G_TYPE_INT, h, NULL);
5492 if (videocontext->display_width > 0 || videocontext->display_height > 0) {
5495 if (videocontext->display_width <= 0)
5496 videocontext->display_width = videocontext->pixel_width;
5497 if (videocontext->display_height <= 0)
5498 videocontext->display_height = videocontext->pixel_height;
5500 /* calculate the pixel aspect ratio using the display and pixel w/h */
5501 n = videocontext->display_width * videocontext->pixel_height;
5502 d = videocontext->display_height * videocontext->pixel_width;
5503 GST_DEBUG ("setting PAR to %d/%d", n, d);
5504 gst_structure_set (structure, "pixel-aspect-ratio",
5506 videocontext->display_width * videocontext->pixel_height,
5507 videocontext->display_height * videocontext->pixel_width, NULL);
5510 if (videocontext->default_fps > 0.0) {
5511 GValue fps_double = { 0, };
5512 GValue fps_fraction = { 0, };
5514 g_value_init (&fps_double, G_TYPE_DOUBLE);
5515 g_value_init (&fps_fraction, GST_TYPE_FRACTION);
5516 g_value_set_double (&fps_double, videocontext->default_fps);
5517 g_value_transform (&fps_double, &fps_fraction);
5519 GST_DEBUG ("using default fps %f", videocontext->default_fps);
5521 gst_structure_set_value (structure, "framerate", &fps_fraction);
5522 g_value_unset (&fps_double);
5523 g_value_unset (&fps_fraction);
5524 } else if (context->default_duration > 0) {
5527 gst_duration_to_fraction (context->default_duration, &fps_n, &fps_d);
5529 GST_INFO ("using default duration %" G_GUINT64_FORMAT
5530 " framerate %d/%d", context->default_duration, fps_n, fps_d);
5532 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
5533 fps_n, fps_d, NULL);
5535 /* sort of a hack to get most codecs to support,
5536 * even if the default_duration is missing */
5537 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
5541 if (videocontext->parent.flags & GST_MATROSKA_VIDEOTRACK_INTERLACED)
5542 gst_structure_set (structure, "interlaced", G_TYPE_BOOLEAN, TRUE, NULL);
5545 gst_caps_do_simplify (caps);
5552 * Some AAC specific code... *sigh*
5553 * FIXME: maybe we should use '15' and code the sample rate explicitly
5554 * if the sample rate doesn't match the predefined rates exactly? (tpm)
5558 aac_rate_idx (gint rate)
5562 else if (75132 <= rate)
5564 else if (55426 <= rate)
5566 else if (46009 <= rate)
5568 else if (37566 <= rate)
5570 else if (27713 <= rate)
5572 else if (23004 <= rate)
5574 else if (18783 <= rate)
5576 else if (13856 <= rate)
5578 else if (11502 <= rate)
5580 else if (9391 <= rate)
5587 aac_profile_idx (const gchar * codec_id)
5591 if (strlen (codec_id) <= 12)
5593 else if (!strncmp (&codec_id[12], "MAIN", 4))
5595 else if (!strncmp (&codec_id[12], "LC", 2))
5597 else if (!strncmp (&codec_id[12], "SSR", 3))
5605 #define AAC_SYNC_EXTENSION_TYPE 0x02b7
5608 gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext *
5609 audiocontext, const gchar * codec_id, guint8 * data, guint size,
5610 gchar ** codec_name, guint16 * riff_audio_fmt)
5612 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) audiocontext;
5613 GstCaps *caps = NULL;
5615 g_assert (audiocontext != NULL);
5616 g_assert (codec_name != NULL);
5619 *riff_audio_fmt = 0;
5621 context->send_xiph_headers = FALSE;
5622 context->send_flac_headers = FALSE;
5623 context->send_speex_headers = FALSE;
5625 /* TODO: check if we have all codec types from matroska-ids.h
5626 * check if we have to do more special things with codec_private
5627 * check if we need bitdepth in different places too
5628 * implement channel position magic
5630 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID9
5631 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID10
5632 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDMC
5633 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDM2
5636 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1) ||
5637 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2) ||
5638 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L3)) {
5641 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1))
5643 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2))
5648 caps = gst_caps_new_simple ("audio/mpeg",
5649 "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, layer, NULL);
5650 *codec_name = g_strdup_printf ("MPEG-1 layer %d", layer);
5651 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE) ||
5652 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_LE)) {
5655 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE))
5656 endianness = G_BIG_ENDIAN;
5658 endianness = G_LITTLE_ENDIAN;
5660 caps = gst_caps_new_simple ("audio/x-raw-int",
5661 "width", G_TYPE_INT, audiocontext->bitdepth,
5662 "depth", G_TYPE_INT, audiocontext->bitdepth,
5663 "signed", G_TYPE_BOOLEAN, audiocontext->bitdepth != 8,
5664 "endianness", G_TYPE_INT, endianness, NULL);
5666 *codec_name = g_strdup_printf ("Raw %d-bit PCM audio",
5667 audiocontext->bitdepth);
5668 context->alignment = audiocontext->bitdepth / 8;
5669 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_FLOAT)) {
5670 caps = gst_caps_new_simple ("audio/x-raw-float",
5671 "endianness", G_TYPE_INT, G_LITTLE_ENDIAN,
5672 "width", G_TYPE_INT, audiocontext->bitdepth, NULL);
5673 *codec_name = g_strdup_printf ("Raw %d-bit floating-point audio",
5674 audiocontext->bitdepth);
5675 context->alignment = audiocontext->bitdepth / 8;
5676 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AC3,
5677 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AC3))) {
5678 caps = gst_caps_new_simple ("audio/x-ac3",
5679 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5680 *codec_name = g_strdup ("AC-3 audio");
5681 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_EAC3,
5682 strlen (GST_MATROSKA_CODEC_ID_AUDIO_EAC3))) {
5683 caps = gst_caps_new_simple ("audio/x-eac3",
5684 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5685 *codec_name = g_strdup ("E-AC-3 audio");
5686 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_DTS)) {
5687 caps = gst_caps_new_simple ("audio/x-dts", NULL);
5688 *codec_name = g_strdup ("DTS audio");
5689 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_VORBIS)) {
5690 caps = gst_caps_new_simple ("audio/x-vorbis", NULL);
5691 context->send_xiph_headers = TRUE;
5692 /* vorbis decoder does tags */
5693 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_FLAC)) {
5694 caps = gst_caps_new_simple ("audio/x-flac", NULL);
5695 context->send_flac_headers = TRUE;
5696 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_SPEEX)) {
5697 caps = gst_caps_new_simple ("audio/x-speex", NULL);
5698 context->send_speex_headers = TRUE;
5699 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_ACM)) {
5700 gst_riff_strf_auds auds;
5703 GstBuffer *codec_data = gst_buffer_new ();
5705 /* little-endian -> byte-order */
5706 auds.format = GST_READ_UINT16_LE (data);
5707 auds.channels = GST_READ_UINT16_LE (data + 2);
5708 auds.rate = GST_READ_UINT32_LE (data + 4);
5709 auds.av_bps = GST_READ_UINT32_LE (data + 8);
5710 auds.blockalign = GST_READ_UINT16_LE (data + 12);
5711 auds.size = GST_READ_UINT16_LE (data + 16);
5713 /* 18 is the waveformatex size */
5714 gst_buffer_set_data (codec_data, data + 18, auds.size);
5717 *riff_audio_fmt = auds.format;
5719 caps = gst_riff_create_audio_caps (auds.format, NULL, &auds, NULL,
5720 codec_data, codec_name);
5721 gst_buffer_unref (codec_data);
5724 GST_WARNING ("Unhandled RIFF audio format 0x%02x", auds.format);
5727 } else if (g_str_has_prefix (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC)) {
5728 GstBuffer *priv = NULL;
5730 gint rate_idx, profile;
5731 guint8 *data = NULL;
5733 /* unspecified AAC profile with opaque private codec data */
5734 if (strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC) == 0) {
5735 if (context->codec_priv_size >= 2) {
5736 guint obj_type, freq_index, explicit_freq_bytes = 0;
5738 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
5740 freq_index = (GST_READ_UINT16_BE (context->codec_priv) & 0x780) >> 7;
5741 obj_type = (GST_READ_UINT16_BE (context->codec_priv) & 0xF800) >> 11;
5742 if (freq_index == 15)
5743 explicit_freq_bytes = 3;
5744 GST_DEBUG ("obj_type = %u, freq_index = %u", obj_type, freq_index);
5745 priv = gst_buffer_new_and_alloc (context->codec_priv_size);
5746 memcpy (GST_BUFFER_DATA (priv), context->codec_priv,
5747 context->codec_priv_size);
5748 /* assume SBR if samplerate <= 24kHz */
5749 if (obj_type == 5 || (freq_index >= 6 && freq_index != 15) ||
5750 (context->codec_priv_size == (5 + explicit_freq_bytes))) {
5751 audiocontext->samplerate *= 2;
5754 GST_WARNING ("Opaque A_AAC codec ID, but no codec private data");
5755 /* this is pretty broken;
5756 * maybe we need to make up some default private,
5757 * or maybe ADTS data got dumped in.
5758 * Let's set up some private data now, and check actual data later */
5759 /* just try this and see what happens ... */
5760 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
5761 context->postprocess_frame = gst_matroska_demux_check_aac;
5765 /* make up decoder-specific data if it is not supplied */
5767 priv = gst_buffer_new_and_alloc (5);
5768 data = GST_BUFFER_DATA (priv);
5769 rate_idx = aac_rate_idx (audiocontext->samplerate);
5770 profile = aac_profile_idx (codec_id);
5772 data[0] = ((profile + 1) << 3) | ((rate_idx & 0xE) >> 1);
5773 data[1] = ((rate_idx & 0x1) << 7) | (audiocontext->channels << 3);
5774 GST_BUFFER_SIZE (priv) = 2;
5776 if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2,
5777 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2))) {
5779 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4,
5780 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4))) {
5783 if (g_strrstr (codec_id, "SBR")) {
5784 /* HE-AAC (aka SBR AAC) */
5785 audiocontext->samplerate *= 2;
5786 rate_idx = aac_rate_idx (audiocontext->samplerate);
5787 data[2] = AAC_SYNC_EXTENSION_TYPE >> 3;
5788 data[3] = ((AAC_SYNC_EXTENSION_TYPE & 0x07) << 5) | 5;
5789 data[4] = (1 << 7) | (rate_idx << 3);
5790 GST_BUFFER_SIZE (priv) = 5;
5793 gst_buffer_unref (priv);
5795 GST_ERROR ("Unknown AAC profile and no codec private data");
5800 caps = gst_caps_new_simple ("audio/mpeg",
5801 "mpegversion", G_TYPE_INT, mpegversion,
5802 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5803 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5804 *codec_name = g_strdup_printf ("MPEG-%d AAC audio", mpegversion);
5805 gst_buffer_unref (priv);
5807 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TTA)) {
5808 caps = gst_caps_new_simple ("audio/x-tta",
5809 "width", G_TYPE_INT, audiocontext->bitdepth, NULL);
5810 *codec_name = g_strdup ("TTA audio");
5811 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_WAVPACK4)) {
5812 caps = gst_caps_new_simple ("audio/x-wavpack",
5813 "width", G_TYPE_INT, audiocontext->bitdepth,
5814 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5815 *codec_name = g_strdup ("Wavpack audio");
5816 context->postprocess_frame = gst_matroska_demux_add_wvpk_header;
5817 audiocontext->wvpk_block_index = 0;
5818 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4)) ||
5819 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4)) ||
5820 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))) {
5821 gint raversion = -1;
5823 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4))
5825 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))
5830 caps = gst_caps_new_simple ("audio/x-pn-realaudio",
5831 "raversion", G_TYPE_INT, raversion, NULL);
5832 /* Extract extra information from caps, mapping varies based on codec */
5833 if (data && (size >= 0x50)) {
5840 guint extra_data_size;
5842 GST_ERROR ("real audio raversion:%d", raversion);
5843 if (raversion == 8) {
5845 flavor = GST_READ_UINT16_BE (data + 22);
5846 packet_size = GST_READ_UINT32_BE (data + 24);
5847 height = GST_READ_UINT16_BE (data + 40);
5848 leaf_size = GST_READ_UINT16_BE (data + 44);
5849 sample_width = GST_READ_UINT16_BE (data + 58);
5850 extra_data_size = GST_READ_UINT32_BE (data + 74);
5853 ("flavor:%d, packet_size:%d, height:%d, leaf_size:%d, sample_width:%d, extra_data_size:%d",
5854 flavor, packet_size, height, leaf_size, sample_width,
5856 gst_caps_set_simple (caps, "flavor", G_TYPE_INT, flavor, "packet_size",
5857 G_TYPE_INT, packet_size, "height", G_TYPE_INT, height, "leaf_size",
5858 G_TYPE_INT, leaf_size, "width", G_TYPE_INT, sample_width, NULL);
5860 if ((size - 78) >= extra_data_size) {
5861 priv = gst_buffer_new_and_alloc (extra_data_size);
5862 memcpy (GST_BUFFER_DATA (priv), data + 78, extra_data_size);
5863 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5864 gst_buffer_unref (priv);
5869 *codec_name = g_strdup_printf ("RealAudio %d.0", raversion);
5870 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_SIPR)) {
5871 caps = gst_caps_new_simple ("audio/x-sipro", NULL);
5872 *codec_name = g_strdup ("Sipro/ACELP.NET Voice Codec");
5873 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_RALF)) {
5874 caps = gst_caps_new_simple ("audio/x-ralf-mpeg4-generic", NULL);
5875 *codec_name = g_strdup ("Real Audio Lossless");
5876 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_ATRC)) {
5877 caps = gst_caps_new_simple ("audio/x-vnd.sony.atrac3", NULL);
5878 *codec_name = g_strdup ("Sony ATRAC3");
5880 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
5885 if (audiocontext->samplerate > 0 && audiocontext->channels > 0) {
5888 for (i = 0; i < gst_caps_get_size (caps); i++) {
5889 gst_structure_set (gst_caps_get_structure (caps, i),
5890 "channels", G_TYPE_INT, audiocontext->channels,
5891 "rate", G_TYPE_INT, audiocontext->samplerate, NULL);
5895 gst_caps_do_simplify (caps);
5902 gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
5903 subtitlecontext, const gchar * codec_id, gpointer data, guint size)
5905 GstCaps *caps = NULL;
5906 GstMatroskaTrackContext *context =
5907 (GstMatroskaTrackContext *) subtitlecontext;
5909 /* for backwards compatibility */
5910 if (!g_ascii_strcasecmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASCII))
5911 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8;
5912 else if (!g_ascii_strcasecmp (codec_id, "S_SSA"))
5913 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_SSA;
5914 else if (!g_ascii_strcasecmp (codec_id, "S_ASS"))
5915 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_ASS;
5916 else if (!g_ascii_strcasecmp (codec_id, "S_USF"))
5917 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_USF;
5919 /* TODO: Add GST_MATROSKA_CODEC_ID_SUBTITLE_BMP support
5920 * Check if we have to do something with codec_private */
5921 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8)) {
5922 /* well, plain text simply does not have a lot of markup ... */
5923 caps = gst_caps_new_simple ("text/x-pango-markup", NULL);
5924 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5925 subtitlecontext->check_markup = TRUE;
5926 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_SSA)) {
5927 caps = gst_caps_new_simple ("application/x-ssa", NULL);
5928 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5929 subtitlecontext->check_markup = FALSE;
5930 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASS)) {
5931 caps = gst_caps_new_simple ("application/x-ass", NULL);
5932 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5933 subtitlecontext->check_markup = FALSE;
5934 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_USF)) {
5935 caps = gst_caps_new_simple ("application/x-usf", NULL);
5936 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5937 subtitlecontext->check_markup = FALSE;
5938 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB)) {
5939 caps = gst_caps_new_simple ("video/x-dvd-subpicture", NULL);
5940 ((GstMatroskaTrackContext *) subtitlecontext)->send_dvd_event = TRUE;
5941 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_HDMVPGS)) {
5942 caps = gst_caps_new_simple ("subpicture/x-pgs", NULL);
5943 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_KATE)) {
5944 caps = gst_caps_new_simple ("subtitle/x-kate", NULL);
5945 context->send_xiph_headers = TRUE;
5947 GST_DEBUG ("Unknown subtitle stream: codec_id='%s'", codec_id);
5948 caps = gst_caps_new_simple ("application/x-subtitle-unknown", NULL);
5951 if (data != NULL && size > 0) {
5954 buf = gst_buffer_new_and_alloc (size);
5955 memcpy (GST_BUFFER_DATA (buf), data, size);
5956 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, buf, NULL);
5957 gst_buffer_unref (buf);
5964 gst_matroska_demux_set_index (GstElement * element, GstIndex * index)
5966 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5968 GST_OBJECT_LOCK (demux);
5969 if (demux->common.element_index)
5970 gst_object_unref (demux->common.element_index);
5971 demux->common.element_index = index ? gst_object_ref (index) : NULL;
5972 GST_OBJECT_UNLOCK (demux);
5973 GST_DEBUG_OBJECT (demux, "Set index %" GST_PTR_FORMAT,
5974 demux->common.element_index);
5978 gst_matroska_demux_get_index (GstElement * element)
5980 GstIndex *result = NULL;
5981 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5983 GST_OBJECT_LOCK (demux);
5984 if (demux->common.element_index)
5985 result = gst_object_ref (demux->common.element_index);
5986 GST_OBJECT_UNLOCK (demux);
5988 GST_DEBUG_OBJECT (demux, "Returning index %" GST_PTR_FORMAT, result);
5994 #ifdef MKV_DEMUX_MODIFICATION
5995 static GstMatroskaIndex *
5996 gst_matroska_demux_get_next_index (GstMatroskaDemux * demux, GstMatroskaTrackContext * track, GstMatroskaIndex *entry)
6000 GstMatroskaIndex *tmp = NULL;
6002 /* find entry just before or at the requested position */
6003 if (track && track->index_table)
6004 index = track->index_table;
6006 index = demux->common.index;
6008 for (i=0; i < index->len; i++) {
6009 tmp = &g_array_index (index, GstMatroskaIndex, i);
6010 if ((tmp->time == entry->time) && (tmp->pos == entry->pos)) {
6011 if ((index->len - i) == 1) {
6012 GST_DEBUG_OBJECT (demux, "entry found in last index...returning last index");
6014 GST_DEBUG_OBJECT (demux, "Found entry at index = %d");
6016 tmp = &g_array_index (index, GstMatroskaIndex, i);
6024 static GstFlowReturn
6025 gst_matroska_demux_trickplay_find_tracks (GstMatroskaDemux * demux)
6031 GstFlowReturn ret = GST_FLOW_OK;
6033 GST_WARNING_OBJECT (demux,
6034 "Found Cluster element before Tracks, searching Tracks");
6037 before_pos = demux->common.offset;
6039 /* Search Tracks element */
6041 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
6042 GST_ELEMENT_CAST (demux), &id, &length, &needed);
6043 if (ret != GST_FLOW_OK)
6046 if (id != GST_MATROSKA_ID_TRACKS) {
6047 /* we may be skipping large cluster here, so forego size check etc */
6048 /* ... but we can't skip undefined size; force error */
6049 if (length == G_MAXUINT64) {
6050 ret = gst_matroska_demux_check_read_size (demux, length);
6053 demux->common.offset += needed;
6054 demux->common.offset += length;
6059 /* will lead to track parsing ... */
6060 ret = gst_matroska_demux_trickplay_parse_id (demux, id, length, needed);
6065 demux->common.offset = before_pos;
6070 static GstFlowReturn
6071 gst_matroska_demux_trickplay_parse_id (GstMatroskaDemux * demux, guint32 id,
6072 guint64 length, guint needed)
6074 GstEbmlRead ebml = { 0, };
6075 GstFlowReturn ret = GST_FLOW_OK;
6078 GST_LOG_OBJECT (demux, "Parsing Element id 0x%x, "
6079 "size %" G_GUINT64_FORMAT ", prefix %d", id, length, needed);
6081 /* if we plan to read and parse this element, we need prefix (id + length)
6082 * and the contents */
6083 /* mind about overflow wrap-around when dealing with undefined size */
6085 if (G_LIKELY (length != G_MAXUINT64))
6088 switch (demux->common.state) {
6089 case GST_MATROSKA_READ_STATE_START:
6091 case GST_EBML_ID_HEADER:
6092 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
6093 ret = gst_matroska_read_common_parse_header (&demux->common, &ebml);
6094 if (ret != GST_FLOW_OK)
6096 demux->common.state = GST_MATROSKA_READ_STATE_SEGMENT;
6097 gst_matroska_demux_check_seekability (demux);
6100 goto invalid_header;
6104 case GST_MATROSKA_READ_STATE_SEGMENT:
6106 case GST_MATROSKA_ID_SEGMENT:
6107 /* eat segment prefix */
6108 GST_READ_CHECK (gst_matroska_demux_flush (demux, needed));
6109 GST_DEBUG_OBJECT (demux,
6110 "Found Segment start at offset %" G_GUINT64_FORMAT,
6111 demux->common.offset);
6112 /* seeks are from the beginning of the segment,
6113 * after the segment ID/length */
6114 demux->common.ebml_segment_start = demux->common.offset;
6115 demux->common.state = GST_MATROSKA_READ_STATE_HEADER;
6118 GST_WARNING_OBJECT (demux,
6119 "Expected a Segment ID (0x%x), but received 0x%x!",
6120 GST_MATROSKA_ID_SEGMENT, id);
6121 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
6125 case GST_MATROSKA_READ_STATE_SCANNING:
6126 if (id != GST_MATROSKA_ID_CLUSTER &&
6127 id != GST_MATROSKA_ID_CLUSTERTIMECODE)
6130 case GST_MATROSKA_READ_STATE_HEADER:
6131 case GST_MATROSKA_READ_STATE_DATA:
6132 case GST_MATROSKA_READ_STATE_SEEK:
6134 case GST_MATROSKA_ID_CLUSTER:
6135 if (G_UNLIKELY (!demux->tracks_parsed)) {
6136 if (demux->streaming) {
6137 GST_DEBUG_OBJECT (demux, "Cluster before Track");
6138 goto not_streamable;
6140 ret = gst_matroska_demux_trickplay_find_tracks (demux);
6141 if (!demux->tracks_parsed)
6145 if (G_UNLIKELY (demux->common.state == GST_MATROSKA_READ_STATE_HEADER)) {
6146 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
6147 demux->first_cluster_offset = demux->common.offset;
6148 GST_DEBUG_OBJECT (demux, "signaling no more pads");
6149 gst_element_no_more_pads (GST_ELEMENT (demux));
6150 /* send initial newsegment */
6151 gst_matroska_demux_send_event (demux,
6152 gst_event_new_new_segment (FALSE, 1.0,
6154 (demux->common.segment.duration >
6155 0) ? demux->common.segment.duration : -1, 0));
6157 demux->cluster_time = GST_CLOCK_TIME_NONE;
6158 demux->cluster_offset = demux->common.offset;
6159 if (G_UNLIKELY (!demux->seek_first && demux->seek_block)) {
6160 GST_DEBUG_OBJECT (demux, "seek target block %" G_GUINT64_FORMAT
6161 " not found in Cluster, trying next Cluster's first block instead",
6163 demux->seek_block = 0;
6165 demux->seek_first = FALSE;
6166 /* record next cluster for recovery */
6167 if (read != G_MAXUINT64)
6168 demux->next_cluster_offset = demux->cluster_offset + read;
6169 /* eat cluster prefix */
6170 gst_matroska_demux_flush (demux, needed);
6172 case GST_MATROSKA_ID_CLUSTERTIMECODE: {
6175 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
6176 if ((ret = gst_ebml_read_uint (&ebml, &id, &num)) != GST_FLOW_OK)
6178 GST_DEBUG_OBJECT (demux, "ClusterTimeCode: %" G_GUINT64_FORMAT, num);
6179 demux->cluster_time = num;
6180 if (demux->common.element_index) {
6181 if (demux->common.element_index_writer_id == -1)
6182 gst_index_get_writer_id (demux->common.element_index,
6183 GST_OBJECT (demux), &demux->common.element_index_writer_id);
6184 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
6185 G_GUINT64_FORMAT " for writer id %d",
6186 GST_TIME_ARGS (demux->cluster_time), demux->cluster_offset,
6187 demux->common.element_index_writer_id);
6188 gst_index_add_association (demux->common.element_index,
6189 demux->common.element_index_writer_id, GST_ASSOCIATION_FLAG_KEY_UNIT,
6190 GST_FORMAT_TIME, demux->cluster_time,
6191 GST_FORMAT_BYTES, demux->cluster_offset, NULL);
6195 case GST_MATROSKA_ID_BLOCKGROUP:
6196 if (!gst_matroska_demux_seek_block (demux))
6198 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
6199 DEBUG_ELEMENT_START (demux, &ebml, "BlockGroup");
6200 if ((ret = gst_ebml_read_master (&ebml, &id)) == GST_FLOW_OK) {
6201 ret = gst_matroska_demux_trickplay_parse_blockgroup_or_simpleblock (demux,
6202 &ebml, demux->cluster_time, demux->cluster_offset, FALSE);
6204 DEBUG_ELEMENT_STOP (demux, &ebml, "BlockGroup", ret);
6206 case GST_MATROSKA_ID_SIMPLEBLOCK:
6207 if (!gst_matroska_demux_seek_block (demux))
6209 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
6210 DEBUG_ELEMENT_START (demux, &ebml, "SimpleBlock");
6211 ret = gst_matroska_demux_trickplay_parse_blockgroup_or_simpleblock (demux,
6212 &ebml, demux->cluster_time, demux->cluster_offset, TRUE);
6213 DEBUG_ELEMENT_STOP (demux, &ebml, "SimpleBlock", ret);
6215 case GST_MATROSKA_ID_SEGMENTINFO:
6216 case GST_MATROSKA_ID_TRACKS:
6217 case GST_MATROSKA_ID_ATTACHMENTS:
6218 case GST_MATROSKA_ID_TAGS:
6219 case GST_MATROSKA_ID_CHAPTERS:
6220 case GST_MATROSKA_ID_SEEKHEAD:
6221 case GST_MATROSKA_ID_CUES:
6222 case GST_MATROSKA_ID_POSITION:
6223 case GST_MATROSKA_ID_PREVSIZE:
6224 case GST_MATROSKA_ID_ENCRYPTEDBLOCK:
6225 case GST_MATROSKA_ID_SILENTTRACKS:
6226 GST_DEBUG_OBJECT (demux,
6227 "Skipping Cluster subelement 0x%x - ignoring", id);
6231 GST_DEBUG_OBJECT (demux, "skipping Element 0x%x", id);
6232 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
6238 if (ret == GST_FLOW_PARSE)
6242 gst_ebml_read_clear (&ebml);
6248 /* simply exit, maybe not enough data yet */
6249 /* no ebml to clear if read error */
6254 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
6255 ("Failed to parse Element 0x%x", id));
6256 ret = GST_FLOW_ERROR;
6261 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
6262 ("File layout does not permit streaming"));
6263 ret = GST_FLOW_ERROR;
6268 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
6269 ("No Tracks element found"));
6270 ret = GST_FLOW_ERROR;
6275 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Invalid header"));
6276 ret = GST_FLOW_ERROR;
6281 static GstFlowReturn
6282 gst_matroska_demux_trickplay_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux,
6283 GstEbmlRead * ebml, guint64 cluster_time, guint64 cluster_offset,
6284 gboolean is_simpleblock)
6286 GstMatroskaTrackContext *stream = NULL;
6287 GstFlowReturn ret = GST_FLOW_OK;
6288 gboolean readblock = FALSE;
6290 guint64 block_duration = 0;
6291 GstBuffer *buf = NULL;
6292 gint stream_num = -1, n, laces = 0;
6296 gint64 referenceblock = 0;
6299 offset = gst_ebml_read_get_offset (ebml);
6301 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
6302 if (!is_simpleblock) {
6303 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK) {
6307 id = GST_MATROSKA_ID_SIMPLEBLOCK;
6311 /* one block inside the group. Note, block parsing is one
6312 * of the harder things, so this code is a bit complicated.
6313 * See http://www.matroska.org/ for documentation. */
6314 case GST_MATROSKA_ID_SIMPLEBLOCK:
6315 case GST_MATROSKA_ID_BLOCK: {
6320 gst_buffer_unref (buf);
6323 if ((ret = gst_ebml_read_buffer (ebml, &id, &buf)) != GST_FLOW_OK)
6326 data = GST_BUFFER_DATA (buf);
6327 size = GST_BUFFER_SIZE (buf);
6329 /* first byte(s): blocknum */
6330 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
6335 /* fetch stream from num */
6336 stream_num = gst_matroska_read_common_stream_from_num (&demux->common, num);
6337 if (G_UNLIKELY (size < 3)) {
6338 GST_WARNING_OBJECT (demux, "Invalid size %u", size);
6339 /* non-fatal, try next block(group) */
6342 } else if (G_UNLIKELY (stream_num < 0 ||
6343 stream_num >= demux->common.num_streams)) {
6344 /* let's not give up on a stray invalid track number */
6345 GST_WARNING_OBJECT (demux,
6346 "Invalid stream %d for track number %" G_GUINT64_FORMAT
6347 "; ignoring block", stream_num, num);
6351 stream = g_ptr_array_index (demux->common.src, stream_num);
6353 /* time (relative to cluster time) */
6354 time = ((gint16) GST_READ_UINT16_BE (data));
6357 flags = GST_READ_UINT8 (data);
6361 GST_LOG_OBJECT (demux, "time %" G_GUINT64_FORMAT ", flags %d", time,
6364 switch ((flags & 0x06) >> 1) {
6365 case 0x0: /* no lacing */
6369 case 0x1: /* xiph lacing */
6370 case 0x2: /* fixed-size lacing */
6371 case 0x3: /* EBML lacing */
6373 goto invalid_lacing;
6374 laces = GST_READ_UINT8 (data) + 1;
6379 if (ret != GST_FLOW_OK)
6386 case GST_MATROSKA_ID_BLOCKDURATION: {
6387 ret = gst_ebml_read_uint (ebml, &id, &block_duration);
6388 GST_DEBUG_OBJECT (demux, "BlockDuration: %" G_GUINT64_FORMAT,
6393 case GST_MATROSKA_ID_REFERENCEBLOCK: {
6394 ret = gst_ebml_read_sint (ebml, &id, &referenceblock);
6395 GST_DEBUG_OBJECT (demux, "ReferenceBlock: %" G_GINT64_FORMAT,
6401 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml, "BlockGroup", id);
6404 case GST_MATROSKA_ID_BLOCKVIRTUAL:
6405 case GST_MATROSKA_ID_BLOCKADDITIONS:
6406 case GST_MATROSKA_ID_REFERENCEPRIORITY:
6407 case GST_MATROSKA_ID_REFERENCEVIRTUAL:
6408 case GST_MATROSKA_ID_SLICES:
6409 GST_DEBUG_OBJECT (demux,
6410 "Skipping BlockGroup subelement 0x%x - ignoring", id);
6411 ret = gst_ebml_read_skip (ebml);
6419 /* reading a number or so could have failed */
6420 if (ret != GST_FLOW_OK)
6423 if (ret == GST_FLOW_OK && readblock) {
6424 gint64 lace_time = 0;
6425 gboolean delta_unit;
6427 stream = g_ptr_array_index (demux->common.src, stream_num);
6429 if (cluster_time != GST_CLOCK_TIME_NONE) {
6430 /* FIXME: What to do with negative timestamps? Give timestamp 0 or -1?
6431 * Drop unless the lace contains timestamp 0? */
6432 if (time < 0 && (-time) > cluster_time) {
6435 if (stream->timecodescale == 1.0)
6436 lace_time = (cluster_time + time) * demux->common.time_scale;
6439 gst_util_guint64_to_gdouble ((cluster_time + time) *
6440 demux->common.time_scale) * stream->timecodescale;
6443 lace_time = GST_CLOCK_TIME_NONE;
6446 /* else duration is diff between timecode of this and next block */
6448 /* For SimpleBlock, look at the keyframe bit in flags. Otherwise,
6449 a ReferenceBlock implies that this is not a keyframe. In either
6450 case, it only makes sense for video streams. */
6451 delta_unit = stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
6452 ((is_simpleblock && !(flags & 0x80)) || referenceblock);
6454 if (delta_unit && stream->set_discont) {
6455 /* When doing seeks or such, we need to restart on key frames or
6456 * decoders might choke. */
6457 GST_DEBUG_OBJECT (demux, "skipping delta unit");
6461 /* last_ts used for EOS in trickplay */
6462 stream->last_ts = lace_time;
6464 if (stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
6465 stream->num_frames_bw_keyframes++;
6466 if (delta_unit == FALSE) {
6467 stream->found_next_kframe = TRUE;
6468 demux->next_key_cluster_time = demux->cluster_time;
6469 stream->next_kframe_timestamp = lace_time;
6470 demux->common.segment.last_stop = lace_time - 0.5* GST_SECOND;
6472 } else if (stream->type == GST_MATROSKA_TRACK_TYPE_AUDIO) {
6473 stream->num_frames_bw_keyframes = stream->num_frames_bw_keyframes + laces;
6479 gst_buffer_unref (buf);
6485 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Invalid lacing size"));
6486 /* non-fatal, try next block(group) */
6492 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Data error"));
6493 /* non-fatal, try next block(group) */
6500 gst_matroska_demux_trickplay_nframes2show_bw_keyframes (GstMatroskaDemux* demux, GstMatroskaTrackContext * stream)
6502 GstFlowReturn ret = GST_FLOW_OK;
6506 gint prev_offset = demux->common.offset;
6507 gint next_keyframe_offset = 0;
6508 guint64 prev_cluster_time = demux->cluster_time;
6509 guint64 prev_cluster_offset = demux->cluster_offset;
6512 while (stream->found_next_kframe == FALSE) {
6513 next_keyframe_offset = demux->common.offset;
6515 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
6516 GST_ELEMENT_CAST (demux), &id, &length, &needed);
6517 if (ret == GST_FLOW_UNEXPECTED) {
6518 stream->next_kframe_timestamp = stream->last_ts;
6519 stream->found_next_kframe = TRUE;
6522 GST_LOG_OBJECT (demux, "trickplay : Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
6523 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
6526 if (ret != GST_FLOW_OK) {
6527 GST_WARNING_OBJECT (demux, "Error in id_length_pull flow ret...reason : %s\n", gst_flow_get_name (ret));
6531 ret = gst_matroska_demux_trickplay_parse_id (demux, id, length, needed);
6532 if (ret == GST_FLOW_UNEXPECTED) {
6533 stream->next_kframe_timestamp = stream->last_ts;
6534 stream->found_next_kframe = TRUE;
6538 if (ret != GST_FLOW_OK) {
6539 GST_WARNING_OBJECT (demux, "Error in parse_id flow ret...reason : %s\n", gst_flow_get_name (ret));
6544 if (stream->found_next_kframe == TRUE) {
6545 demux->next_key_frame_offset = next_keyframe_offset;
6548 for (i = 0; i < demux->common.src->len; i++) {
6549 GstMatroskaTrackContext *context = g_ptr_array_index (demux->common.src, i);
6550 if (context->type <= GST_MATROSKA_TRACK_TYPE_AUDIO) {
6551 context->frames_to_show_bw_keyframes = context->num_frames_bw_keyframes / demux->common.segment.rate;
6555 /* keeping previous offset values for normal operation */
6556 demux->common.offset = prev_offset;
6557 demux->cluster_offset = prev_cluster_offset;
6558 demux->cluster_time = prev_cluster_time;
6560 return stream->num_frames_bw_keyframes;
6563 static GstFlowReturn
6564 gst_matroska_demux_backward_trickplay (GstMatroskaDemux* demux, GstMatroskaTrackContext * stream, GstBuffer* sub)
6566 GstFlowReturn ret = GST_FLOW_OK;
6568 if (((stream->type == GST_MATROSKA_TRACK_TYPE_AUDIO) || (!GST_BUFFER_FLAG_IS_SET (sub, GST_BUFFER_FLAG_DELTA_UNIT)))
6569 && (demux->prev_keyframe_ts <= (GST_BUFFER_TIMESTAMP (sub)) <= demux->next_keyframe_ts)) {
6571 if(stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO && !demux->video_keyframe_pushed) {
6572 demux->video_keyframe_pushed = TRUE;
6573 } else if(stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO && demux->video_keyframe_pushed){
6574 GST_INFO("unreffing the video frame (already sent one keyframe)");
6575 gst_buffer_unref (sub);
6579 if(demux->prev_keyframe_ts == demux->next_keyframe_ts || demux->prev_keyframe_ts > demux->next_keyframe_ts) {
6580 GST_INFO("Unreffing the already pushed buffer");
6581 gst_buffer_unref (sub);
6585 GST_DEBUG_OBJECT (demux, "Pushing data of size %d for stream %d, time=%"GST_TIME_FORMAT
6586 " and duration=%" GST_TIME_FORMAT,
6587 GST_BUFFER_SIZE (sub), stream->type,
6588 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (sub)),
6589 GST_TIME_ARGS (GST_BUFFER_DURATION (sub)));
6591 g_assert (stream->alignment <= G_MEM_ALIGN);
6592 if (((guintptr) GST_BUFFER_DATA (sub)) & (stream->alignment - 1)) {
6593 GST_INFO("in if alignment log");
6594 GstBuffer *buffer = gst_buffer_new_and_alloc (GST_BUFFER_SIZE (sub));
6595 memcpy (GST_BUFFER_DATA (buffer), GST_BUFFER_DATA (sub),
6596 GST_BUFFER_SIZE (sub));
6597 gst_buffer_copy_metadata (buffer, sub, GST_BUFFER_COPY_ALL);
6598 GST_DEBUG_OBJECT (demux, "We want output aligned on %d, reallocated", stream->alignment);
6599 gst_buffer_unref (sub);
6603 ret = gst_pad_push(stream->pad, sub);
6605 if (ret != GST_FLOW_OK) {
6606 GST_DEBUG_OBJECT (demux, "Error in pad_push. Reason : %s\n", gst_flow_get_name (ret));
6608 } else if(GST_BUFFER_FLAG_IS_SET (sub, GST_BUFFER_FLAG_DELTA_UNIT)) {
6609 gst_buffer_unref (sub);
6614 static GstFlowReturn
6615 gst_matroska_demux_forward_trickplay (GstMatroskaDemux* demux, GstMatroskaTrackContext * stream, GstBuffer *buffer, gboolean *skip)
6617 GstFlowReturn ret = GST_FLOW_OK;
6618 guint64 time_escalation = 0;
6621 if (stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
6622 if ((stream->found_next_kframe == FALSE) && (!GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT))) {
6623 GST_INFO("Finding the no of frames b/w keyframe");
6624 g_assert (!GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT));
6625 gst_matroska_demux_trickplay_nframes2show_bw_keyframes (demux, stream);
6626 stream->prev_kframe_timestamp = GST_BUFFER_TIMESTAMP (buffer);
6627 GST_INFO("next keyframe timestamp is %"GST_TIME_FORMAT" and previous keyframe timestamp is %"GST_TIME_FORMAT,
6628 GST_TIME_ARGS(stream->next_kframe_timestamp), GST_TIME_ARGS(stream->prev_kframe_timestamp));
6629 stream->avg_duration_bw_keyframes = (stream->next_kframe_timestamp - stream->prev_kframe_timestamp) / stream->num_frames_bw_keyframes;
6630 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);
6631 GST_DEBUG_OBJECT (demux, "average duration of frames = %"GST_TIME_FORMAT, GST_TIME_ARGS(stream->avg_duration_bw_keyframes));
6633 for (i = 0; i < demux->common.src->len; i++) {
6634 GstMatroskaTrackContext *context = g_ptr_array_index (demux->common.src, i);
6635 if (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO) {
6636 context->num_frames_bw_keyframes = 0;
6640 if (stream->frames_to_show_bw_keyframes == 0) {
6641 stream->found_next_kframe = FALSE;
6642 demux->cluster_time = demux->next_key_cluster_time;
6643 demux->common.offset = demux->next_key_frame_offset;
6644 stream->num_frames_bw_keyframes = 0;
6645 GST_DEBUG_OBJECT (demux, "next key cluster time = %"GST_TIME_FORMAT" and offset = %u...\n", GST_TIME_ARGS(demux->cluster_time), demux->common.offset);
6648 if(stream->num_frames_bw_keyframes == 0)
6651 if(stream->frames_to_show_bw_keyframes > 0) {
6652 GST_INFO("Time stamp modification %"GST_TIME_FORMAT,GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(buffer)));
6654 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;
6656 GST_BUFFER_TIMESTAMP(buffer) = stream->prev_kframe_timestamp + time_escalation;
6657 GST_INFO("Time stamp modified %"GST_TIME_FORMAT,GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(buffer)));
6659 stream->frames_to_show_bw_keyframes--;
6661 } else if (stream->type == GST_MATROSKA_TRACK_TYPE_AUDIO) {
6662 if (stream->frames_to_show_bw_keyframes == 0) {
6664 stream->num_frames_bw_keyframes = 0;
6665 stream->frames_to_show_bw_keyframes = 0;
6667 stream->frames_to_show_bw_keyframes--;
6676 static GstStateChangeReturn
6677 gst_matroska_demux_change_state (GstElement * element,
6678 GstStateChange transition)
6680 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
6681 GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
6683 /* handle upwards state changes here */
6684 switch (transition) {
6689 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
6691 /* handle downwards state changes */
6692 switch (transition) {
6693 case GST_STATE_CHANGE_PAUSED_TO_READY:
6694 gst_matroska_demux_reset (GST_ELEMENT (demux));
6704 gst_matroska_demux_set_property (GObject * object,
6705 guint prop_id, const GValue * value, GParamSpec * pspec)
6707 GstMatroskaDemux *demux;
6709 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
6710 demux = GST_MATROSKA_DEMUX (object);
6713 case ARG_MAX_GAP_TIME:
6714 GST_OBJECT_LOCK (demux);
6715 demux->max_gap_time = g_value_get_uint64 (value);
6716 GST_OBJECT_UNLOCK (demux);
6719 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
6725 gst_matroska_demux_get_property (GObject * object,
6726 guint prop_id, GValue * value, GParamSpec * pspec)
6728 GstMatroskaDemux *demux;
6730 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
6731 demux = GST_MATROSKA_DEMUX (object);
6734 case ARG_MAX_GAP_TIME:
6735 GST_OBJECT_LOCK (demux);
6736 g_value_set_uint64 (value, demux->max_gap_time);
6737 GST_OBJECT_UNLOCK (demux);
6740 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
6745 #ifdef MKV_DEMUX_MODIFICATION
6746 static gboolean gst_matroska_demux_create_index_table(GstMatroskaDemux* demux)
6750 guint64 length_index;
6754 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
6755 GST_ELEMENT_CAST (demux), &id_index, &length_index, &needed_index);
6757 if (ret == GST_FLOW_UNEXPECTED || ret != GST_FLOW_OK) {
6758 GST_INFO("problem in pulling data or eos reached");
6759 demux->index_table_created = TRUE;
6763 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
6764 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id_index,
6765 length_index, needed_index);
6767 ret = gst_matroska_demux_parse_id (demux, id_index, length_index, needed_index);
6769 if(ret == GST_FLOW_UNEXPECTED || ret != GST_FLOW_OK) {
6770 GST_INFO("problem in pulling data or eos reached");
6771 demux->index_table_created = TRUE;
6781 gst_matroska_demux_plugin_init (GstPlugin * plugin)
6785 /* parser helper separate debug */
6786 GST_DEBUG_CATEGORY_INIT (ebmlread_debug, "ebmlread",
6787 0, "EBML stream helper class");
6789 /* create an elementfactory for the matroska_demux element */
6790 if (!gst_element_register (plugin, "matroskademux",
6791 GST_RANK_PRIMARY, GST_TYPE_MATROSKA_DEMUX))