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>
6 * matroska-demux.c: matroska file/stream demuxer
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details.
18 * You should have received a copy of the GNU Library General Public
19 * License along with this library; if not, write to the
20 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 * Boston, MA 02111-1307, USA.
24 /* TODO: check CRC32 if present
25 * TODO: there can be a segment after the first segment. Handle like
26 * chained oggs. Fixes #334082
27 * TODO: Test samples: http://www.matroska.org/samples/matrix/index.html
28 * http://samples.mplayerhq.hu/Matroska/
29 * TODO: check if demuxing is done correct for all codecs according to spec
30 * TODO: seeking with incomplete or without CUE
34 * SECTION:element-matroskademux
36 * matroskademux demuxes a Matroska file into the different contained streams.
39 * <title>Example launch line</title>
41 * gst-launch -v filesrc location=/path/to/mkv ! matroskademux ! vorbisdec ! audioconvert ! audioresample ! autoaudiosink
42 * ]| This pipeline demuxes a Matroska file and outputs the contained Vorbis audio.
53 #include <glib/gprintf.h>
55 /* For AVI compatibility mode
56 and for fourcc stuff */
57 #include <gst/riff/riff-read.h>
58 #include <gst/riff/riff-ids.h>
59 #include <gst/riff/riff-media.h>
61 #include <gst/tag/tag.h>
63 #include <gst/base/gsttypefindhelper.h>
73 #include <gst/pbutils/pbutils.h>
77 #include "matroska-demux.h"
78 #include "matroska-ids.h"
80 GST_DEBUG_CATEGORY_STATIC (matroskademux_debug);
81 #define GST_CAT_DEFAULT matroskademux_debug
83 #define DEBUG_ELEMENT_START(demux, ebml, element) \
84 GST_DEBUG_OBJECT (demux, "Parsing " element " element at offset %" \
85 G_GUINT64_FORMAT, gst_ebml_read_get_pos (ebml))
87 #define DEBUG_ELEMENT_STOP(demux, ebml, element, ret) \
88 GST_DEBUG_OBJECT (demux, "Parsing " element " element " \
89 " finished with '%s'", gst_flow_get_name (ret))
98 static GstStaticPadTemplate sink_templ = GST_STATIC_PAD_TEMPLATE ("sink",
101 GST_STATIC_CAPS ("video/x-matroska; video/webm")
104 /* TODO: fill in caps! */
106 static GstStaticPadTemplate audio_src_templ =
107 GST_STATIC_PAD_TEMPLATE ("audio_%02d",
110 GST_STATIC_CAPS ("ANY")
113 static GstStaticPadTemplate video_src_templ =
114 GST_STATIC_PAD_TEMPLATE ("video_%02d",
117 GST_STATIC_CAPS ("ANY")
120 static GstStaticPadTemplate subtitle_src_templ =
121 GST_STATIC_PAD_TEMPLATE ("subtitle_%02d",
124 GST_STATIC_CAPS ("text/plain; application/x-ssa; application/x-ass; "
125 "application/x-usf; video/x-dvd-subpicture; "
126 "subpicture/x-pgs; subtitle/x-kate; " "application/x-subtitle-unknown")
129 static GstFlowReturn gst_matroska_demux_parse_id (GstMatroskaDemux * demux,
130 guint32 id, guint64 length, guint needed);
132 /* element functions */
133 static void gst_matroska_demux_loop (GstPad * pad);
135 static gboolean gst_matroska_demux_element_send_event (GstElement * element,
137 static gboolean gst_matroska_demux_element_query (GstElement * element,
141 static gboolean gst_matroska_demux_sink_activate_pull (GstPad * sinkpad,
143 static gboolean gst_matroska_demux_sink_activate (GstPad * sinkpad);
145 static gboolean gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
146 GstPad * pad, GstEvent * event);
147 static gboolean gst_matroska_demux_handle_src_event (GstPad * pad,
149 static const GstQueryType *gst_matroska_demux_get_src_query_types (GstPad *
151 static gboolean gst_matroska_demux_handle_src_query (GstPad * pad,
154 static gboolean gst_matroska_demux_handle_sink_event (GstPad * pad,
156 static GstFlowReturn gst_matroska_demux_chain (GstPad * pad,
159 static GstStateChangeReturn
160 gst_matroska_demux_change_state (GstElement * element,
161 GstStateChange transition);
163 gst_matroska_demux_set_index (GstElement * element, GstIndex * index);
164 static GstIndex *gst_matroska_demux_get_index (GstElement * element);
167 static GstCaps *gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext
168 * videocontext, const gchar * codec_id, guint8 * data, guint size,
169 gchar ** codec_name, guint32 * riff_fourcc);
170 static GstCaps *gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext
171 * audiocontext, const gchar * codec_id, guint8 * data, guint size,
172 gchar ** codec_name, guint16 * riff_audio_fmt);
174 * gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
175 subtitlecontext, const gchar * codec_id, gpointer data, guint size);
178 static void gst_matroska_demux_reset (GstElement * element);
179 static gboolean perform_seek_to_offset (GstMatroskaDemux * demux,
182 #ifdef MKVDEMUX_MODIFICATION
183 static GstFlowReturn gst_sec_matroska_demux_find_tracks (GstMatroskaDemux * demux);
184 static GstFlowReturn gst_sec_matroska_demux_parse_id (GstMatroskaDemux * demux, guint32 id, guint64 length, guint needed);
185 static GstFlowReturn gst_sec_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux, GstEbmlRead * ebml, guint64 cluster_time, guint64 cluster_offset, gboolean is_simpleblock);
186 static gint32 gst_sec_matroska_nframes2show_bw_keyframes (GstMatroskaDemux* demux, GstMatroskaTrackContext * stream);
187 static GstFlowReturn gst_sec_matroska_forward_trickplay (GstMatroskaDemux* demux, GstMatroskaTrackContext * stream, GstBuffer *buffer, gboolean *skip);
190 GType gst_matroska_demux_get_type (void);
191 GST_BOILERPLATE (GstMatroskaDemux, gst_matroska_demux, GstElement,
195 gst_matroska_demux_base_init (gpointer klass)
197 GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
199 gst_element_class_add_pad_template (element_class,
200 gst_static_pad_template_get (&video_src_templ));
201 gst_element_class_add_pad_template (element_class,
202 gst_static_pad_template_get (&audio_src_templ));
203 gst_element_class_add_pad_template (element_class,
204 gst_static_pad_template_get (&subtitle_src_templ));
205 gst_element_class_add_pad_template (element_class,
206 gst_static_pad_template_get (&sink_templ));
208 gst_element_class_set_details_simple (element_class, "Matroska demuxer",
210 "Demuxes Matroska/WebM streams into video/audio/subtitles",
211 "GStreamer maintainers <gstreamer-devel@lists.sourceforge.net>");
215 gst_matroska_demux_finalize (GObject * object)
217 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (object);
220 g_ptr_array_free (demux->src, TRUE);
224 if (demux->global_tags) {
225 gst_tag_list_free (demux->global_tags);
226 demux->global_tags = NULL;
229 g_object_unref (demux->adapter);
231 G_OBJECT_CLASS (parent_class)->finalize (object);
235 gst_matroska_demux_class_init (GstMatroskaDemuxClass * klass)
237 GObjectClass *gobject_class = (GObjectClass *) klass;
238 GstElementClass *gstelement_class = (GstElementClass *) klass;
240 /* parser helper separate debug */
241 GST_DEBUG_CATEGORY_INIT (ebmlread_debug, "ebmlread",
242 0, "EBML stream helper class");
244 GST_DEBUG_CATEGORY_INIT (matroskademux_debug, "matroskademux", 0,
247 gobject_class->finalize = gst_matroska_demux_finalize;
249 gstelement_class->change_state =
250 GST_DEBUG_FUNCPTR (gst_matroska_demux_change_state);
251 gstelement_class->send_event =
252 GST_DEBUG_FUNCPTR (gst_matroska_demux_element_send_event);
253 gstelement_class->query =
254 GST_DEBUG_FUNCPTR (gst_matroska_demux_element_query);
256 gstelement_class->set_index =
257 GST_DEBUG_FUNCPTR (gst_matroska_demux_set_index);
258 gstelement_class->get_index =
259 GST_DEBUG_FUNCPTR (gst_matroska_demux_get_index);
263 gst_matroska_demux_init (GstMatroskaDemux * demux,
264 GstMatroskaDemuxClass * klass)
266 demux->sinkpad = gst_pad_new_from_static_template (&sink_templ, "sink");
267 gst_pad_set_activate_function (demux->sinkpad,
268 GST_DEBUG_FUNCPTR (gst_matroska_demux_sink_activate));
269 gst_pad_set_activatepull_function (demux->sinkpad,
270 GST_DEBUG_FUNCPTR (gst_matroska_demux_sink_activate_pull));
271 gst_pad_set_chain_function (demux->sinkpad,
272 GST_DEBUG_FUNCPTR (gst_matroska_demux_chain));
273 gst_pad_set_event_function (demux->sinkpad,
274 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_sink_event));
275 gst_element_add_pad (GST_ELEMENT (demux), demux->sinkpad);
277 /* initial stream no. */
280 demux->writing_app = NULL;
281 demux->muxing_app = NULL;
283 demux->global_tags = NULL;
285 demux->adapter = gst_adapter_new ();
287 #ifdef MKVDEMUX_MODIFICATION
288 demux->found_videokeyframe = FALSE;
289 demux->found_audioframe = FALSE;
293 gst_matroska_demux_reset (GST_ELEMENT (demux));
297 gst_matroska_track_free (GstMatroskaTrackContext * track)
299 g_free (track->codec_id);
300 g_free (track->codec_name);
301 g_free (track->name);
302 g_free (track->language);
303 g_free (track->codec_priv);
304 g_free (track->codec_state);
306 #ifdef MKVDEMUX_MODIFICATION
307 while (!g_queue_is_empty (track->queue)) {
308 GstBuffer* buf = g_queue_pop_head (track->queue);
309 gst_buffer_unref (buf);
311 g_queue_free (track->queue);
314 if (track->encodings != NULL) {
317 for (i = 0; i < track->encodings->len; ++i) {
318 GstMatroskaTrackEncoding *enc = &g_array_index (track->encodings,
319 GstMatroskaTrackEncoding,
322 g_free (enc->comp_settings);
324 g_array_free (track->encodings, TRUE);
327 if (track->pending_tags)
328 gst_tag_list_free (track->pending_tags);
330 if (track->index_table)
331 g_array_free (track->index_table, TRUE);
337 * Returns the aggregated GstFlowReturn.
340 gst_matroska_demux_combine_flows (GstMatroskaDemux * demux,
341 GstMatroskaTrackContext * track, GstFlowReturn ret)
345 /* store the value */
346 track->last_flow = ret;
348 /* any other error that is not-linked can be returned right away */
349 if (ret != GST_FLOW_NOT_LINKED)
352 /* only return NOT_LINKED if all other pads returned NOT_LINKED */
353 g_assert (demux->src->len == demux->num_streams);
354 for (i = 0; i < demux->src->len; i++) {
355 GstMatroskaTrackContext *ostream = g_ptr_array_index (demux->src, i);
360 ret = ostream->last_flow;
361 /* some other return value (must be SUCCESS but we can return
362 * other values as well) */
363 if (ret != GST_FLOW_NOT_LINKED)
366 /* if we get here, all other pads were unlinked and we return
369 GST_LOG_OBJECT (demux, "combined return %s", gst_flow_get_name (ret));
374 gst_matroska_demux_free_parsed_el (gpointer mem, gpointer user_data)
376 g_slice_free (guint64, mem);
380 gst_matroska_demux_reset (GstElement * element)
382 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
385 GST_DEBUG_OBJECT (demux, "Resetting state");
388 demux->state = GST_MATROSKA_DEMUX_STATE_START;
390 /* clean up existing streams */
392 g_assert (demux->src->len == demux->num_streams);
393 for (i = 0; i < demux->src->len; i++) {
394 GstMatroskaTrackContext *context = g_ptr_array_index (demux->src, i);
396 if (context->pad != NULL)
397 gst_element_remove_pad (GST_ELEMENT (demux), context->pad);
399 gst_caps_replace (&context->caps, NULL);
400 gst_matroska_track_free (context);
402 g_ptr_array_free (demux->src, TRUE);
404 demux->src = g_ptr_array_new ();
406 demux->num_streams = 0;
407 demux->num_a_streams = 0;
408 demux->num_t_streams = 0;
409 demux->num_v_streams = 0;
411 /* reset media info */
412 g_free (demux->writing_app);
413 demux->writing_app = NULL;
414 g_free (demux->muxing_app);
415 demux->muxing_app = NULL;
419 g_array_free (demux->index, TRUE);
423 if (demux->clusters) {
424 g_array_free (demux->clusters, TRUE);
425 demux->clusters = NULL;
430 demux->time_scale = 1000000;
431 demux->created = G_MININT64;
433 demux->index_parsed = FALSE;
434 demux->tracks_parsed = FALSE;
435 demux->segmentinfo_parsed = FALSE;
436 demux->attachments_parsed = FALSE;
438 g_list_foreach (demux->tags_parsed,
439 (GFunc) gst_matroska_demux_free_parsed_el, NULL);
440 g_list_free (demux->tags_parsed);
441 demux->tags_parsed = NULL;
443 g_list_foreach (demux->seek_parsed,
444 (GFunc) gst_matroska_demux_free_parsed_el, NULL);
445 g_list_free (demux->seek_parsed);
446 demux->seek_parsed = NULL;
448 gst_segment_init (&demux->segment, GST_FORMAT_TIME);
449 demux->last_stop_end = GST_CLOCK_TIME_NONE;
450 demux->seek_block = 0;
453 demux->cluster_time = GST_CLOCK_TIME_NONE;
454 demux->cluster_offset = 0;
455 demux->next_cluster_offset = 0;
456 demux->index_offset = 0;
457 demux->seekable = FALSE;
458 demux->need_newsegment = FALSE;
459 demux->building_index = FALSE;
460 if (demux->seek_event) {
461 gst_event_unref (demux->seek_event);
462 demux->seek_event = NULL;
465 demux->seek_index = NULL;
466 demux->seek_entry = 0;
468 if (demux->close_segment) {
469 gst_event_unref (demux->close_segment);
470 demux->close_segment = NULL;
473 if (demux->new_segment) {
474 gst_event_unref (demux->new_segment);
475 demux->new_segment = NULL;
478 if (demux->element_index) {
479 gst_object_unref (demux->element_index);
480 demux->element_index = NULL;
482 demux->element_index_writer_id = -1;
484 if (demux->global_tags) {
485 gst_tag_list_free (demux->global_tags);
487 demux->global_tags = gst_tag_list_new ();
489 if (demux->cached_buffer) {
490 gst_buffer_unref (demux->cached_buffer);
491 demux->cached_buffer = NULL;
496 * Calls pull_range for (offset,size) without advancing our offset
499 gst_matroska_demux_peek_bytes (GstMatroskaDemux * demux, guint64 offset,
500 guint size, GstBuffer ** p_buf, guint8 ** bytes)
504 /* Caching here actually makes much less difference than one would expect.
505 * We do it mainly to avoid pulling buffers of 1 byte all the time */
506 if (demux->cached_buffer) {
507 guint64 cache_offset = GST_BUFFER_OFFSET (demux->cached_buffer);
508 guint cache_size = GST_BUFFER_SIZE (demux->cached_buffer);
510 if (cache_offset <= demux->offset &&
511 (demux->offset + size) <= (cache_offset + cache_size)) {
513 *p_buf = gst_buffer_create_sub (demux->cached_buffer,
514 demux->offset - cache_offset, size);
516 *bytes = GST_BUFFER_DATA (demux->cached_buffer) + demux->offset -
520 /* not enough data in the cache, free cache and get a new one */
521 gst_buffer_unref (demux->cached_buffer);
522 demux->cached_buffer = NULL;
525 /* refill the cache */
526 ret = gst_pad_pull_range (demux->sinkpad, demux->offset,
527 MAX (size, 64 * 1024), &demux->cached_buffer);
528 if (ret != GST_FLOW_OK) {
529 demux->cached_buffer = NULL;
533 if (GST_BUFFER_SIZE (demux->cached_buffer) >= size) {
535 *p_buf = gst_buffer_create_sub (demux->cached_buffer, 0, size);
537 *bytes = GST_BUFFER_DATA (demux->cached_buffer);
541 /* Not possible to get enough data, try a last time with
542 * requesting exactly the size we need */
543 gst_buffer_unref (demux->cached_buffer);
544 demux->cached_buffer = NULL;
547 gst_pad_pull_range (demux->sinkpad, demux->offset, size,
548 &demux->cached_buffer);
549 if (ret != GST_FLOW_OK) {
550 GST_DEBUG_OBJECT (demux, "pull_range returned %d", ret);
558 if (GST_BUFFER_SIZE (demux->cached_buffer) < size) {
559 GST_WARNING_OBJECT (demux, "Dropping short buffer at offset %"
560 G_GUINT64_FORMAT ": wanted %u bytes, got %u bytes", demux->offset,
561 size, GST_BUFFER_SIZE (demux->cached_buffer));
563 gst_buffer_unref (demux->cached_buffer);
564 demux->cached_buffer = NULL;
569 return GST_FLOW_UNEXPECTED;
573 *p_buf = gst_buffer_create_sub (demux->cached_buffer, 0, size);
575 *bytes = GST_BUFFER_DATA (demux->cached_buffer);
580 static const guint8 *
581 gst_matroska_demux_peek_pull (GstMatroskaDemux * demux, guint peek)
585 gst_matroska_demux_peek_bytes (demux, demux->offset, peek, NULL, &data);
590 gst_matroska_demux_peek_id_length_pull (GstMatroskaDemux * demux, guint32 * _id,
591 guint64 * _length, guint * _needed)
593 return gst_ebml_peek_id_length (_id, _length, _needed,
594 (GstPeekData) gst_matroska_demux_peek_pull, (gpointer) demux,
595 GST_ELEMENT_CAST (demux), demux->offset);
599 gst_matroska_demux_get_length (GstMatroskaDemux * demux)
601 GstFormat fmt = GST_FORMAT_BYTES;
604 if (!gst_pad_query_peer_duration (demux->sinkpad, &fmt, &end) ||
605 fmt != GST_FORMAT_BYTES || end < 0)
606 GST_DEBUG_OBJECT (demux, "no upstream length");
612 gst_matroska_demux_stream_from_num (GstMatroskaDemux * demux, guint track_num)
616 g_assert (demux->src->len == demux->num_streams);
617 for (n = 0; n < demux->src->len; n++) {
618 GstMatroskaTrackContext *context = g_ptr_array_index (demux->src, n);
620 if (context->num == track_num) {
625 if (n == demux->num_streams)
626 GST_WARNING_OBJECT (demux,
627 "Failed to find corresponding pad for tracknum %d", track_num);
633 gst_matroska_demux_encoding_cmp (GstMatroskaTrackEncoding * a,
634 GstMatroskaTrackEncoding * b)
636 if (b->order > a->order)
638 else if (b->order < a->order)
645 gst_matroska_demux_encoding_order_unique (GArray * encodings, guint64 order)
649 if (encodings == NULL || encodings->len == 0)
652 for (i = 0; i < encodings->len; i++)
653 if (g_array_index (encodings, GstMatroskaTrackEncoding, i).order == order)
660 gst_matroska_demux_read_track_encoding (GstMatroskaDemux * demux,
661 GstEbmlRead * ebml, GstMatroskaTrackContext * context)
663 GstMatroskaTrackEncoding enc = { 0, };
667 DEBUG_ELEMENT_START (demux, ebml, "ContentEncoding");
668 /* Set default values */
670 /* All other default values are 0 */
672 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
673 DEBUG_ELEMENT_STOP (demux, ebml, "ContentEncoding", ret);
677 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
678 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
682 case GST_MATROSKA_ID_CONTENTENCODINGORDER:{
685 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
688 if (!gst_matroska_demux_encoding_order_unique (context->encodings, num)) {
689 GST_ERROR_OBJECT (demux, "ContentEncodingOrder %" G_GUINT64_FORMAT
690 "is not unique for track %d", num, context->num);
691 ret = GST_FLOW_ERROR;
695 GST_DEBUG_OBJECT (demux, "ContentEncodingOrder: %" G_GUINT64_FORMAT,
700 case GST_MATROSKA_ID_CONTENTENCODINGSCOPE:{
703 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
706 if (num > 7 && num == 0) {
707 GST_ERROR_OBJECT (demux, "Invalid ContentEncodingScope %"
708 G_GUINT64_FORMAT, num);
709 ret = GST_FLOW_ERROR;
713 GST_DEBUG_OBJECT (demux, "ContentEncodingScope: %" G_GUINT64_FORMAT,
719 case GST_MATROSKA_ID_CONTENTENCODINGTYPE:{
722 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
726 GST_ERROR_OBJECT (demux, "Invalid ContentEncodingType %"
727 G_GUINT64_FORMAT, num);
728 ret = GST_FLOW_ERROR;
730 } else if (num != 0) {
731 GST_ERROR_OBJECT (demux, "Encrypted tracks are not supported yet");
732 ret = GST_FLOW_ERROR;
735 GST_DEBUG_OBJECT (demux, "ContentEncodingType: %" G_GUINT64_FORMAT,
740 case GST_MATROSKA_ID_CONTENTCOMPRESSION:{
742 DEBUG_ELEMENT_START (demux, ebml, "ContentCompression");
744 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
747 while (ret == GST_FLOW_OK &&
748 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
749 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
753 case GST_MATROSKA_ID_CONTENTCOMPALGO:{
756 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK) {
760 GST_ERROR_OBJECT (demux, "Invalid ContentCompAlgo %"
761 G_GUINT64_FORMAT, num);
762 ret = GST_FLOW_ERROR;
765 GST_DEBUG_OBJECT (demux, "ContentCompAlgo: %" G_GUINT64_FORMAT,
771 case GST_MATROSKA_ID_CONTENTCOMPSETTINGS:{
776 gst_ebml_read_binary (ebml, &id, &data,
777 &size)) != GST_FLOW_OK) {
780 enc.comp_settings = data;
781 enc.comp_settings_length = size;
782 GST_DEBUG_OBJECT (demux,
783 "ContentCompSettings of size %" G_GUINT64_FORMAT, size);
787 GST_WARNING_OBJECT (demux,
788 "Unknown ContentCompression subelement 0x%x - ignoring", id);
789 ret = gst_ebml_read_skip (ebml);
793 DEBUG_ELEMENT_STOP (demux, ebml, "ContentCompression", ret);
797 case GST_MATROSKA_ID_CONTENTENCRYPTION:
798 GST_ERROR_OBJECT (demux, "Encrypted tracks not yet supported");
799 gst_ebml_read_skip (ebml);
800 ret = GST_FLOW_ERROR;
803 GST_WARNING_OBJECT (demux,
804 "Unknown ContentEncoding subelement 0x%x - ignoring", id);
805 ret = gst_ebml_read_skip (ebml);
810 DEBUG_ELEMENT_STOP (demux, ebml, "ContentEncoding", ret);
811 if (ret != GST_FLOW_OK && ret != GST_FLOW_UNEXPECTED)
814 /* TODO: Check if the combination of values is valid */
816 g_array_append_val (context->encodings, enc);
822 gst_matroska_decompress_data (GstMatroskaTrackEncoding * enc,
823 guint8 ** data_out, guint * size_out,
824 GstMatroskaTrackCompressionAlgorithm algo)
826 guint8 *new_data = NULL;
828 guint8 *data = *data_out;
829 guint size = *size_out;
832 if (algo == GST_MATROSKA_TRACK_COMPRESSION_ALGORITHM_ZLIB) {
834 /* zlib encoded data */
840 zstream.zalloc = (alloc_func) 0;
841 zstream.zfree = (free_func) 0;
842 zstream.opaque = (voidpf) 0;
843 if (inflateInit (&zstream) != Z_OK) {
844 GST_WARNING ("zlib initialization failed.");
848 zstream.next_in = (Bytef *) data;
849 zstream.avail_in = orig_size;
850 new_size = orig_size;
851 new_data = g_malloc (new_size);
852 zstream.avail_out = new_size;
853 zstream.next_out = (Bytef *) new_data;
856 result = inflate (&zstream, Z_NO_FLUSH);
857 if (result != Z_OK && result != Z_STREAM_END) {
858 GST_WARNING ("zlib decompression failed.");
860 inflateEnd (&zstream);
864 new_data = g_realloc (new_data, new_size);
865 zstream.next_out = (Bytef *) (new_data + zstream.total_out);
866 zstream.avail_out += 4000;
867 } while (zstream.avail_in != 0 && result != Z_STREAM_END);
869 if (result != Z_STREAM_END) {
873 new_size = zstream.total_out;
874 inflateEnd (&zstream);
877 GST_WARNING ("zlib encoded tracks not supported.");
881 } else if (algo == GST_MATROSKA_TRACK_COMPRESSION_ALGORITHM_BZLIB) {
883 /* bzip2 encoded data */
888 bzstream.bzalloc = NULL;
889 bzstream.bzfree = NULL;
890 bzstream.opaque = NULL;
893 if (BZ2_bzDecompressInit (&bzstream, 0, 0) != BZ_OK) {
894 GST_WARNING ("bzip2 initialization failed.");
899 bzstream.next_in = (char *) data;
900 bzstream.avail_in = orig_size;
901 new_size = orig_size;
902 new_data = g_malloc (new_size);
903 bzstream.avail_out = new_size;
904 bzstream.next_out = (char *) new_data;
907 result = BZ2_bzDecompress (&bzstream);
908 if (result != BZ_OK && result != BZ_STREAM_END) {
909 GST_WARNING ("bzip2 decompression failed.");
911 BZ2_bzDecompressEnd (&bzstream);
915 new_data = g_realloc (new_data, new_size);
916 bzstream.next_out = (char *) (new_data + bzstream.total_out_lo32);
917 bzstream.avail_out += 4000;
918 } while (bzstream.avail_in != 0 && result != BZ_STREAM_END);
920 if (result != BZ_STREAM_END) {
924 new_size = bzstream.total_out_lo32;
925 BZ2_bzDecompressEnd (&bzstream);
928 GST_WARNING ("bzip2 encoded tracks not supported.");
932 } else if (algo == GST_MATROSKA_TRACK_COMPRESSION_ALGORITHM_LZO1X) {
933 /* lzo encoded data */
935 int orig_size, out_size;
940 new_data = g_malloc (new_size);
946 result = lzo1x_decode (new_data, &out_size, data, &orig_size);
950 new_data = g_realloc (new_data, new_size);
952 } while (orig_size > 0 && result == LZO_OUTPUT_FULL);
954 new_size -= out_size;
956 if (result != LZO_OUTPUT_FULL) {
957 GST_WARNING ("lzo decompression failed");
964 } else if (algo == GST_MATROSKA_TRACK_COMPRESSION_ALGORITHM_HEADERSTRIP) {
965 /* header stripped encoded data */
966 if (enc->comp_settings_length > 0) {
967 new_data = g_malloc (size + enc->comp_settings_length);
968 new_size = size + enc->comp_settings_length;
970 memcpy (new_data, enc->comp_settings, enc->comp_settings_length);
971 memcpy (new_data + enc->comp_settings_length, data, size);
974 GST_ERROR ("invalid compression algorithm %d", algo);
984 *data_out = new_data;
985 *size_out = new_size;
992 gst_matroska_decode_data (GArray * encodings, guint8 ** data_out,
993 guint * size_out, GstMatroskaTrackEncodingScope scope, gboolean free)
1000 g_return_val_if_fail (encodings != NULL, FALSE);
1001 g_return_val_if_fail (data_out != NULL && *data_out != NULL, FALSE);
1002 g_return_val_if_fail (size_out != NULL, FALSE);
1007 for (i = 0; i < encodings->len; i++) {
1008 GstMatroskaTrackEncoding *enc =
1009 &g_array_index (encodings, GstMatroskaTrackEncoding, i);
1010 guint8 *new_data = NULL;
1013 if ((enc->scope & scope) == 0)
1016 /* Encryption not supported yet */
1017 if (enc->type != 0) {
1026 gst_matroska_decompress_data (enc, &new_data, &new_size,
1032 if ((data == *data_out && free) || (data != *data_out))
1040 if ((data == *data_out && free) || (data != *data_out))
1054 gst_matroska_decode_buffer (GstMatroskaTrackContext * context, GstBuffer * buf)
1060 g_return_val_if_fail (GST_IS_BUFFER (buf), NULL);
1062 GST_DEBUG ("decoding buffer %p", buf);
1064 data = GST_BUFFER_DATA (buf);
1065 size = GST_BUFFER_SIZE (buf);
1067 g_return_val_if_fail (data != NULL && size > 0, buf);
1069 if (gst_matroska_decode_data (context->encodings, &data, &size,
1070 GST_MATROSKA_TRACK_ENCODING_SCOPE_FRAME, FALSE)) {
1071 new_buf = gst_buffer_new ();
1072 GST_BUFFER_MALLOCDATA (new_buf) = (guint8 *) data;
1073 GST_BUFFER_DATA (new_buf) = (guint8 *) data;
1074 GST_BUFFER_SIZE (new_buf) = size;
1076 gst_buffer_unref (buf);
1081 GST_DEBUG ("decode data failed");
1082 gst_buffer_unref (buf);
1087 static GstFlowReturn
1088 gst_matroska_decode_content_encodings (GArray * encodings)
1092 if (encodings == NULL)
1095 for (i = 0; i < encodings->len; i++) {
1096 GstMatroskaTrackEncoding *enc =
1097 &g_array_index (encodings, GstMatroskaTrackEncoding, i);
1098 GstMatroskaTrackEncoding *enc2;
1099 guint8 *data = NULL;
1102 if ((enc->scope & GST_MATROSKA_TRACK_ENCODING_SCOPE_NEXT_CONTENT_ENCODING)
1106 /* Encryption not supported yet */
1108 return GST_FLOW_ERROR;
1110 if (i + 1 >= encodings->len)
1111 return GST_FLOW_ERROR;
1113 enc2 = &g_array_index (encodings, GstMatroskaTrackEncoding, i + 1);
1115 if (enc->comp_settings_length == 0)
1118 data = enc->comp_settings;
1119 size = enc->comp_settings_length;
1121 if (!gst_matroska_decompress_data (enc, &data, &size, enc->comp_algo))
1122 return GST_FLOW_ERROR;
1124 g_free (enc->comp_settings);
1126 enc->comp_settings = data;
1127 enc->comp_settings_length = size;
1133 static GstFlowReturn
1134 gst_matroska_demux_read_track_encodings (GstMatroskaDemux * demux,
1135 GstEbmlRead * ebml, GstMatroskaTrackContext * context)
1140 DEBUG_ELEMENT_START (demux, ebml, "ContentEncodings");
1142 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
1143 DEBUG_ELEMENT_STOP (demux, ebml, "ContentEncodings", ret);
1147 context->encodings =
1148 g_array_sized_new (FALSE, FALSE, sizeof (GstMatroskaTrackEncoding), 1);
1150 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1151 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1155 case GST_MATROSKA_ID_CONTENTENCODING:
1156 ret = gst_matroska_demux_read_track_encoding (demux, ebml, context);
1159 GST_WARNING_OBJECT (demux,
1160 "Unknown ContentEncodings subelement 0x%x - ignoring", id);
1161 ret = gst_ebml_read_skip (ebml);
1166 DEBUG_ELEMENT_STOP (demux, ebml, "ContentEncodings", ret);
1167 if (ret != GST_FLOW_OK && ret != GST_FLOW_UNEXPECTED)
1170 /* Sort encodings according to their order */
1171 g_array_sort (context->encodings,
1172 (GCompareFunc) gst_matroska_demux_encoding_cmp);
1174 return gst_matroska_decode_content_encodings (context->encodings);
1178 gst_matroska_demux_tracknumber_unique (GstMatroskaDemux * demux, guint64 num)
1182 g_assert (demux->src->len == demux->num_streams);
1183 for (i = 0; i < demux->src->len; i++) {
1184 GstMatroskaTrackContext *context = g_ptr_array_index (demux->src, i);
1186 if (context->num == num)
1193 static GstFlowReturn
1194 gst_matroska_demux_add_stream (GstMatroskaDemux * demux, GstEbmlRead * ebml)
1196 GstElementClass *klass = GST_ELEMENT_GET_CLASS (demux);
1197 GstMatroskaTrackContext *context;
1198 GstPadTemplate *templ = NULL;
1199 GstCaps *caps = NULL;
1200 gchar *padname = NULL;
1202 guint32 id, riff_fourcc = 0;
1203 guint16 riff_audio_fmt = 0;
1204 GstTagList *list = NULL;
1205 gchar *codec = NULL;
1207 DEBUG_ELEMENT_START (demux, ebml, "TrackEntry");
1209 /* start with the master */
1210 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
1211 DEBUG_ELEMENT_STOP (demux, ebml, "TrackEntry", ret);
1215 /* allocate generic... if we know the type, we'll g_renew()
1216 * with the precise type */
1217 context = g_new0 (GstMatroskaTrackContext, 1);
1218 g_ptr_array_add (demux->src, context);
1219 context->index = demux->num_streams;
1220 context->index_writer_id = -1;
1221 context->type = 0; /* no type yet */
1222 context->default_duration = 0;
1224 #ifdef MKVDEMUX_MODIFICATION
1225 context->found_next_kframe = FALSE;
1227 context->set_discont = TRUE;
1228 context->timecodescale = 1.0;
1230 GST_MATROSKA_TRACK_ENABLED | GST_MATROSKA_TRACK_DEFAULT |
1231 GST_MATROSKA_TRACK_LACING;
1232 context->last_flow = GST_FLOW_OK;
1233 context->to_offset = G_MAXINT64;
1234 demux->num_streams++;
1235 g_assert (demux->src->len == demux->num_streams);
1237 #ifdef MKVDEMUX_MODIFICATION
1238 context->queue = g_queue_new ();
1239 context->found_key_frame = FALSE;
1240 context->last_ts = GST_CLOCK_TIME_NONE;
1241 context->avg_duration = GST_CLOCK_TIME_NONE;
1242 context->intra_gap = 0;
1245 GST_DEBUG_OBJECT (demux, "Stream number %d", context->index);
1247 /* try reading the trackentry headers */
1248 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1249 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1253 /* track number (unique stream ID) */
1254 case GST_MATROSKA_ID_TRACKNUMBER:{
1257 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1261 GST_ERROR_OBJECT (demux, "Invalid TrackNumber 0");
1262 ret = GST_FLOW_ERROR;
1264 } else if (!gst_matroska_demux_tracknumber_unique (demux, num)) {
1265 GST_ERROR_OBJECT (demux, "TrackNumber %" G_GUINT64_FORMAT
1266 " is not unique", num);
1267 ret = GST_FLOW_ERROR;
1271 GST_DEBUG_OBJECT (demux, "TrackNumber: %" G_GUINT64_FORMAT, num);
1275 /* track UID (unique identifier) */
1276 case GST_MATROSKA_ID_TRACKUID:{
1279 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1283 GST_ERROR_OBJECT (demux, "Invalid TrackUID 0");
1284 ret = GST_FLOW_ERROR;
1288 GST_DEBUG_OBJECT (demux, "TrackUID: %" G_GUINT64_FORMAT, num);
1293 /* track type (video, audio, combined, subtitle, etc.) */
1294 case GST_MATROSKA_ID_TRACKTYPE:{
1297 if ((ret = gst_ebml_read_uint (ebml, &id, &track_type)) != GST_FLOW_OK) {
1301 if (context->type != 0 && context->type != track_type) {
1302 GST_WARNING_OBJECT (demux,
1303 "More than one tracktype defined in a TrackEntry - skipping");
1305 } else if (track_type < 1 || track_type > 254) {
1306 GST_WARNING_OBJECT (demux, "Invalid TrackType %" G_GUINT64_FORMAT,
1311 GST_DEBUG_OBJECT (demux, "TrackType: %" G_GUINT64_FORMAT, track_type);
1313 /* ok, so we're actually going to reallocate this thing */
1314 switch (track_type) {
1315 case GST_MATROSKA_TRACK_TYPE_VIDEO:
1316 gst_matroska_track_init_video_context (&context);
1318 case GST_MATROSKA_TRACK_TYPE_AUDIO:
1319 gst_matroska_track_init_audio_context (&context);
1321 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
1322 gst_matroska_track_init_subtitle_context (&context);
1324 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1325 case GST_MATROSKA_TRACK_TYPE_LOGO:
1326 case GST_MATROSKA_TRACK_TYPE_BUTTONS:
1327 case GST_MATROSKA_TRACK_TYPE_CONTROL:
1329 GST_WARNING_OBJECT (demux,
1330 "Unknown or unsupported TrackType %" G_GUINT64_FORMAT,
1335 g_ptr_array_index (demux->src, demux->num_streams - 1) = context;
1339 /* tracktype specific stuff for video */
1340 case GST_MATROSKA_ID_TRACKVIDEO:{
1341 GstMatroskaTrackVideoContext *videocontext;
1343 DEBUG_ELEMENT_START (demux, ebml, "TrackVideo");
1345 if (!gst_matroska_track_init_video_context (&context)) {
1346 GST_WARNING_OBJECT (demux,
1347 "TrackVideo element in non-video track - ignoring track");
1348 ret = GST_FLOW_ERROR;
1350 } else if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
1353 videocontext = (GstMatroskaTrackVideoContext *) context;
1354 g_ptr_array_index (demux->src, demux->num_streams - 1) = context;
1356 while (ret == GST_FLOW_OK &&
1357 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1358 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1362 /* Should be one level up but some broken muxers write it here. */
1363 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
1366 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1370 GST_WARNING_OBJECT (demux, "Invalid TrackDefaultDuration 0");
1374 GST_DEBUG_OBJECT (demux,
1375 "TrackDefaultDuration: %" G_GUINT64_FORMAT, num);
1376 context->default_duration = num;
1380 /* video framerate */
1381 /* NOTE: This one is here only for backward compatibility.
1382 * Use _TRACKDEFAULDURATION one level up. */
1383 case GST_MATROSKA_ID_VIDEOFRAMERATE:{
1386 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
1390 GST_WARNING_OBJECT (demux, "Invalid TrackVideoFPS %lf", num);
1394 GST_DEBUG_OBJECT (demux, "TrackVideoFrameRate: %lf", num);
1395 if (context->default_duration == 0)
1396 context->default_duration =
1397 gst_gdouble_to_guint64 ((gdouble) GST_SECOND * (1.0 / num));
1398 videocontext->default_fps = num;
1402 /* width of the size to display the video at */
1403 case GST_MATROSKA_ID_VIDEODISPLAYWIDTH:{
1406 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1410 GST_WARNING_OBJECT (demux, "Invalid TrackVideoDisplayWidth 0");
1414 GST_DEBUG_OBJECT (demux,
1415 "TrackVideoDisplayWidth: %" G_GUINT64_FORMAT, num);
1416 videocontext->display_width = num;
1420 /* height of the size to display the video at */
1421 case GST_MATROSKA_ID_VIDEODISPLAYHEIGHT:{
1424 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1428 GST_WARNING_OBJECT (demux, "Invalid TrackVideoDisplayHeight 0");
1432 GST_DEBUG_OBJECT (demux,
1433 "TrackVideoDisplayHeight: %" G_GUINT64_FORMAT, num);
1434 videocontext->display_height = num;
1438 /* width of the video in the file */
1439 case GST_MATROSKA_ID_VIDEOPIXELWIDTH:{
1442 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1446 GST_WARNING_OBJECT (demux, "Invalid TrackVideoPixelWidth 0");
1450 GST_DEBUG_OBJECT (demux,
1451 "TrackVideoPixelWidth: %" G_GUINT64_FORMAT, num);
1452 videocontext->pixel_width = num;
1456 /* height of the video in the file */
1457 case GST_MATROSKA_ID_VIDEOPIXELHEIGHT:{
1460 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1464 GST_WARNING_OBJECT (demux, "Invalid TrackVideoPixelHeight 0");
1468 GST_DEBUG_OBJECT (demux,
1469 "TrackVideoPixelHeight: %" G_GUINT64_FORMAT, num);
1470 videocontext->pixel_height = num;
1474 /* whether the video is interlaced */
1475 case GST_MATROSKA_ID_VIDEOFLAGINTERLACED:{
1478 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1482 context->flags |= GST_MATROSKA_VIDEOTRACK_INTERLACED;
1484 context->flags &= ~GST_MATROSKA_VIDEOTRACK_INTERLACED;
1485 GST_DEBUG_OBJECT (demux, "TrackVideoInterlaced: %d",
1486 (context->flags & GST_MATROSKA_VIDEOTRACK_INTERLACED) ? 1 :
1491 /* aspect ratio behaviour */
1492 case GST_MATROSKA_ID_VIDEOASPECTRATIOTYPE:{
1495 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1498 if (num != GST_MATROSKA_ASPECT_RATIO_MODE_FREE &&
1499 num != GST_MATROSKA_ASPECT_RATIO_MODE_KEEP &&
1500 num != GST_MATROSKA_ASPECT_RATIO_MODE_FIXED) {
1501 GST_WARNING_OBJECT (demux,
1502 "Unknown TrackVideoAspectRatioType 0x%x", (guint) num);
1505 GST_DEBUG_OBJECT (demux,
1506 "TrackVideoAspectRatioType: %" G_GUINT64_FORMAT, num);
1507 videocontext->asr_mode = num;
1511 /* colourspace (only matters for raw video) fourcc */
1512 case GST_MATROSKA_ID_VIDEOCOLOURSPACE:{
1517 gst_ebml_read_binary (ebml, &id, &data,
1518 &datalen)) != GST_FLOW_OK)
1523 GST_WARNING_OBJECT (demux,
1524 "Invalid TrackVideoColourSpace length %" G_GUINT64_FORMAT,
1529 memcpy (&videocontext->fourcc, data, 4);
1530 GST_DEBUG_OBJECT (demux,
1531 "TrackVideoColourSpace: %" GST_FOURCC_FORMAT,
1532 GST_FOURCC_ARGS (videocontext->fourcc));
1538 GST_WARNING_OBJECT (demux,
1539 "Unknown TrackVideo subelement 0x%x - ignoring", id);
1541 case GST_MATROSKA_ID_VIDEOSTEREOMODE:
1542 case GST_MATROSKA_ID_VIDEODISPLAYUNIT:
1543 case GST_MATROSKA_ID_VIDEOPIXELCROPBOTTOM:
1544 case GST_MATROSKA_ID_VIDEOPIXELCROPTOP:
1545 case GST_MATROSKA_ID_VIDEOPIXELCROPLEFT:
1546 case GST_MATROSKA_ID_VIDEOPIXELCROPRIGHT:
1547 case GST_MATROSKA_ID_VIDEOGAMMAVALUE:
1548 ret = gst_ebml_read_skip (ebml);
1553 DEBUG_ELEMENT_STOP (demux, ebml, "TrackVideo", ret);
1557 /* tracktype specific stuff for audio */
1558 case GST_MATROSKA_ID_TRACKAUDIO:{
1559 GstMatroskaTrackAudioContext *audiocontext;
1561 DEBUG_ELEMENT_START (demux, ebml, "TrackAudio");
1563 if (!gst_matroska_track_init_audio_context (&context)) {
1564 GST_WARNING_OBJECT (demux,
1565 "TrackAudio element in non-audio track - ignoring track");
1566 ret = GST_FLOW_ERROR;
1570 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
1573 audiocontext = (GstMatroskaTrackAudioContext *) context;
1574 g_ptr_array_index (demux->src, demux->num_streams - 1) = context;
1576 while (ret == GST_FLOW_OK &&
1577 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1578 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1583 case GST_MATROSKA_ID_AUDIOSAMPLINGFREQ:{
1586 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
1591 GST_WARNING_OBJECT (demux,
1592 "Invalid TrackAudioSamplingFrequency %lf", num);
1596 GST_DEBUG_OBJECT (demux, "TrackAudioSamplingFrequency: %lf", num);
1597 audiocontext->samplerate = num;
1602 case GST_MATROSKA_ID_AUDIOBITDEPTH:{
1605 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1609 GST_WARNING_OBJECT (demux, "Invalid TrackAudioBitDepth 0");
1613 GST_DEBUG_OBJECT (demux, "TrackAudioBitDepth: %" G_GUINT64_FORMAT,
1615 audiocontext->bitdepth = num;
1620 case GST_MATROSKA_ID_AUDIOCHANNELS:{
1623 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1627 GST_WARNING_OBJECT (demux, "Invalid TrackAudioChannels 0");
1631 GST_DEBUG_OBJECT (demux, "TrackAudioChannels: %" G_GUINT64_FORMAT,
1633 audiocontext->channels = num;
1638 GST_WARNING_OBJECT (demux,
1639 "Unknown TrackAudio subelement 0x%x - ignoring", id);
1641 case GST_MATROSKA_ID_AUDIOCHANNELPOSITIONS:
1642 case GST_MATROSKA_ID_AUDIOOUTPUTSAMPLINGFREQ:
1643 ret = gst_ebml_read_skip (ebml);
1648 DEBUG_ELEMENT_STOP (demux, ebml, "TrackAudio", ret);
1653 /* codec identifier */
1654 case GST_MATROSKA_ID_CODECID:{
1657 if ((ret = gst_ebml_read_ascii (ebml, &id, &text)) != GST_FLOW_OK)
1660 GST_DEBUG_OBJECT (demux, "CodecID: %s", GST_STR_NULL (text));
1661 context->codec_id = text;
1665 /* codec private data */
1666 case GST_MATROSKA_ID_CODECPRIVATE:{
1671 gst_ebml_read_binary (ebml, &id, &data, &size)) != GST_FLOW_OK)
1674 context->codec_priv = data;
1675 context->codec_priv_size = size;
1677 GST_DEBUG_OBJECT (demux, "CodecPrivate of size %" G_GUINT64_FORMAT,
1682 /* name of the codec */
1683 case GST_MATROSKA_ID_CODECNAME:{
1686 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1689 GST_DEBUG_OBJECT (demux, "CodecName: %s", GST_STR_NULL (text));
1690 context->codec_name = text;
1694 /* name of this track */
1695 case GST_MATROSKA_ID_TRACKNAME:{
1698 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1701 context->name = text;
1702 GST_DEBUG_OBJECT (demux, "TrackName: %s", GST_STR_NULL (text));
1706 /* language (matters for audio/subtitles, mostly) */
1707 case GST_MATROSKA_ID_TRACKLANGUAGE:{
1710 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1714 context->language = text;
1717 if (strlen (context->language) >= 4 && context->language[3] == '-')
1718 context->language[3] = '\0';
1720 GST_DEBUG_OBJECT (demux, "TrackLanguage: %s",
1721 GST_STR_NULL (context->language));
1725 /* whether this is actually used */
1726 case GST_MATROSKA_ID_TRACKFLAGENABLED:{
1729 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1733 context->flags |= GST_MATROSKA_TRACK_ENABLED;
1735 context->flags &= ~GST_MATROSKA_TRACK_ENABLED;
1737 GST_DEBUG_OBJECT (demux, "TrackEnabled: %d",
1738 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
1742 /* whether it's the default for this track type */
1743 case GST_MATROSKA_ID_TRACKFLAGDEFAULT:{
1746 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1750 context->flags |= GST_MATROSKA_TRACK_DEFAULT;
1752 context->flags &= ~GST_MATROSKA_TRACK_DEFAULT;
1754 GST_DEBUG_OBJECT (demux, "TrackDefault: %d",
1755 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
1759 /* whether the track must be used during playback */
1760 case GST_MATROSKA_ID_TRACKFLAGFORCED:{
1763 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1767 context->flags |= GST_MATROSKA_TRACK_FORCED;
1769 context->flags &= ~GST_MATROSKA_TRACK_FORCED;
1771 GST_DEBUG_OBJECT (demux, "TrackForced: %d",
1772 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
1776 /* lacing (like MPEG, where blocks don't end/start on frame
1778 case GST_MATROSKA_ID_TRACKFLAGLACING:{
1781 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1785 context->flags |= GST_MATROSKA_TRACK_LACING;
1787 context->flags &= ~GST_MATROSKA_TRACK_LACING;
1789 GST_DEBUG_OBJECT (demux, "TrackLacing: %d",
1790 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
1794 /* default length (in time) of one data block in this track */
1795 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
1798 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1803 GST_WARNING_OBJECT (demux, "Invalid TrackDefaultDuration 0");
1807 GST_DEBUG_OBJECT (demux, "TrackDefaultDuration: %" G_GUINT64_FORMAT,
1809 context->default_duration = num;
1813 case GST_MATROSKA_ID_CONTENTENCODINGS:{
1814 ret = gst_matroska_demux_read_track_encodings (demux, ebml, context);
1818 case GST_MATROSKA_ID_TRACKTIMECODESCALE:{
1821 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
1825 GST_WARNING_OBJECT (demux, "Invalid TrackTimeCodeScale %lf", num);
1829 GST_DEBUG_OBJECT (demux, "TrackTimeCodeScale: %lf", num);
1830 context->timecodescale = num;
1835 GST_WARNING ("Unknown TrackEntry subelement 0x%x - ignoring", id);
1838 /* we ignore these because they're nothing useful (i.e. crap)
1839 * or simply not implemented yet. */
1840 case GST_MATROSKA_ID_TRACKMINCACHE:
1841 case GST_MATROSKA_ID_TRACKMAXCACHE:
1842 case GST_MATROSKA_ID_MAXBLOCKADDITIONID:
1843 case GST_MATROSKA_ID_TRACKATTACHMENTLINK:
1844 case GST_MATROSKA_ID_TRACKOVERLAY:
1845 case GST_MATROSKA_ID_TRACKTRANSLATE:
1846 case GST_MATROSKA_ID_TRACKOFFSET:
1847 case GST_MATROSKA_ID_CODECSETTINGS:
1848 case GST_MATROSKA_ID_CODECINFOURL:
1849 case GST_MATROSKA_ID_CODECDOWNLOADURL:
1850 case GST_MATROSKA_ID_CODECDECODEALL:
1851 ret = gst_ebml_read_skip (ebml);
1856 DEBUG_ELEMENT_STOP (demux, ebml, "TrackEntry", ret);
1858 /* Decode codec private data if necessary */
1859 if (context->encodings && context->encodings->len > 0 && context->codec_priv
1860 && context->codec_priv_size > 0) {
1861 if (!gst_matroska_decode_data (context->encodings,
1862 &context->codec_priv, &context->codec_priv_size,
1863 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
1864 GST_WARNING_OBJECT (demux, "Decoding codec private data failed");
1865 ret = GST_FLOW_ERROR;
1869 if (context->type == 0 || context->codec_id == NULL || (ret != GST_FLOW_OK
1870 && ret != GST_FLOW_UNEXPECTED)) {
1871 if (ret == GST_FLOW_OK || ret == GST_FLOW_UNEXPECTED)
1872 GST_WARNING_OBJECT (ebml, "Unknown stream/codec in track entry header");
1874 demux->num_streams--;
1875 g_ptr_array_remove_index (demux->src, demux->num_streams);
1876 g_assert (demux->src->len == demux->num_streams);
1878 gst_matroska_track_free (context);
1884 /* now create the GStreamer connectivity */
1885 switch (context->type) {
1886 case GST_MATROSKA_TRACK_TYPE_VIDEO:{
1887 GstMatroskaTrackVideoContext *videocontext =
1888 (GstMatroskaTrackVideoContext *) context;
1890 padname = g_strdup_printf ("video_%02d", demux->num_v_streams++);
1891 templ = gst_element_class_get_pad_template (klass, "video_%02d");
1892 caps = gst_matroska_demux_video_caps (videocontext,
1893 context->codec_id, (guint8 *) context->codec_priv,
1894 context->codec_priv_size, &codec, &riff_fourcc);
1897 list = gst_tag_list_new ();
1898 gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
1899 GST_TAG_VIDEO_CODEC, codec, NULL);
1905 case GST_MATROSKA_TRACK_TYPE_AUDIO:{
1906 GstMatroskaTrackAudioContext *audiocontext =
1907 (GstMatroskaTrackAudioContext *) context;
1909 padname = g_strdup_printf ("audio_%02d", demux->num_a_streams++);
1910 templ = gst_element_class_get_pad_template (klass, "audio_%02d");
1911 caps = gst_matroska_demux_audio_caps (audiocontext,
1912 context->codec_id, context->codec_priv, context->codec_priv_size,
1913 &codec, &riff_audio_fmt);
1916 list = gst_tag_list_new ();
1917 gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
1918 GST_TAG_AUDIO_CODEC, codec, NULL);
1924 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:{
1925 GstMatroskaTrackSubtitleContext *subtitlecontext =
1926 (GstMatroskaTrackSubtitleContext *) context;
1928 padname = g_strdup_printf ("subtitle_%02d", demux->num_t_streams++);
1929 templ = gst_element_class_get_pad_template (klass, "subtitle_%02d");
1930 caps = gst_matroska_demux_subtitle_caps (subtitlecontext,
1931 context->codec_id, context->codec_priv, context->codec_priv_size);
1935 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1936 case GST_MATROSKA_TRACK_TYPE_LOGO:
1937 case GST_MATROSKA_TRACK_TYPE_BUTTONS:
1938 case GST_MATROSKA_TRACK_TYPE_CONTROL:
1940 /* we should already have quit by now */
1941 g_assert_not_reached ();
1944 if ((context->language == NULL || *context->language == '\0') &&
1945 (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO ||
1946 context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
1947 GST_LOG ("stream %d: language=eng (assuming default)", context->index);
1948 context->language = g_strdup ("eng");
1951 if (context->language) {
1955 list = gst_tag_list_new ();
1957 /* Matroska contains ISO 639-2B codes, we want ISO 639-1 */
1958 lang = gst_tag_get_language_code (context->language);
1959 gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
1960 GST_TAG_LANGUAGE_CODE, (lang) ? lang : context->language, NULL);
1964 GST_WARNING_OBJECT (demux, "could not determine caps for stream with "
1965 "codec_id='%s'", context->codec_id);
1966 switch (context->type) {
1967 case GST_MATROSKA_TRACK_TYPE_VIDEO:
1968 caps = gst_caps_new_simple ("video/x-unknown", NULL);
1970 case GST_MATROSKA_TRACK_TYPE_AUDIO:
1971 caps = gst_caps_new_simple ("audio/x-unknown", NULL);
1973 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
1974 caps = gst_caps_new_simple ("application/x-subtitle-unknown", NULL);
1976 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1978 caps = gst_caps_new_simple ("application/x-matroska-unknown", NULL);
1981 gst_caps_set_simple (caps, "codec-id", G_TYPE_STRING, context->codec_id,
1984 /* add any unrecognised riff fourcc / audio format, but after codec-id */
1985 if (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO && riff_audio_fmt != 0)
1986 gst_caps_set_simple (caps, "format", G_TYPE_INT, riff_audio_fmt, NULL);
1987 else if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO && riff_fourcc != 0)
1988 gst_caps_set_simple (caps, "fourcc", GST_TYPE_FOURCC, riff_fourcc, NULL);
1991 /* the pad in here */
1992 context->pad = gst_pad_new_from_template (templ, padname);
1993 context->caps = caps;
1995 gst_pad_set_event_function (context->pad,
1996 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_event));
1997 gst_pad_set_query_type_function (context->pad,
1998 GST_DEBUG_FUNCPTR (gst_matroska_demux_get_src_query_types));
1999 gst_pad_set_query_function (context->pad,
2000 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_query));
2002 GST_INFO_OBJECT (demux, "Adding pad '%s' with caps %" GST_PTR_FORMAT,
2005 context->pending_tags = list;
2007 gst_pad_set_element_private (context->pad, context);
2009 gst_pad_use_fixed_caps (context->pad);
2010 gst_pad_set_caps (context->pad, context->caps);
2011 gst_pad_set_active (context->pad, TRUE);
2012 gst_element_add_pad (GST_ELEMENT (demux), context->pad);
2016 #ifdef MKVDEMUX_MODIFICATION
2017 if (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO)
2018 demux->audio_stream = context;
2019 if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO)
2020 demux->video = TRUE;
2027 static const GstQueryType *
2028 gst_matroska_demux_get_src_query_types (GstPad * pad)
2030 static const GstQueryType query_types[] = {
2041 gst_matroska_demux_query (GstMatroskaDemux * demux, GstPad * pad,
2044 gboolean res = FALSE;
2045 GstMatroskaTrackContext *context = NULL;
2048 context = gst_pad_get_element_private (pad);
2051 switch (GST_QUERY_TYPE (query)) {
2052 case GST_QUERY_POSITION:
2056 gst_query_parse_position (query, &format, NULL);
2058 if (format == GST_FORMAT_TIME) {
2059 GST_OBJECT_LOCK (demux);
2061 gst_query_set_position (query, GST_FORMAT_TIME, context->pos);
2063 gst_query_set_position (query, GST_FORMAT_TIME,
2064 demux->segment.last_stop);
2065 GST_OBJECT_UNLOCK (demux);
2066 } else if (format == GST_FORMAT_DEFAULT && context
2067 && context->default_duration) {
2068 GST_OBJECT_LOCK (demux);
2069 gst_query_set_position (query, GST_FORMAT_DEFAULT,
2070 context->pos / context->default_duration);
2071 GST_OBJECT_UNLOCK (demux);
2073 GST_DEBUG_OBJECT (demux,
2074 "only position query in TIME and DEFAULT format is supported");
2080 case GST_QUERY_DURATION:
2084 gst_query_parse_duration (query, &format, NULL);
2086 if (format == GST_FORMAT_TIME) {
2087 GST_OBJECT_LOCK (demux);
2088 gst_query_set_duration (query, GST_FORMAT_TIME,
2089 demux->segment.duration);
2090 GST_OBJECT_UNLOCK (demux);
2091 } else if (format == GST_FORMAT_DEFAULT && context
2092 && context->default_duration) {
2093 GST_OBJECT_LOCK (demux);
2094 gst_query_set_duration (query, GST_FORMAT_DEFAULT,
2095 demux->segment.duration / context->default_duration);
2096 GST_OBJECT_UNLOCK (demux);
2098 GST_DEBUG_OBJECT (demux,
2099 "only duration query in TIME and DEFAULT format is supported");
2106 case GST_QUERY_SEEKING:
2110 gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
2111 if (fmt == GST_FORMAT_TIME) {
2114 if (demux->streaming) {
2115 /* assuming we'll be able to get an index ... */
2116 seekable = demux->seekable;
2118 seekable = ! !demux->index;
2121 gst_query_set_seeking (query, GST_FORMAT_TIME, seekable,
2122 0, demux->segment.duration);
2128 res = gst_pad_query_default (pad, query);
2136 gst_matroska_demux_element_query (GstElement * element, GstQuery * query)
2138 return gst_matroska_demux_query (GST_MATROSKA_DEMUX (element), NULL, query);
2142 gst_matroska_demux_handle_src_query (GstPad * pad, GstQuery * query)
2145 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (gst_pad_get_parent (pad));
2147 ret = gst_matroska_demux_query (demux, pad, query);
2149 gst_object_unref (demux);
2155 gst_matroska_index_seek_find (GstMatroskaIndex * i1, GstClockTime * time,
2158 if (i1->time < *time)
2160 else if (i1->time > *time)
2166 static GstMatroskaIndex *
2167 gst_matroskademux_do_index_seek (GstMatroskaDemux * demux,
2168 GstMatroskaTrackContext * track, gint64 seek_pos, gint64 segment_stop,
2171 GstMatroskaIndex *entry = NULL;
2174 if (!demux->index || !demux->index->len)
2177 /* find entry just before or at the requested position */
2178 if (track && track->index_table)
2179 index = track->index_table;
2181 index = demux->index;
2184 gst_util_array_binary_search (index->data, index->len,
2185 sizeof (GstMatroskaIndex),
2186 (GCompareDataFunc) gst_matroska_index_seek_find, GST_SEARCH_MODE_BEFORE,
2190 entry = &g_array_index (index, GstMatroskaIndex, 0);
2195 /* takes ownership of taglist */
2197 gst_matroska_demux_found_global_tag (GstMatroskaDemux * demux,
2198 GstTagList * taglist)
2200 if (demux->global_tags) {
2201 /* nothing sent yet, add to cache */
2202 gst_tag_list_insert (demux->global_tags, taglist, GST_TAG_MERGE_APPEND);
2203 gst_tag_list_free (taglist);
2205 /* hm, already sent, no need to cache and wait anymore */
2206 GST_DEBUG_OBJECT (demux, "Sending late global tags %" GST_PTR_FORMAT,
2208 gst_element_found_tags (GST_ELEMENT (demux), taglist);
2212 /* returns FALSE if there are no pads to deliver event to,
2213 * otherwise TRUE (whatever the outcome of event sending),
2214 * takes ownership of the passed event! */
2216 gst_matroska_demux_send_event (GstMatroskaDemux * demux, GstEvent * event)
2218 gboolean is_newsegment;
2219 gboolean ret = FALSE;
2222 g_return_val_if_fail (event != NULL, FALSE);
2224 GST_INFO_OBJECT (demux, "Sending event of type %s to all source pads",
2225 GST_EVENT_TYPE_NAME (event));
2227 is_newsegment = (GST_EVENT_TYPE (event) == GST_EVENT_NEWSEGMENT);
2229 g_assert (demux->src->len == demux->num_streams);
2230 for (i = 0; i < demux->src->len; i++) {
2231 GstMatroskaTrackContext *stream;
2233 stream = g_ptr_array_index (demux->src, i);
2234 gst_event_ref (event);
2235 gst_pad_push_event (stream->pad, event);
2238 /* FIXME: send global tags before stream tags */
2239 if (G_UNLIKELY (is_newsegment && stream->pending_tags != NULL)) {
2240 GST_DEBUG_OBJECT (demux, "Sending pending_tags %p for pad %s:%s : %"
2241 GST_PTR_FORMAT, stream->pending_tags,
2242 GST_DEBUG_PAD_NAME (stream->pad), stream->pending_tags);
2243 gst_element_found_tags_for_pad (GST_ELEMENT (demux), stream->pad,
2244 stream->pending_tags);
2245 stream->pending_tags = NULL;
2249 if (G_UNLIKELY (is_newsegment && demux->global_tags != NULL)) {
2250 gst_tag_list_add (demux->global_tags, GST_TAG_MERGE_REPLACE,
2251 GST_TAG_CONTAINER_FORMAT, "Matroska", NULL);
2252 GST_DEBUG_OBJECT (demux, "Sending global_tags %p : %" GST_PTR_FORMAT,
2253 demux->global_tags, demux->global_tags);
2254 gst_element_found_tags (GST_ELEMENT (demux), demux->global_tags);
2255 demux->global_tags = NULL;
2258 gst_event_unref (event);
2263 gst_matroska_demux_element_send_event (GstElement * element, GstEvent * event)
2265 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
2268 g_return_val_if_fail (event != NULL, FALSE);
2270 if (GST_EVENT_TYPE (event) == GST_EVENT_SEEK) {
2271 res = gst_matroska_demux_handle_seek_event (demux, NULL, event);
2273 GST_WARNING_OBJECT (demux, "Unhandled event of type %s",
2274 GST_EVENT_TYPE_NAME (event));
2277 gst_event_unref (event);
2281 #ifdef MKVDEMUX_MODIFICATION
2282 static GstMatroskaIndex *
2283 gst_matroskademux_get_next_index (GstMatroskaDemux * demux, GstMatroskaTrackContext * track, GstMatroskaIndex *entry)
2288 GstMatroskaIndex *tmp = NULL;
2290 /* find entry just before or at the requested position */
2291 if (track && track->index_table)
2292 index = track->index_table;
2294 index = demux->index;
2296 for (i=0; i < index->len; i++)
2298 tmp = &g_array_index (index, GstMatroskaIndex, i);
2299 if ((tmp->time == entry->time) && (tmp->pos == entry->pos))
2301 if ((index->len - i) == 1)
2303 GST_DEBUG_OBJECT (demux, "entry found in last index...returning last index");
2307 GST_DEBUG_OBJECT (demux, "Found entry at index = %d");
2309 tmp = &g_array_index (index, GstMatroskaIndex, i);
2318 /* determine track to seek in */
2319 static GstMatroskaTrackContext *
2320 gst_matroska_demux_get_seek_track (GstMatroskaDemux * demux,
2321 GstMatroskaTrackContext * track)
2325 if (track && track->type == GST_MATROSKA_TRACK_TYPE_VIDEO)
2328 for (i = 0; i < demux->src->len; i++) {
2329 GstMatroskaTrackContext *stream;
2331 stream = g_ptr_array_index (demux->src, i);
2332 if (stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO && stream->index_table)
2340 gst_matroska_demux_reset_streams (GstMatroskaDemux * demux, GstClockTime time,
2345 GST_DEBUG_OBJECT (demux, "resetting stream state");
2347 g_assert (demux->src->len == demux->num_streams);
2348 for (i = 0; i < demux->src->len; i++) {
2349 GstMatroskaTrackContext *context = g_ptr_array_index (demux->src, i);
2350 context->pos = time;
2351 context->set_discont = TRUE;
2352 context->eos = FALSE;
2353 context->from_time = GST_CLOCK_TIME_NONE;
2354 #ifdef MKVDEMUX_MODIFICATION
2355 context->found_next_kframe = FALSE;
2356 context->num_frames_bw_keyframes = 0;
2357 context->avg_duration_bw_keyframes = GST_CLOCK_TIME_NONE;
2358 context->frames_to_show_bw_keyframes = 0;
2359 context->prev_kframe_timestamp = GST_CLOCK_TIME_NONE;
2360 context->next_kframe_timestamp = GST_CLOCK_TIME_NONE;
2361 context->last_ts = GST_CLOCK_TIME_NONE;
2364 context->last_flow = GST_FLOW_OK;
2365 if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
2366 GstMatroskaTrackVideoContext *videocontext =
2367 (GstMatroskaTrackVideoContext *) context;
2368 /* demux object lock held by caller */
2369 videocontext->earliest_time = GST_CLOCK_TIME_NONE;
2375 gst_matroska_demux_move_to_entry (GstMatroskaDemux * demux,
2376 GstMatroskaIndex * entry, gboolean reset)
2380 GST_OBJECT_LOCK (demux);
2382 /* seek (relative to matroska segment) */
2383 /* position might be invalid; will error when streaming resumes ... */
2384 demux->offset = entry->pos + demux->ebml_segment_start;
2386 GST_DEBUG_OBJECT (demux, "Seeked to offset %" G_GUINT64_FORMAT ", block %d, "
2387 "time %" GST_TIME_FORMAT, entry->pos + demux->ebml_segment_start,
2388 entry->block, GST_TIME_ARGS (entry->time));
2390 /* update the time */
2391 gst_matroska_demux_reset_streams (demux, entry->time, TRUE);
2392 demux->segment.last_stop = entry->time;
2393 demux->seek_block = entry->block;
2394 demux->seek_first = TRUE;
2395 demux->last_stop_end = GST_CLOCK_TIME_NONE;
2397 for (i = 0; i < demux->src->len; i++) {
2398 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->src, i);
2401 stream->to_offset = G_MAXINT64;
2403 if (stream->from_offset != -1)
2404 stream->to_offset = stream->from_offset;
2406 stream->from_offset = -1;
2409 GST_OBJECT_UNLOCK (demux);
2415 gst_matroska_cluster_compare (gint64 * i1, gint64 * i2)
2425 /* searches for a cluster start from @pos,
2426 * return GST_FLOW_OK and cluster position in @pos if found */
2427 static GstFlowReturn
2428 gst_matroska_demux_search_cluster (GstMatroskaDemux * demux, gint64 * pos)
2430 gint64 newpos = *pos;
2432 GstFlowReturn ret = GST_FLOW_OK;
2433 const guint chunk = 64 * 1024;
2434 GstBuffer *buf = NULL;
2439 orig_offset = demux->offset;
2441 GST_LOG_OBJECT (demux, "searching cluster following offset %" G_GINT64_FORMAT,
2444 if (demux->clusters) {
2447 cpos = gst_util_array_binary_search (demux->clusters->data,
2448 demux->clusters->len, sizeof (gint64),
2449 (GCompareDataFunc) gst_matroska_cluster_compare,
2450 GST_SEARCH_MODE_AFTER, pos, NULL);
2453 GST_DEBUG_OBJECT (demux,
2454 "cluster reported at offset %" G_GINT64_FORMAT, *cpos);
2455 demux->offset = *cpos;
2457 gst_matroska_demux_peek_id_length_pull (demux, &id, &length, &needed);
2458 if (ret == GST_FLOW_OK && id == GST_MATROSKA_ID_CLUSTER) {
2465 /* read in at newpos and scan for ebml cluster id */
2467 GstByteReader reader;
2470 ret = gst_pad_pull_range (demux->sinkpad, newpos, chunk, &buf);
2471 if (ret != GST_FLOW_OK)
2473 GST_DEBUG_OBJECT (demux, "read buffer size %d at offset %" G_GINT64_FORMAT,
2474 GST_BUFFER_SIZE (buf), newpos);
2475 gst_byte_reader_init_from_buffer (&reader, buf);
2477 cluster_pos = gst_byte_reader_masked_scan_uint32 (&reader, 0xffffffff,
2478 GST_MATROSKA_ID_CLUSTER, 0, gst_byte_reader_get_remaining (&reader));
2479 if (cluster_pos >= 0) {
2480 newpos += cluster_pos;
2481 /* prepare resuming at next byte */
2482 gst_byte_reader_skip (&reader, cluster_pos + 1);
2483 GST_DEBUG_OBJECT (demux,
2484 "found cluster ebml id at offset %" G_GINT64_FORMAT, newpos);
2485 /* extra checks whether we really sync'ed to a cluster:
2486 * - either it is the first and only cluster
2487 * - either there is a cluster after this one
2488 * - either cluster length is undefined
2490 /* ok if first cluster (there may not a subsequent one) */
2491 if (newpos == demux->first_cluster_offset) {
2492 GST_DEBUG_OBJECT (demux, "cluster is first cluster -> OK");
2495 demux->offset = newpos;
2497 gst_matroska_demux_peek_id_length_pull (demux, &id, &length, &needed);
2498 if (ret != GST_FLOW_OK)
2500 g_assert (id == GST_MATROSKA_ID_CLUSTER);
2501 GST_DEBUG_OBJECT (demux, "cluster size %" G_GUINT64_FORMAT ", prefix %d",
2503 /* ok if undefined length or first cluster */
2504 if (length == G_MAXUINT64) {
2505 GST_DEBUG_OBJECT (demux, "cluster has undefined length -> OK");
2509 demux->offset += length + needed;
2511 gst_matroska_demux_peek_id_length_pull (demux, &id, &length, &needed);
2512 if (ret != GST_FLOW_OK)
2514 GST_DEBUG_OBJECT (demux, "next element is %scluster",
2515 id == GST_MATROSKA_ID_CLUSTER ? "" : "not ");
2516 if (id == GST_MATROSKA_ID_CLUSTER)
2518 /* not ok, resume */
2521 /* partial cluster id may have been in tail of buffer */
2522 newpos += MAX (gst_byte_reader_get_remaining (&reader), 4) - 3;
2523 gst_buffer_unref (buf);
2529 gst_buffer_unref (buf);
2534 demux->offset = orig_offset;
2539 /* bisect and scan through file for cluster starting before @time,
2540 * returns fake index entry with corresponding info on cluster */
2541 static GstMatroskaIndex *
2542 gst_matroska_demux_search_pos (GstMatroskaDemux * demux, GstClockTime time)
2544 GstMatroskaIndex *entry = NULL;
2545 GstMatroskaDemuxState current_state;
2546 GstClockTime otime, prev_cluster_time, current_cluster_time, cluster_time;
2547 gint64 opos, newpos, startpos = 0, current_offset;
2548 gint64 prev_cluster_offset = -1, current_cluster_offset, cluster_offset;
2549 const guint chunk = 64 * 1024;
2550 GstBuffer *buf = NULL;
2556 /* (under)estimate new position, resync using cluster ebml id,
2557 * and scan forward to appropriate cluster
2558 * (and re-estimate if need to go backward) */
2560 prev_cluster_time = GST_CLOCK_TIME_NONE;
2562 /* store some current state */
2563 current_state = demux->state;
2564 g_return_val_if_fail (current_state == GST_MATROSKA_DEMUX_STATE_DATA, NULL);
2566 current_cluster_offset = demux->cluster_offset;
2567 current_cluster_time = demux->cluster_time;
2568 current_offset = demux->offset;
2570 demux->state = GST_MATROSKA_DEMUX_STATE_SCANNING;
2572 /* estimate using start and current position */
2573 opos = demux->offset - demux->ebml_segment_start;
2574 otime = demux->segment.last_stop;
2577 GST_LOG_OBJECT (demux,
2578 "opos: %" G_GUINT64_FORMAT ", otime: %" GST_TIME_FORMAT, opos,
2579 GST_TIME_ARGS (otime));
2580 newpos = gst_util_uint64_scale (opos, time, otime) - chunk;
2583 /* favour undershoot */
2584 newpos = newpos * 90 / 100;
2585 newpos += demux->ebml_segment_start;
2587 GST_DEBUG_OBJECT (demux,
2588 "estimated offset for %" GST_TIME_FORMAT ": %" G_GINT64_FORMAT,
2589 GST_TIME_ARGS (time), newpos);
2591 /* and at least start scanning before previous scan start to avoid looping */
2592 startpos = startpos * 90 / 100;
2593 if (startpos && startpos < newpos)
2596 /* read in at newpos and scan for ebml cluster id */
2600 ret = gst_matroska_demux_search_cluster (demux, &newpos);
2601 if (ret == GST_FLOW_UNEXPECTED) {
2602 /* heuristic HACK */
2603 newpos = startpos * 80 / 100;
2604 GST_DEBUG_OBJECT (demux, "EOS; "
2605 "new estimated offset for %" GST_TIME_FORMAT ": %" G_GINT64_FORMAT,
2606 GST_TIME_ARGS (time), newpos);
2609 } else if (ret != GST_FLOW_OK) {
2616 /* then start scanning and parsing for cluster time,
2617 * re-estimate if overshoot, otherwise next cluster and so on */
2618 demux->offset = newpos;
2619 demux->cluster_time = cluster_time = GST_CLOCK_TIME_NONE;
2621 guint64 cluster_size = 0;
2623 /* peek and parse some elements */
2624 ret = gst_matroska_demux_peek_id_length_pull (demux, &id, &length, &needed);
2625 if (ret != GST_FLOW_OK)
2627 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
2628 "size %" G_GUINT64_FORMAT ", needed %d", demux->offset, id,
2630 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
2631 if (ret != GST_FLOW_OK)
2634 if (id == GST_MATROSKA_ID_CLUSTER) {
2635 cluster_time = GST_CLOCK_TIME_NONE;
2636 if (length == G_MAXUINT64)
2639 cluster_size = length + needed;
2641 if (demux->cluster_time != GST_CLOCK_TIME_NONE &&
2642 cluster_time == GST_CLOCK_TIME_NONE) {
2643 cluster_time = demux->cluster_time * demux->time_scale;
2644 cluster_offset = demux->cluster_offset;
2645 GST_DEBUG_OBJECT (demux, "found cluster at offset %" G_GINT64_FORMAT
2646 " with time %" GST_TIME_FORMAT, cluster_offset,
2647 GST_TIME_ARGS (cluster_time));
2648 if (cluster_time > time) {
2649 GST_DEBUG_OBJECT (demux, "overshot target");
2650 /* cluster overshoots */
2651 if (cluster_offset == demux->first_cluster_offset) {
2652 /* but no prev one */
2653 GST_DEBUG_OBJECT (demux, "but using first cluster anyway");
2654 prev_cluster_time = cluster_time;
2655 prev_cluster_offset = cluster_offset;
2658 if (prev_cluster_time != GST_CLOCK_TIME_NONE) {
2659 /* prev cluster did not overshoot, so prev cluster is target */
2662 /* re-estimate using this new position info */
2663 opos = cluster_offset;
2664 otime = cluster_time;
2668 /* cluster undershoots, goto next one */
2669 prev_cluster_time = cluster_time;
2670 prev_cluster_offset = cluster_offset;
2671 /* skip cluster if length is defined,
2672 * otherwise will be skippingly parsed into */
2674 GST_DEBUG_OBJECT (demux, "skipping to next cluster");
2675 demux->offset = cluster_offset + cluster_size;
2676 demux->cluster_time = GST_CLOCK_TIME_NONE;
2678 GST_DEBUG_OBJECT (demux, "parsing/skipping cluster elements");
2685 if (ret == GST_FLOW_UNEXPECTED) {
2686 if (prev_cluster_time != GST_CLOCK_TIME_NONE)
2692 entry = g_new0 (GstMatroskaIndex, 1);
2693 entry->time = prev_cluster_time;
2694 entry->pos = prev_cluster_offset - demux->ebml_segment_start;
2695 GST_DEBUG_OBJECT (demux, "simulated index entry; time %" GST_TIME_FORMAT
2696 ", pos %" G_GUINT64_FORMAT, GST_TIME_ARGS (entry->time), entry->pos);
2700 gst_buffer_unref (buf);
2702 /* restore some state */
2703 demux->cluster_offset = current_cluster_offset;
2704 demux->cluster_time = current_cluster_time;
2705 demux->offset = current_offset;
2706 demux->state = current_state;
2712 gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
2713 GstPad * pad, GstEvent * event)
2715 GstMatroskaIndex *entry = NULL;
2716 GstMatroskaIndex scan_entry;
2717 #ifdef MKVDEMUX_MODIFICATION
2718 GstMatroskaIndex *next_entry = NULL;
2721 GstSeekType cur_type, stop_type;
2723 gboolean flush, keyunit;
2727 GstMatroskaTrackContext *track = NULL;
2728 GstSegment seeksegment = { 0, };
2733 track = gst_pad_get_element_private (pad);
2735 //track = gst_matroska_demux_get_seek_track (demux, track);
2737 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
2740 /* we can only seek on time */
2741 if (format != GST_FORMAT_TIME) {
2742 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
2746 #ifndef MKVDEMUX_MODIFICATION
2747 /* cannot yet do backwards playback */
2749 GST_DEBUG_OBJECT (demux, "Can only seek with positive rate");
2753 /* copy segment, we need this because we still need the old
2754 * segment when we close the current segment. */
2755 memcpy (&seeksegment, &demux->segment, sizeof (GstSegment));
2758 GST_DEBUG_OBJECT (demux, "configuring seek");
2759 gst_segment_set_seek (&seeksegment, rate, format, flags,
2760 cur_type, cur, stop_type, stop, &update);
2763 GST_INFO_OBJECT (demux, "New segment %" GST_SEGMENT_FORMAT, &seeksegment);
2765 /* check sanity before we start flushing and all that */
2766 GST_OBJECT_LOCK (demux);
2769 gst_matroskademux_do_index_seek (demux, track,
2770 seeksegment.last_stop, -1, FALSE)) == NULL) {
2771 /* pull mode without index can scan later on */
2773 GST_INFO_OBJECT (demux, "No matching seek entry in index");
2774 GST_OBJECT_UNLOCK (demux);
2777 #ifdef MKVDEMUX_MODIFICATION
2778 if (seeksegment.rate < 0.0)
2780 next_entry = gst_matroskademux_get_next_index (demux, track, entry);
2781 if (next_entry == NULL)
2783 GST_ERROR ("Entry Not found....");
2788 GST_DEBUG_OBJECT (demux, "Seek position looks sane");
2789 GST_OBJECT_UNLOCK (demux);
2791 if (demux->streaming) {
2792 /* need to seek to cluster start to pick up cluster time */
2793 /* upstream takes care of flushing and all that
2794 * ... and newsegment event handling takes care of the rest */
2795 return perform_seek_to_offset (demux,
2796 entry->pos + demux->ebml_segment_start);
2799 flush = ! !(flags & GST_SEEK_FLAG_FLUSH);
2800 keyunit = ! !(flags & GST_SEEK_FLAG_KEY_UNIT);
2802 #ifdef MKVDEMUX_MODIFICATION
2803 keyunit = TRUE;//intentionally making it as true
2807 gst_pad_push_event (demux->sinkpad, gst_event_new_flush_start ());
2808 gst_matroska_demux_send_event (demux, gst_event_new_flush_start ());
2810 gst_pad_pause_task (demux->sinkpad);
2813 /* now grab the stream lock so that streaming cannot continue, for
2814 * non flushing seeks when the element is in PAUSED this could block
2816 GST_INFO_OBJECT (demux, "Waiting for streaming to stop");
2817 GST_PAD_STREAM_LOCK (demux->sinkpad);
2819 if (!demux->streaming && !demux->index)
2823 GST_OBJECT_LOCK (demux);
2825 offset = entry->pos + demux->ebml_segment_start;
2826 if (offset >= gst_matroska_demux_get_length(demux))
2828 GST_INFO_OBJECT (demux, " Seek failed");
2831 demux->offset = offset;
2833 GST_OBJECT_UNLOCK (demux);
2838 GST_INFO_OBJECT (demux, "seek to key unit, adjusting segment start to %"
2839 GST_TIME_FORMAT, GST_TIME_ARGS (entry->time));
2840 #ifdef MKVDEMUX_MODIFICATION
2841 if (seeksegment.stop == -1)
2843 seeksegment.stop = seeksegment.duration;
2845 if (seeksegment.rate > 0.0)
2848 seeksegment.start = entry->time;
2849 seeksegment.last_stop = entry->time;
2850 seeksegment.time = entry->time;
2851 #ifdef MKVDEMUX_MODIFICATION
2853 else if (seeksegment.rate < 0.0) /* Reverse trick play */
2855 seeksegment.start = 0.0;
2856 seeksegment.stop = next_entry->time;
2857 seeksegment.last_stop = next_entry->time;
2858 seeksegment.time = 0.0;
2866 GST_DEBUG_OBJECT (demux, "Stopping flush");
2867 gst_pad_push_event (demux->sinkpad, gst_event_new_flush_stop ());
2868 gst_matroska_demux_send_event (demux, gst_event_new_flush_stop ());
2869 } else if (demux->segment_running) {
2870 GST_DEBUG_OBJECT (demux, "Closing currently running segment");
2872 GST_OBJECT_LOCK (demux);
2873 if (demux->close_segment)
2874 gst_event_unref (demux->close_segment);
2876 demux->close_segment = gst_event_new_new_segment (TRUE,
2877 demux->segment.rate, GST_FORMAT_TIME, demux->segment.start,
2878 demux->segment.last_stop, demux->segment.time);
2879 GST_OBJECT_UNLOCK (demux);
2882 GST_OBJECT_LOCK (demux);
2883 /* now update the real segment info */
2884 memcpy (&demux->segment, &seeksegment, sizeof (GstSegment));
2885 GST_OBJECT_UNLOCK (demux);
2887 /* update some (segment) state */
2888 if (!gst_matroska_demux_move_to_entry (demux, entry, TRUE))
2891 /* notify start of new segment */
2892 if (demux->segment.flags & GST_SEEK_FLAG_SEGMENT) {
2895 msg = gst_message_new_segment_start (GST_OBJECT (demux),
2896 GST_FORMAT_TIME, demux->segment.start);
2897 gst_element_post_message (GST_ELEMENT (demux), msg);
2900 GST_OBJECT_LOCK (demux);
2901 if (demux->new_segment)
2902 gst_event_unref (demux->new_segment);
2903 #ifdef MKVDEMUX_MODIFICATION
2904 if (demux->segment.rate > 0.0)
2907 demux->new_segment = gst_event_new_new_segment_full (FALSE,
2908 demux->segment.rate, demux->segment.applied_rate, demux->segment.format,
2909 demux->segment.last_stop, demux->segment.stop, demux->segment.time);
2910 #ifdef MKVDEMUX_MODIFICATION
2912 else if (demux->segment.rate < 0.0)
2914 /* Reverse trick play */
2915 demux->new_segment = gst_event_new_new_segment_full (FALSE,
2916 demux->segment.rate, demux->segment.applied_rate, demux->segment.format,
2917 demux->segment.start, demux->segment.last_stop, demux->segment.time);
2920 GST_OBJECT_UNLOCK (demux);
2922 /* update the time */
2923 g_assert (demux->src->len == demux->num_streams);
2924 for (i = 0; i < demux->src->len; i++) {
2925 GstMatroskaTrackContext *context = g_ptr_array_index (demux->src, i);
2926 context->pos = entry->time;
2927 context->set_discont = TRUE;
2928 context->last_flow = GST_FLOW_OK;
2929 context->eos = FALSE;
2931 #ifdef MKVDEMUX_MODIFICATION
2932 if (demux->segment.rate > 0.0)
2935 demux->segment.last_stop = entry->time;
2936 #ifdef MKVDEMUX_MODIFICATION
2938 else if (demux->segment.rate < 0.0)
2940 demux->segment.last_stop = next_entry->time;
2943 demux->seek_block = entry->block;
2944 demux->last_stop_end = GST_CLOCK_TIME_NONE;
2946 /* restart our task since it might have been stopped when we did the
2948 demux->segment_running = TRUE;
2949 gst_pad_start_task (demux->sinkpad, (GstTaskFunction) gst_matroska_demux_loop,
2952 #ifdef MKVDEMUX_MODIFICATION
2953 track->found_key_frame = FALSE;
2954 track->intra_gap = 0;
2955 while (!g_queue_is_empty (track->queue)) {
2956 GstBuffer* buf = g_queue_pop_head (track->queue);
2957 gst_buffer_unref (buf);
2961 /* streaming can continue now */
2962 GST_PAD_STREAM_UNLOCK (demux->sinkpad);
2968 GST_PAD_STREAM_UNLOCK (demux->sinkpad);
2969 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Got a seek error"));
2975 * Handle whether we can perform the seek event or if we have to let the chain
2976 * function handle seeks to build the seek indexes first.
2979 gst_matroska_demux_handle_seek_push (GstMatroskaDemux * demux, GstPad * pad,
2983 GstSeekType cur_type, stop_type;
2988 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
2993 /* we can only seek on time */
2994 if (format != GST_FORMAT_TIME) {
2995 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
2999 if (stop_type != GST_SEEK_TYPE_NONE && stop != GST_CLOCK_TIME_NONE) {
3000 GST_DEBUG_OBJECT (demux, "Seek end-time not supported in streaming mode");
3004 if (!(flags & GST_SEEK_FLAG_FLUSH)) {
3005 GST_DEBUG_OBJECT (demux,
3006 "Non-flushing seek not supported in streaming mode");
3010 if (flags & GST_SEEK_FLAG_SEGMENT) {
3011 GST_DEBUG_OBJECT (demux, "Segment seek not supported in streaming mode");
3015 /* check for having parsed index already */
3016 if (!demux->index_parsed) {
3017 gboolean building_index;
3020 if (!demux->index_offset) {
3021 GST_DEBUG_OBJECT (demux, "no index (location); no seek in push mode");
3025 GST_OBJECT_LOCK (demux);
3026 /* handle the seek event in the chain function */
3027 demux->state = GST_MATROSKA_DEMUX_STATE_SEEK;
3028 /* no more seek can be issued until state reset to _DATA */
3030 /* copy the event */
3031 if (demux->seek_event)
3032 gst_event_unref (demux->seek_event);
3033 demux->seek_event = gst_event_ref (event);
3035 /* set the building_index flag so that only one thread can setup the
3036 * structures for index seeking. */
3037 building_index = demux->building_index;
3038 if (!building_index) {
3039 demux->building_index = TRUE;
3040 offset = demux->index_offset;
3042 GST_OBJECT_UNLOCK (demux);
3044 if (!building_index) {
3045 /* seek to the first subindex or legacy index */
3046 GST_INFO_OBJECT (demux, "Seeking to Cues at %" G_GUINT64_FORMAT, offset);
3047 return perform_seek_to_offset (demux, offset);
3050 /* well, we are handling it already */
3054 /* delegate to tweaked regular seek */
3055 return gst_matroska_demux_handle_seek_event (demux, pad, event);
3059 gst_matroska_demux_handle_src_event (GstPad * pad, GstEvent * event)
3061 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (gst_pad_get_parent (pad));
3062 gboolean res = TRUE;
3064 switch (GST_EVENT_TYPE (event)) {
3065 case GST_EVENT_SEEK:
3066 /* no seeking until we are (safely) ready */
3067 if (demux->state != GST_MATROSKA_DEMUX_STATE_DATA) {
3068 GST_DEBUG_OBJECT (demux, "not ready for seeking yet");
3071 if (!demux->streaming)
3072 res = gst_matroska_demux_handle_seek_event (demux, pad, event);
3074 res = gst_matroska_demux_handle_seek_push (demux, pad, event);
3075 gst_event_unref (event);
3080 GstMatroskaTrackContext *context = gst_pad_get_element_private (pad);
3081 if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
3082 GstMatroskaTrackVideoContext *videocontext =
3083 (GstMatroskaTrackVideoContext *) context;
3085 GstClockTimeDiff diff;
3086 GstClockTime timestamp;
3088 gst_event_parse_qos (event, &proportion, &diff, ×tamp);
3090 GST_OBJECT_LOCK (demux);
3091 videocontext->earliest_time = timestamp + diff;
3092 GST_OBJECT_UNLOCK (demux);
3095 gst_event_unref (event);
3099 /* events we don't need to handle */
3100 case GST_EVENT_NAVIGATION:
3101 gst_event_unref (event);
3105 case GST_EVENT_LATENCY:
3107 res = gst_pad_push_event (demux->sinkpad, event);
3111 gst_object_unref (demux);
3116 static GstFlowReturn
3117 gst_matroska_demux_seek_to_previous_keyframe (GstMatroskaDemux * demux)
3119 GstFlowReturn ret = GST_FLOW_UNEXPECTED;
3120 gboolean done = TRUE;
3123 g_return_val_if_fail (demux->seek_index, GST_FLOW_UNEXPECTED);
3124 g_return_val_if_fail (demux->seek_entry < demux->seek_index->len,
3125 GST_FLOW_UNEXPECTED);
3127 GST_DEBUG_OBJECT (demux, "locating previous keyframe");
3129 if (!demux->seek_entry) {
3130 GST_DEBUG_OBJECT (demux, "no earlier index entry");
3134 for (i = 0; i < demux->src->len; i++) {
3135 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->src, i);
3137 GST_DEBUG_OBJECT (demux, "segment start %" GST_TIME_FORMAT
3138 ", stream %d at %" GST_TIME_FORMAT,
3139 GST_TIME_ARGS (demux->segment.start), stream->index,
3140 GST_TIME_ARGS (stream->from_time));
3141 if (GST_CLOCK_TIME_IS_VALID (stream->from_time)) {
3142 if (stream->from_time > demux->segment.start) {
3143 GST_DEBUG_OBJECT (demux, "stream %d not finished yet", stream->index);
3147 /* nothing pushed for this stream;
3148 * likely seek entry did not start at keyframe, so all was skipped.
3149 * So we need an earlier entry */
3155 GstMatroskaIndex *entry;
3157 entry = &g_array_index (demux->seek_index, GstMatroskaIndex,
3158 --demux->seek_entry);
3159 if (!gst_matroska_demux_move_to_entry (demux, entry, FALSE))
3169 /* skip unknown or alike element */
3170 static GstFlowReturn
3171 gst_matroska_demux_parse_skip (GstMatroskaDemux * demux, GstEbmlRead * ebml,
3172 const gchar * parent_name, guint id)
3174 if (id == GST_EBML_ID_VOID) {
3175 GST_DEBUG_OBJECT (demux, "Skipping EBML Void element");
3176 } else if (id == GST_EBML_ID_CRC32) {
3177 GST_DEBUG_OBJECT (demux, "Skipping EBML CRC32 element");
3179 GST_WARNING_OBJECT (demux,
3180 "Unknown %s subelement 0x%x - ignoring", parent_name, id);
3183 return gst_ebml_read_skip (ebml);
3186 static GstFlowReturn
3187 gst_matroska_demux_parse_header (GstMatroskaDemux * demux, GstEbmlRead * ebml)
3194 /* this function is the first to be called */
3200 ret = gst_ebml_peek_id (ebml, &id);
3201 if (ret != GST_FLOW_OK)
3204 GST_DEBUG_OBJECT (demux, "id: %08x", id);
3206 if (id != GST_EBML_ID_HEADER) {
3207 GST_ERROR_OBJECT (demux, "Failed to read header");
3211 ret = gst_ebml_read_master (ebml, &id);
3212 if (ret != GST_FLOW_OK)
3215 while (gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3216 ret = gst_ebml_peek_id (ebml, &id);
3217 if (ret != GST_FLOW_OK)
3221 /* is our read version uptodate? */
3222 case GST_EBML_ID_EBMLREADVERSION:{
3225 ret = gst_ebml_read_uint (ebml, &id, &num);
3226 if (ret != GST_FLOW_OK)
3228 if (num != GST_EBML_VERSION) {
3229 GST_ERROR_OBJECT (ebml, "Unsupported EBML version %" G_GUINT64_FORMAT,
3231 return GST_FLOW_ERROR;
3234 GST_DEBUG_OBJECT (ebml, "EbmlReadVersion: %" G_GUINT64_FORMAT, num);
3238 /* we only handle 8 byte lengths at max */
3239 case GST_EBML_ID_EBMLMAXSIZELENGTH:{
3242 ret = gst_ebml_read_uint (ebml, &id, &num);
3243 if (ret != GST_FLOW_OK)
3245 if (num > sizeof (guint64)) {
3246 GST_ERROR_OBJECT (ebml,
3247 "Unsupported EBML maximum size %" G_GUINT64_FORMAT, num);
3248 return GST_FLOW_ERROR;
3250 GST_DEBUG_OBJECT (ebml, "EbmlMaxSizeLength: %" G_GUINT64_FORMAT, num);
3254 /* we handle 4 byte IDs at max */
3255 case GST_EBML_ID_EBMLMAXIDLENGTH:{
3258 ret = gst_ebml_read_uint (ebml, &id, &num);
3259 if (ret != GST_FLOW_OK)
3261 if (num > sizeof (guint32)) {
3262 GST_ERROR_OBJECT (ebml,
3263 "Unsupported EBML maximum ID %" G_GUINT64_FORMAT, num);
3264 return GST_FLOW_ERROR;
3266 GST_DEBUG_OBJECT (ebml, "EbmlMaxIdLength: %" G_GUINT64_FORMAT, num);
3270 case GST_EBML_ID_DOCTYPE:{
3273 ret = gst_ebml_read_ascii (ebml, &id, &text);
3274 if (ret != GST_FLOW_OK)
3277 GST_DEBUG_OBJECT (ebml, "EbmlDocType: %s", GST_STR_NULL (text));
3285 case GST_EBML_ID_DOCTYPEREADVERSION:{
3288 ret = gst_ebml_read_uint (ebml, &id, &num);
3289 if (ret != GST_FLOW_OK)
3292 GST_DEBUG_OBJECT (ebml, "EbmlReadVersion: %" G_GUINT64_FORMAT, num);
3297 ret = gst_matroska_demux_parse_skip (demux, ebml, "EBML header", id);
3298 if (ret != GST_FLOW_OK)
3302 /* we ignore these two, as they don't tell us anything we care about */
3303 case GST_EBML_ID_EBMLVERSION:
3304 case GST_EBML_ID_DOCTYPEVERSION:
3305 ret = gst_ebml_read_skip (ebml);
3306 if (ret != GST_FLOW_OK)
3314 if ((doctype != NULL && !strcmp (doctype, GST_MATROSKA_DOCTYPE_MATROSKA)) ||
3315 (doctype != NULL && !strcmp (doctype, GST_MATROSKA_DOCTYPE_WEBM)) ||
3316 (doctype == NULL)) {
3319 GST_INFO_OBJECT (demux, "Input is %s version %d", doctype, version);
3321 GST_WARNING_OBJECT (demux, "Input is EBML without doctype, assuming "
3322 "matroska (version %d)", version);
3326 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
3327 ("Demuxer version (2) is too old to read %s version %d",
3328 GST_STR_NULL (doctype), version));
3329 ret = GST_FLOW_ERROR;
3333 GST_ELEMENT_ERROR (demux, STREAM, WRONG_TYPE, (NULL),
3334 ("Input is not a matroska stream (doctype=%s)", doctype));
3335 ret = GST_FLOW_ERROR;
3342 static GstFlowReturn
3343 gst_matroska_demux_parse_tracks (GstMatroskaDemux * demux, GstEbmlRead * ebml)
3345 GstFlowReturn ret = GST_FLOW_OK;
3348 DEBUG_ELEMENT_START (demux, ebml, "Tracks");
3350 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3351 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
3355 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3356 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3360 /* one track within the "all-tracks" header */
3361 case GST_MATROSKA_ID_TRACKENTRY:
3362 ret = gst_matroska_demux_add_stream (demux, ebml);
3366 ret = gst_matroska_demux_parse_skip (demux, ebml, "Track", id);
3370 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
3372 demux->tracks_parsed = TRUE;
3377 static GstFlowReturn
3378 gst_matroska_demux_parse_index_cuetrack (GstMatroskaDemux * demux,
3379 GstEbmlRead * ebml, guint * nentries)
3383 GstMatroskaIndex idx;
3385 idx.pos = (guint64) - 1;
3387 idx.time = GST_CLOCK_TIME_NONE;
3390 DEBUG_ELEMENT_START (demux, ebml, "CueTrackPositions");
3392 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3393 DEBUG_ELEMENT_STOP (demux, ebml, "CueTrackPositions", ret);
3397 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3398 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3403 case GST_MATROSKA_ID_CUETRACK:
3407 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
3412 GST_WARNING_OBJECT (demux, "Invalid CueTrack 0");
3416 GST_DEBUG_OBJECT (demux, "CueTrack: %" G_GUINT64_FORMAT, num);
3421 /* position in file */
3422 case GST_MATROSKA_ID_CUECLUSTERPOSITION:
3426 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
3429 if (num > G_MAXINT64) {
3430 GST_WARNING_OBJECT (demux, "CueClusterPosition %" G_GUINT64_FORMAT
3439 /* number of block in the cluster */
3440 case GST_MATROSKA_ID_CUEBLOCKNUMBER:
3444 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
3448 GST_WARNING_OBJECT (demux, "Invalid CueBlockNumber 0");
3452 GST_DEBUG_OBJECT (demux, "CueBlockNumber: %" G_GUINT64_FORMAT, num);
3455 /* mild sanity check, disregard strange cases ... */
3456 if (idx.block > G_MAXUINT16) {
3457 GST_DEBUG_OBJECT (demux, "... looks suspicious, ignoring");
3464 ret = gst_matroska_demux_parse_skip (demux, ebml, "CueTrackPositions",
3468 case GST_MATROSKA_ID_CUECODECSTATE:
3469 case GST_MATROSKA_ID_CUEREFERENCE:
3470 ret = gst_ebml_read_skip (ebml);
3475 DEBUG_ELEMENT_STOP (demux, ebml, "CueTrackPositions", ret);
3477 if ((ret == GST_FLOW_OK || ret == GST_FLOW_UNEXPECTED)
3478 && idx.pos != (guint64) - 1 && idx.track > 0) {
3479 g_array_append_val (demux->index, idx);
3481 } else if (ret == GST_FLOW_OK || ret == GST_FLOW_UNEXPECTED) {
3482 GST_DEBUG_OBJECT (demux, "CueTrackPositions without valid content");
3488 static GstFlowReturn
3489 gst_matroska_demux_parse_index_pointentry (GstMatroskaDemux * demux,
3494 GstClockTime time = GST_CLOCK_TIME_NONE;
3497 DEBUG_ELEMENT_START (demux, ebml, "CuePoint");
3499 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3500 DEBUG_ELEMENT_STOP (demux, ebml, "CuePoint", ret);
3504 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3505 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3509 /* one single index entry ('point') */
3510 case GST_MATROSKA_ID_CUETIME:
3512 if ((ret = gst_ebml_read_uint (ebml, &id, &time)) != GST_FLOW_OK)
3515 GST_DEBUG_OBJECT (demux, "CueTime: %" G_GUINT64_FORMAT, time);
3516 time = time * demux->time_scale;
3520 /* position in the file + track to which it belongs */
3521 case GST_MATROSKA_ID_CUETRACKPOSITIONS:
3524 gst_matroska_demux_parse_index_cuetrack (demux, ebml,
3525 &nentries)) != GST_FLOW_OK)
3531 ret = gst_matroska_demux_parse_skip (demux, ebml, "CuePoint", id);
3536 DEBUG_ELEMENT_STOP (demux, ebml, "CuePoint", ret);
3539 if (time == GST_CLOCK_TIME_NONE) {
3540 GST_WARNING_OBJECT (demux, "CuePoint without valid time");
3541 g_array_remove_range (demux->index, demux->index->len - nentries,
3546 for (i = demux->index->len - nentries; i < demux->index->len; i++) {
3547 GstMatroskaIndex *idx =
3548 &g_array_index (demux->index, GstMatroskaIndex, i);
3551 GST_DEBUG_OBJECT (demux, "Index entry: pos=%" G_GUINT64_FORMAT
3552 ", time=%" GST_TIME_FORMAT ", track=%u, block=%u", idx->pos,
3553 GST_TIME_ARGS (idx->time), (guint) idx->track, (guint) idx->block);
3557 GST_DEBUG_OBJECT (demux, "Empty CuePoint");
3564 gst_matroska_index_compare (GstMatroskaIndex * i1, GstMatroskaIndex * i2)
3566 if (i1->time < i2->time)
3568 else if (i1->time > i2->time)
3570 else if (i1->block < i2->block)
3572 else if (i1->block > i2->block)
3578 static GstFlowReturn
3579 gst_matroska_demux_parse_index (GstMatroskaDemux * demux, GstEbmlRead * ebml)
3582 GstFlowReturn ret = GST_FLOW_OK;
3586 g_array_free (demux->index, TRUE);
3588 g_array_sized_new (FALSE, FALSE, sizeof (GstMatroskaIndex), 128);
3590 DEBUG_ELEMENT_START (demux, ebml, "Cues");
3592 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3593 DEBUG_ELEMENT_STOP (demux, ebml, "Cues", ret);
3597 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3598 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3602 /* one single index entry ('point') */
3603 case GST_MATROSKA_ID_POINTENTRY:
3604 ret = gst_matroska_demux_parse_index_pointentry (demux, ebml);
3608 ret = gst_matroska_demux_parse_skip (demux, ebml, "Cues", id);
3612 DEBUG_ELEMENT_STOP (demux, ebml, "Cues", ret);
3614 /* Sort index by time, smallest time first, for easier searching */
3615 g_array_sort (demux->index, (GCompareFunc) gst_matroska_index_compare);
3617 /* Now sort the track specific index entries into their own arrays */
3618 for (i = 0; i < demux->index->len; i++) {
3619 GstMatroskaIndex *idx = &g_array_index (demux->index, GstMatroskaIndex, i);
3621 GstMatroskaTrackContext *ctx;
3623 if (demux->element_index) {
3626 if (idx->track != 0 &&
3628 gst_matroska_demux_stream_from_num (demux, idx->track)) != -1) {
3629 ctx = g_ptr_array_index (demux->src, track_num);
3631 if (ctx->index_writer_id == -1)
3632 gst_index_get_writer_id (demux->element_index, GST_OBJECT (ctx->pad),
3633 &ctx->index_writer_id);
3634 writer_id = ctx->index_writer_id;
3636 if (demux->element_index_writer_id == -1)
3637 gst_index_get_writer_id (demux->element_index, GST_OBJECT (demux),
3638 &demux->element_index_writer_id);
3639 writer_id = demux->element_index_writer_id;
3642 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
3643 G_GUINT64_FORMAT " for writer id %d", GST_TIME_ARGS (idx->time),
3644 idx->pos, writer_id);
3645 gst_index_add_association (demux->element_index, writer_id,
3646 GST_ASSOCIATION_FLAG_KEY_UNIT, GST_FORMAT_TIME, idx->time,
3647 GST_FORMAT_BYTES, idx->pos + demux->ebml_segment_start, NULL);
3650 if (idx->track == 0)
3653 track_num = gst_matroska_demux_stream_from_num (demux, idx->track);
3654 if (track_num == -1)
3657 ctx = g_ptr_array_index (demux->src, track_num);
3659 if (ctx->index_table == NULL)
3661 g_array_sized_new (FALSE, FALSE, sizeof (GstMatroskaIndex), 128);
3663 g_array_append_vals (ctx->index_table, idx, 1);
3666 demux->index_parsed = TRUE;
3668 /* sanity check; empty index normalizes to no index */
3669 if (demux->index->len == 0) {
3670 g_array_free (demux->index, TRUE);
3671 demux->index = NULL;
3677 static GstFlowReturn
3678 gst_matroska_demux_parse_info (GstMatroskaDemux * demux, GstEbmlRead * ebml)
3680 GstFlowReturn ret = GST_FLOW_OK;
3683 DEBUG_ELEMENT_START (demux, ebml, "SegmentInfo");
3685 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3686 DEBUG_ELEMENT_STOP (demux, ebml, "SegmentInfo", ret);
3690 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3691 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3695 /* cluster timecode */
3696 case GST_MATROSKA_ID_TIMECODESCALE:{
3699 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
3703 GST_DEBUG_OBJECT (demux, "TimeCodeScale: %" G_GUINT64_FORMAT, num);
3704 demux->time_scale = num;
3708 case GST_MATROSKA_ID_DURATION:{
3712 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
3716 GST_WARNING_OBJECT (demux, "Invalid duration %lf", num);
3720 GST_DEBUG_OBJECT (demux, "Duration: %lf", num);
3722 dur = gst_gdouble_to_guint64 (num *
3723 gst_guint64_to_gdouble (demux->time_scale));
3724 if (GST_CLOCK_TIME_IS_VALID (dur) && dur <= G_MAXINT64)
3726 demux->duration = dur;
3727 #ifdef MKVDEMUX_MODIFICATION
3728 gst_segment_set_duration (&demux->segment, GST_FORMAT_TIME, demux->duration);
3734 case GST_MATROSKA_ID_WRITINGAPP:{
3737 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
3740 GST_DEBUG_OBJECT (demux, "WritingApp: %s", GST_STR_NULL (text));
3741 demux->writing_app = text;
3745 case GST_MATROSKA_ID_MUXINGAPP:{
3748 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
3751 GST_DEBUG_OBJECT (demux, "MuxingApp: %s", GST_STR_NULL (text));
3752 demux->muxing_app = text;
3756 case GST_MATROSKA_ID_DATEUTC:{
3759 if ((ret = gst_ebml_read_date (ebml, &id, &time)) != GST_FLOW_OK)
3762 GST_DEBUG_OBJECT (demux, "DateUTC: %" G_GINT64_FORMAT, time);
3763 demux->created = time;
3767 case GST_MATROSKA_ID_TITLE:{
3769 GstTagList *taglist;
3771 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
3774 GST_DEBUG_OBJECT (demux, "Title: %s", GST_STR_NULL (text));
3775 taglist = gst_tag_list_new ();
3776 gst_tag_list_add (taglist, GST_TAG_MERGE_APPEND, GST_TAG_TITLE, text,
3778 gst_matroska_demux_found_global_tag (demux, taglist);
3784 ret = gst_matroska_demux_parse_skip (demux, ebml, "SegmentInfo", id);
3788 case GST_MATROSKA_ID_SEGMENTUID:
3789 case GST_MATROSKA_ID_SEGMENTFILENAME:
3790 case GST_MATROSKA_ID_PREVUID:
3791 case GST_MATROSKA_ID_PREVFILENAME:
3792 case GST_MATROSKA_ID_NEXTUID:
3793 case GST_MATROSKA_ID_NEXTFILENAME:
3794 case GST_MATROSKA_ID_SEGMENTFAMILY:
3795 case GST_MATROSKA_ID_CHAPTERTRANSLATE:
3796 ret = gst_ebml_read_skip (ebml);
3801 DEBUG_ELEMENT_STOP (demux, ebml, "SegmentInfo", ret);
3803 demux->segmentinfo_parsed = TRUE;
3808 static GstFlowReturn
3809 gst_matroska_demux_parse_metadata_id_simple_tag (GstMatroskaDemux * demux,
3810 GstEbmlRead * ebml, GstTagList ** p_taglist)
3812 /* FIXME: check if there are more useful mappings */
3815 const gchar *matroska_tagname;
3816 const gchar *gstreamer_tagname;
3820 GST_MATROSKA_TAG_ID_TITLE, GST_TAG_TITLE}, {
3821 GST_MATROSKA_TAG_ID_ARTIST, GST_TAG_ARTIST}, {
3822 GST_MATROSKA_TAG_ID_AUTHOR, GST_TAG_ARTIST}, {
3823 GST_MATROSKA_TAG_ID_ALBUM, GST_TAG_ALBUM}, {
3824 GST_MATROSKA_TAG_ID_COMMENTS, GST_TAG_COMMENT}, {
3825 GST_MATROSKA_TAG_ID_BITSPS, GST_TAG_BITRATE}, {
3826 GST_MATROSKA_TAG_ID_BPS, GST_TAG_BITRATE}, {
3827 GST_MATROSKA_TAG_ID_ENCODER, GST_TAG_ENCODER}, {
3828 GST_MATROSKA_TAG_ID_DATE, GST_TAG_DATE}, {
3829 GST_MATROSKA_TAG_ID_ISRC, GST_TAG_ISRC}, {
3830 GST_MATROSKA_TAG_ID_COPYRIGHT, GST_TAG_COPYRIGHT}, {
3831 GST_MATROSKA_TAG_ID_BPM, GST_TAG_BEATS_PER_MINUTE}, {
3832 GST_MATROSKA_TAG_ID_TERMS_OF_USE, GST_TAG_LICENSE}, {
3833 GST_MATROSKA_TAG_ID_COMPOSER, GST_TAG_COMPOSER}, {
3834 GST_MATROSKA_TAG_ID_LEAD_PERFORMER, GST_TAG_PERFORMER}, {
3835 GST_MATROSKA_TAG_ID_GENRE, GST_TAG_GENRE}
3839 gchar *value = NULL;
3842 DEBUG_ELEMENT_START (demux, ebml, "SimpleTag");
3844 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3845 DEBUG_ELEMENT_STOP (demux, ebml, "SimpleTag", ret);
3849 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3850 /* read all sub-entries */
3852 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3856 case GST_MATROSKA_ID_TAGNAME:
3859 ret = gst_ebml_read_ascii (ebml, &id, &tag);
3860 GST_DEBUG_OBJECT (demux, "TagName: %s", GST_STR_NULL (tag));
3863 case GST_MATROSKA_ID_TAGSTRING:
3866 ret = gst_ebml_read_utf8 (ebml, &id, &value);
3867 GST_DEBUG_OBJECT (demux, "TagString: %s", GST_STR_NULL (value));
3871 ret = gst_matroska_demux_parse_skip (demux, ebml, "SimpleTag", id);
3875 case GST_MATROSKA_ID_TAGLANGUAGE:
3876 case GST_MATROSKA_ID_TAGDEFAULT:
3877 case GST_MATROSKA_ID_TAGBINARY:
3878 ret = gst_ebml_read_skip (ebml);
3883 DEBUG_ELEMENT_STOP (demux, ebml, "SimpleTag", ret);
3888 for (i = 0; i < G_N_ELEMENTS (tag_conv); i++) {
3889 const gchar *tagname_gst = tag_conv[i].gstreamer_tagname;
3891 const gchar *tagname_mkv = tag_conv[i].matroska_tagname;
3893 if (strcmp (tagname_mkv, tag) == 0) {
3894 GValue dest = { 0, };
3895 GType dest_type = gst_tag_get_type (tagname_gst);
3897 /* Ensure that any date string is complete */
3898 if (dest_type == GST_TYPE_DATE) {
3899 guint year = 1901, month = 1, day = 1;
3901 /* Dates can be yyyy-MM-dd, yyyy-MM or yyyy, but we need
3903 if (sscanf (value, "%04u-%02u-%02u", &year, &month, &day) != 0) {
3905 value = g_strdup_printf ("%04u-%02u-%02u", year, month, day);
3909 g_value_init (&dest, dest_type);
3910 if (gst_value_deserialize (&dest, value)) {
3911 gst_tag_list_add_values (*p_taglist, GST_TAG_MERGE_APPEND,
3912 tagname_gst, &dest, NULL);
3914 GST_WARNING_OBJECT (demux, "Can't transform tag '%s' with "
3915 "value '%s' to target type '%s'", tag, value,
3916 g_type_name (dest_type));
3918 g_value_unset (&dest);
3930 static GstFlowReturn
3931 gst_matroska_demux_parse_metadata_id_tag (GstMatroskaDemux * demux,
3932 GstEbmlRead * ebml, GstTagList ** p_taglist)
3937 DEBUG_ELEMENT_START (demux, ebml, "Tag");
3939 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3940 DEBUG_ELEMENT_STOP (demux, ebml, "Tag", ret);
3944 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3945 /* read all sub-entries */
3947 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3951 case GST_MATROSKA_ID_SIMPLETAG:
3952 ret = gst_matroska_demux_parse_metadata_id_simple_tag (demux, ebml,
3957 ret = gst_matroska_demux_parse_skip (demux, ebml, "Tag", id);
3962 DEBUG_ELEMENT_STOP (demux, ebml, "Tag", ret);
3967 static GstFlowReturn
3968 gst_matroska_demux_parse_metadata (GstMatroskaDemux * demux, GstEbmlRead * ebml)
3970 GstTagList *taglist;
3971 GstFlowReturn ret = GST_FLOW_OK;
3976 curpos = gst_ebml_read_get_pos (ebml);
3978 /* Make sure we don't parse a tags element twice and
3979 * post it's tags twice */
3980 curpos = gst_ebml_read_get_pos (ebml);
3981 for (l = demux->tags_parsed; l; l = l->next) {
3982 guint64 *pos = l->data;
3984 if (*pos == curpos) {
3985 GST_DEBUG_OBJECT (demux, "Skipping already parsed Tags at offset %"
3986 G_GUINT64_FORMAT, curpos);
3991 demux->tags_parsed =
3992 g_list_prepend (demux->tags_parsed, g_slice_new (guint64));
3993 *((guint64 *) demux->tags_parsed->data) = curpos;
3996 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3997 DEBUG_ELEMENT_STOP (demux, ebml, "Tags", ret);
4001 taglist = gst_tag_list_new ();
4003 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
4004 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
4008 case GST_MATROSKA_ID_TAG:
4009 ret = gst_matroska_demux_parse_metadata_id_tag (demux, ebml, &taglist);
4013 ret = gst_matroska_demux_parse_skip (demux, ebml, "Tags", id);
4015 /* FIXME: Use to limit the tags to specific pads */
4016 case GST_MATROSKA_ID_TARGETS:
4017 ret = gst_ebml_read_skip (ebml);
4022 DEBUG_ELEMENT_STOP (demux, ebml, "Tags", ret);
4024 gst_matroska_demux_found_global_tag (demux, taglist);
4029 static GstFlowReturn
4030 gst_matroska_demux_parse_attached_file (GstMatroskaDemux * demux,
4031 GstEbmlRead * ebml, GstTagList * taglist)
4035 gchar *description = NULL;
4036 gchar *filename = NULL;
4037 gchar *mimetype = NULL;
4038 guint8 *data = NULL;
4039 guint64 datalen = 0;
4041 DEBUG_ELEMENT_START (demux, ebml, "AttachedFile");
4043 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
4044 DEBUG_ELEMENT_STOP (demux, ebml, "AttachedFile", ret);
4048 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
4049 /* read all sub-entries */
4051 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
4055 case GST_MATROSKA_ID_FILEDESCRIPTION:
4057 GST_WARNING_OBJECT (demux, "FileDescription can only appear once");
4061 ret = gst_ebml_read_utf8 (ebml, &id, &description);
4062 GST_DEBUG_OBJECT (demux, "FileDescription: %s",
4063 GST_STR_NULL (description));
4065 case GST_MATROSKA_ID_FILENAME:
4067 GST_WARNING_OBJECT (demux, "FileName can only appear once");
4071 ret = gst_ebml_read_utf8 (ebml, &id, &filename);
4073 GST_DEBUG_OBJECT (demux, "FileName: %s", GST_STR_NULL (filename));
4075 case GST_MATROSKA_ID_FILEMIMETYPE:
4077 GST_WARNING_OBJECT (demux, "FileMimeType can only appear once");
4081 ret = gst_ebml_read_ascii (ebml, &id, &mimetype);
4082 GST_DEBUG_OBJECT (demux, "FileMimeType: %s", GST_STR_NULL (mimetype));
4084 case GST_MATROSKA_ID_FILEDATA:
4086 GST_WARNING_OBJECT (demux, "FileData can only appear once");
4090 ret = gst_ebml_read_binary (ebml, &id, &data, &datalen);
4091 GST_DEBUG_OBJECT (demux, "FileData of size %" G_GUINT64_FORMAT,
4096 ret = gst_matroska_demux_parse_skip (demux, ebml, "AttachedFile", id);
4098 case GST_MATROSKA_ID_FILEUID:
4099 ret = gst_ebml_read_skip (ebml);
4104 DEBUG_ELEMENT_STOP (demux, ebml, "AttachedFile", ret);
4106 if (filename && mimetype && data && datalen > 0) {
4107 GstTagImageType image_type = GST_TAG_IMAGE_TYPE_NONE;
4108 GstBuffer *tagbuffer = NULL;
4110 gchar *filename_lc = g_utf8_strdown (filename, -1);
4112 GST_DEBUG_OBJECT (demux, "Creating tag for attachment with filename '%s', "
4113 "mimetype '%s', description '%s', size %" G_GUINT64_FORMAT, filename,
4114 mimetype, GST_STR_NULL (description), datalen);
4116 /* TODO: better heuristics for different image types */
4117 if (strstr (filename_lc, "cover")) {
4118 if (strstr (filename_lc, "back"))
4119 image_type = GST_TAG_IMAGE_TYPE_BACK_COVER;
4121 image_type = GST_TAG_IMAGE_TYPE_FRONT_COVER;
4122 } else if (g_str_has_prefix (mimetype, "image/") ||
4123 g_str_has_suffix (filename_lc, "png") ||
4124 g_str_has_suffix (filename_lc, "jpg") ||
4125 g_str_has_suffix (filename_lc, "jpeg") ||
4126 g_str_has_suffix (filename_lc, "gif") ||
4127 g_str_has_suffix (filename_lc, "bmp")) {
4128 image_type = GST_TAG_IMAGE_TYPE_UNDEFINED;
4130 g_free (filename_lc);
4132 /* First try to create an image tag buffer from this */
4133 if (image_type != GST_TAG_IMAGE_TYPE_NONE) {
4135 gst_tag_image_data_to_image_buffer (data, datalen, image_type);
4138 image_type = GST_TAG_IMAGE_TYPE_NONE;
4141 /* if this failed create an attachment buffer */
4143 tagbuffer = gst_buffer_new_and_alloc (datalen);
4145 memcpy (GST_BUFFER_DATA (tagbuffer), data, datalen);
4146 GST_BUFFER_SIZE (tagbuffer) = datalen;
4148 caps = gst_type_find_helper_for_buffer (NULL, tagbuffer, NULL);
4150 caps = gst_caps_new_simple (mimetype, NULL);
4151 gst_buffer_set_caps (tagbuffer, caps);
4152 gst_caps_unref (caps);
4155 /* Set filename and description on the caps */
4156 caps = GST_BUFFER_CAPS (tagbuffer);
4157 gst_caps_set_simple (caps, "filename", G_TYPE_STRING, filename, NULL);
4159 gst_caps_set_simple (caps, "description", G_TYPE_STRING, description,
4162 GST_DEBUG_OBJECT (demux,
4163 "Created attachment buffer with caps: %" GST_PTR_FORMAT, caps);
4165 /* and append to the tag list */
4166 if (image_type != GST_TAG_IMAGE_TYPE_NONE)
4167 gst_tag_list_add (taglist, GST_TAG_MERGE_APPEND, GST_TAG_IMAGE, tagbuffer,
4170 gst_tag_list_add (taglist, GST_TAG_MERGE_APPEND, GST_TAG_ATTACHMENT,
4177 g_free (description);
4182 static GstFlowReturn
4183 gst_matroska_demux_parse_attachments (GstMatroskaDemux * demux,
4187 GstFlowReturn ret = GST_FLOW_OK;
4188 GstTagList *taglist;
4190 DEBUG_ELEMENT_START (demux, ebml, "Attachments");
4192 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
4193 DEBUG_ELEMENT_STOP (demux, ebml, "Attachments", ret);
4197 taglist = gst_tag_list_new ();
4199 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
4200 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
4204 case GST_MATROSKA_ID_ATTACHEDFILE:
4205 ret = gst_matroska_demux_parse_attached_file (demux, ebml, taglist);
4209 ret = gst_matroska_demux_parse_skip (demux, ebml, "Attachments", id);
4213 DEBUG_ELEMENT_STOP (demux, ebml, "Attachments", ret);
4215 if (gst_structure_n_fields (GST_STRUCTURE (taglist)) > 0) {
4216 GST_DEBUG_OBJECT (demux, "Storing attachment tags");
4217 gst_matroska_demux_found_global_tag (demux, taglist);
4219 GST_DEBUG_OBJECT (demux, "No valid attachments found");
4220 gst_tag_list_free (taglist);
4223 demux->attachments_parsed = TRUE;
4228 static GstFlowReturn
4229 gst_matroska_demux_parse_chapters (GstMatroskaDemux * demux, GstEbmlRead * ebml)
4232 GstFlowReturn ret = GST_FLOW_OK;
4234 GST_WARNING_OBJECT (demux, "Parsing of chapters not implemented yet");
4236 /* TODO: implement parsing of chapters */
4238 DEBUG_ELEMENT_START (demux, ebml, "Chapters");
4240 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
4241 DEBUG_ELEMENT_STOP (demux, ebml, "Chapters", ret);
4245 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
4246 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
4251 ret = gst_ebml_read_skip (ebml);
4256 DEBUG_ELEMENT_STOP (demux, ebml, "Chapters", ret);
4261 * Read signed/unsigned "EBML" numbers.
4262 * Return: number of bytes processed.
4266 gst_matroska_ebmlnum_uint (guint8 * data, guint size, guint64 * num)
4268 gint len_mask = 0x80, read = 1, n = 1, num_ffs = 0;
4276 while (read <= 8 && !(total & len_mask)) {
4283 if ((total &= (len_mask - 1)) == len_mask - 1)
4288 if (data[n] == 0xff)
4290 total = (total << 8) | data[n];
4294 if (read == num_ffs && total != 0)
4303 gst_matroska_ebmlnum_sint (guint8 * data, guint size, gint64 * num)
4308 /* read as unsigned number first */
4309 if ((res = gst_matroska_ebmlnum_uint (data, size, &unum)) < 0)
4313 if (unum == G_MAXUINT64)
4316 *num = unum - ((1 << ((7 * res) - 1)) - 1);
4322 * Mostly used for subtitles. We add void filler data for each
4323 * lagging stream to make sure we don't deadlock.
4327 gst_matroska_demux_sync_streams (GstMatroskaDemux * demux)
4331 GST_LOG_OBJECT (demux, "Sync to %" GST_TIME_FORMAT,
4332 GST_TIME_ARGS (demux->segment.last_stop));
4334 g_assert (demux->num_streams == demux->src->len);
4335 for (stream_nr = 0; stream_nr < demux->src->len; stream_nr++) {
4336 GstMatroskaTrackContext *context;
4338 context = g_ptr_array_index (demux->src, stream_nr);
4340 GST_LOG_OBJECT (demux,
4341 "Checking for resync on stream %d (%" GST_TIME_FORMAT ")", stream_nr,
4342 GST_TIME_ARGS (context->pos));
4344 if (G_LIKELY (context->type != GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
4345 GST_LOG_OBJECT (demux, "Skipping sync on non-subtitle stream");
4348 #ifndef MKVDEMUX_MODIFICATION
4349 /* does it lag? 0.5 seconds is a random threshold...
4350 * lag need only be considered if we have advanced into requested segment */
4351 if (GST_CLOCK_TIME_IS_VALID (context->pos) &&
4352 GST_CLOCK_TIME_IS_VALID (demux->segment.last_stop) &&
4353 demux->segment.last_stop > demux->segment.start &&
4354 context->pos + (GST_SECOND / 2) < demux->segment.last_stop) {
4357 new_start = demux->segment.last_stop - (GST_SECOND / 2);
4358 if (GST_CLOCK_TIME_IS_VALID (demux->segment.stop))
4359 new_start = MIN (new_start, demux->segment.stop);
4360 GST_DEBUG_OBJECT (demux,
4361 "Synchronizing stream %d with others by advancing time " "from %"
4362 GST_TIME_FORMAT " to %" GST_TIME_FORMAT, stream_nr,
4363 GST_TIME_ARGS (context->pos), GST_TIME_ARGS (new_start));
4365 context->pos = new_start;
4367 /* advance stream time */
4368 gst_pad_push_event (context->pad,
4369 gst_event_new_new_segment (TRUE, demux->segment.rate,
4370 demux->segment.format, new_start,
4371 demux->segment.stop, new_start));
4377 static GstFlowReturn
4378 gst_matroska_demux_push_hdr_buf (GstMatroskaDemux * demux,
4379 GstMatroskaTrackContext * stream, guint8 * data, guint len)
4381 GstFlowReturn ret, cret;
4382 GstBuffer *header_buf;
4384 header_buf = gst_buffer_new_and_alloc (len);
4385 gst_buffer_set_caps (header_buf, stream->caps);
4386 memcpy (GST_BUFFER_DATA (header_buf), data, len);
4388 if (stream->set_discont) {
4389 GST_BUFFER_FLAG_SET (header_buf, GST_BUFFER_FLAG_DISCONT);
4390 stream->set_discont = FALSE;
4393 ret = gst_pad_push (stream->pad, header_buf);
4396 cret = gst_matroska_demux_combine_flows (demux, stream, ret);
4401 static GstFlowReturn
4402 gst_matroska_demux_push_flac_codec_priv_data (GstMatroskaDemux * demux,
4403 GstMatroskaTrackContext * stream)
4409 GST_LOG_OBJECT (demux, "priv data size = %u", stream->codec_priv_size);
4411 pdata = (guint8 *) stream->codec_priv;
4413 /* need at least 'fLaC' marker + STREAMINFO metadata block */
4414 if (stream->codec_priv_size < ((4) + (4 + 34))) {
4415 GST_WARNING_OBJECT (demux, "not enough codec priv data for flac headers");
4416 return GST_FLOW_ERROR;
4419 if (memcmp (pdata, "fLaC", 4) != 0) {
4420 GST_WARNING_OBJECT (demux, "no flac marker at start of stream headers");
4421 return GST_FLOW_ERROR;
4424 ret = gst_matroska_demux_push_hdr_buf (demux, stream, pdata, 4);
4425 if (ret != GST_FLOW_OK)
4428 off = 4; /* skip fLaC marker */
4429 while (off < stream->codec_priv_size) {
4430 len = GST_READ_UINT8 (pdata + off + 1) << 16;
4431 len |= GST_READ_UINT8 (pdata + off + 2) << 8;
4432 len |= GST_READ_UINT8 (pdata + off + 3);
4434 GST_DEBUG_OBJECT (demux, "header packet: len=%u bytes, flags=0x%02x",
4435 len, (guint) pdata[off]);
4437 ret = gst_matroska_demux_push_hdr_buf (demux, stream, pdata + off, len + 4);
4438 if (ret != GST_FLOW_OK)
4446 static GstFlowReturn
4447 gst_matroska_demux_push_speex_codec_priv_data (GstMatroskaDemux * demux,
4448 GstMatroskaTrackContext * stream)
4453 GST_LOG_OBJECT (demux, "priv data size = %u", stream->codec_priv_size);
4455 pdata = (guint8 *) stream->codec_priv;
4457 /* need at least 'fLaC' marker + STREAMINFO metadata block */
4458 if (stream->codec_priv_size < 80) {
4459 GST_WARNING_OBJECT (demux, "not enough codec priv data for speex headers");
4460 return GST_FLOW_ERROR;
4463 if (memcmp (pdata, "Speex ", 8) != 0) {
4464 GST_WARNING_OBJECT (demux, "no Speex marker at start of stream headers");
4465 return GST_FLOW_ERROR;
4468 ret = gst_matroska_demux_push_hdr_buf (demux, stream, pdata, 80);
4469 if (ret != GST_FLOW_OK)
4472 if (stream->codec_priv_size == 80)
4475 return gst_matroska_demux_push_hdr_buf (demux, stream, pdata + 80,
4476 stream->codec_priv_size - 80);
4479 static GstFlowReturn
4480 gst_matroska_demux_push_xiph_codec_priv_data (GstMatroskaDemux * demux,
4481 GstMatroskaTrackContext * stream)
4484 guint8 *p = (guint8 *) stream->codec_priv;
4485 gint i, offset, num_packets;
4486 guint *length, last;
4488 if (stream->codec_priv == NULL || stream->codec_priv_size == 0) {
4489 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4490 ("Missing codec private data for xiph headers, broken file"));
4491 return GST_FLOW_ERROR;
4494 /* start of the stream and vorbis audio or theora video, need to
4495 * send the codec_priv data as first three packets */
4496 num_packets = p[0] + 1;
4497 GST_DEBUG_OBJECT (demux, "%u stream headers, total length=%u bytes",
4498 (guint) num_packets, stream->codec_priv_size);
4500 length = g_alloca (num_packets * sizeof (guint));
4504 /* first packets, read length values */
4505 for (i = 0; i < num_packets - 1; i++) {
4507 while (offset < stream->codec_priv_size) {
4508 length[i] += p[offset];
4509 if (p[offset++] != 0xff)
4514 if (offset + last > stream->codec_priv_size)
4515 return GST_FLOW_ERROR;
4517 /* last packet is the remaining size */
4518 length[i] = stream->codec_priv_size - offset - last;
4520 for (i = 0; i < num_packets; i++) {
4521 GST_DEBUG_OBJECT (demux, "buffer %d: length=%u bytes", i,
4523 if (offset + length[i] > stream->codec_priv_size)
4524 return GST_FLOW_ERROR;
4527 gst_matroska_demux_push_hdr_buf (demux, stream, p + offset, length[i]);
4528 if (ret != GST_FLOW_OK)
4531 offset += length[i];
4537 gst_matroska_demux_push_dvd_clut_change_event (GstMatroskaDemux * demux,
4538 GstMatroskaTrackContext * stream)
4542 g_assert (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB));
4544 if (!stream->codec_priv)
4547 /* ideally, VobSub private data should be parsed and stored more convenient
4548 * elsewhere, but for now, only interested in a small part */
4550 /* make sure we have terminating 0 */
4551 buf = g_strndup ((gchar *) stream->codec_priv, stream->codec_priv_size);
4553 /* just locate and parse palette part */
4554 start = strstr (buf, "palette:");
4559 guint8 r, g, b, y, u, v;
4562 while (g_ascii_isspace (*start))
4564 for (i = 0; i < 16; i++) {
4565 if (sscanf (start, "%06x", &col) != 1)
4568 while ((*start == ',') || g_ascii_isspace (*start))
4570 /* sigh, need to convert this from vobsub pseudo-RGB to YUV */
4571 r = (col >> 16) & 0xff;
4572 g = (col >> 8) & 0xff;
4574 y = CLAMP ((0.1494 * r + 0.6061 * g + 0.2445 * b) * 219 / 255 + 16, 0,
4576 u = CLAMP (0.6066 * r - 0.4322 * g - 0.1744 * b + 128, 0, 255);
4577 v = CLAMP (-0.08435 * r - 0.3422 * g + 0.4266 * b + 128, 0, 255);
4578 clut[i] = (y << 16) | (u << 8) | v;
4581 /* got them all without problems; build and send event */
4585 s = gst_structure_new ("application/x-gst-dvd", "event", G_TYPE_STRING,
4586 "dvd-spu-clut-change", "clut00", G_TYPE_INT, clut[0], "clut01",
4587 G_TYPE_INT, clut[1], "clut02", G_TYPE_INT, clut[2], "clut03",
4588 G_TYPE_INT, clut[3], "clut04", G_TYPE_INT, clut[4], "clut05",
4589 G_TYPE_INT, clut[5], "clut06", G_TYPE_INT, clut[6], "clut07",
4590 G_TYPE_INT, clut[7], "clut08", G_TYPE_INT, clut[8], "clut09",
4591 G_TYPE_INT, clut[9], "clut10", G_TYPE_INT, clut[10], "clut11",
4592 G_TYPE_INT, clut[11], "clut12", G_TYPE_INT, clut[12], "clut13",
4593 G_TYPE_INT, clut[13], "clut14", G_TYPE_INT, clut[14], "clut15",
4594 G_TYPE_INT, clut[15], NULL);
4596 gst_pad_push_event (stream->pad,
4597 gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM, s));
4603 static GstFlowReturn
4604 gst_matroska_demux_add_mpeg_seq_header (GstElement * element,
4605 GstMatroskaTrackContext * stream, GstBuffer ** buf)
4608 guint seq_header_len;
4611 if (stream->codec_state) {
4612 seq_header = stream->codec_state;
4613 seq_header_len = stream->codec_state_size;
4614 } else if (stream->codec_priv) {
4615 seq_header = stream->codec_priv;
4616 seq_header_len = stream->codec_priv_size;
4621 /* Sequence header only needed for keyframes */
4622 if (GST_BUFFER_FLAG_IS_SET (*buf, GST_BUFFER_FLAG_DELTA_UNIT))
4625 if (GST_BUFFER_SIZE (*buf) < 4)
4628 header = GST_READ_UINT32_BE (GST_BUFFER_DATA (*buf));
4629 /* Sequence start code, if not found prepend */
4630 if (header != 0x000001b3) {
4633 newbuf = gst_buffer_new_and_alloc (GST_BUFFER_SIZE (*buf) + seq_header_len);
4634 gst_buffer_set_caps (newbuf, stream->caps);
4636 GST_DEBUG_OBJECT (element, "Prepending MPEG sequence header");
4637 gst_buffer_copy_metadata (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
4638 GST_BUFFER_COPY_FLAGS);
4639 g_memmove (GST_BUFFER_DATA (newbuf), seq_header, seq_header_len);
4640 g_memmove (GST_BUFFER_DATA (newbuf) + seq_header_len,
4641 GST_BUFFER_DATA (*buf), GST_BUFFER_SIZE (*buf));
4642 gst_buffer_unref (*buf);
4649 static GstFlowReturn
4650 gst_matroska_demux_add_wvpk_header (GstElement * element,
4651 GstMatroskaTrackContext * stream, GstBuffer ** buf)
4653 GstMatroskaTrackAudioContext *audiocontext =
4654 (GstMatroskaTrackAudioContext *) stream;
4655 GstBuffer *newbuf = NULL;
4665 wvh.version = GST_READ_UINT16_LE (stream->codec_priv);
4668 wvh.total_samples = -1;
4669 wvh.block_index = audiocontext->wvpk_block_index;
4671 if (audiocontext->channels <= 2) {
4672 guint32 block_samples;
4674 block_samples = GST_READ_UINT32_LE (GST_BUFFER_DATA (*buf));
4675 /* we need to reconstruct the header of the wavpack block */
4677 /* -20 because ck_size is the size of the wavpack block -8
4678 * and lace_size is the size of the wavpack block + 12
4679 * (the three guint32 of the header that already are in the buffer) */
4680 wvh.ck_size = GST_BUFFER_SIZE (*buf) + sizeof (Wavpack4Header) - 20;
4682 /* block_samples, flags and crc are already in the buffer */
4683 newlen = GST_BUFFER_SIZE (*buf) + sizeof (Wavpack4Header) - 12;
4684 newbuf = gst_buffer_new_and_alloc (newlen);
4685 gst_buffer_set_caps (newbuf, stream->caps);
4687 data = GST_BUFFER_DATA (newbuf);
4692 GST_WRITE_UINT32_LE (data + 4, wvh.ck_size);
4693 GST_WRITE_UINT16_LE (data + 8, wvh.version);
4694 GST_WRITE_UINT8 (data + 10, wvh.track_no);
4695 GST_WRITE_UINT8 (data + 11, wvh.index_no);
4696 GST_WRITE_UINT32_LE (data + 12, wvh.total_samples);
4697 GST_WRITE_UINT32_LE (data + 16, wvh.block_index);
4698 g_memmove (data + 20, GST_BUFFER_DATA (*buf), GST_BUFFER_SIZE (*buf));
4699 gst_buffer_copy_metadata (newbuf, *buf,
4700 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS);
4701 gst_buffer_unref (*buf);
4703 audiocontext->wvpk_block_index += block_samples;
4708 guint32 block_samples, flags, crc, blocksize;
4710 data = GST_BUFFER_DATA (*buf);
4711 size = GST_BUFFER_SIZE (*buf);
4714 GST_ERROR_OBJECT (element, "Too small wavpack buffer");
4715 return GST_FLOW_ERROR;
4718 block_samples = GST_READ_UINT32_LE (data);
4723 flags = GST_READ_UINT32_LE (data);
4726 crc = GST_READ_UINT32_LE (data);
4729 blocksize = GST_READ_UINT32_LE (data);
4733 if (blocksize == 0 || size < blocksize)
4736 if (newbuf == NULL) {
4737 newbuf = gst_buffer_new_and_alloc (sizeof (Wavpack4Header) + blocksize);
4738 gst_buffer_set_caps (newbuf, stream->caps);
4740 gst_buffer_copy_metadata (newbuf, *buf,
4741 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS);
4744 outdata = GST_BUFFER_DATA (newbuf);
4746 GST_BUFFER_SIZE (newbuf) += sizeof (Wavpack4Header) + blocksize;
4747 GST_BUFFER_DATA (newbuf) =
4748 g_realloc (GST_BUFFER_DATA (newbuf), GST_BUFFER_SIZE (newbuf));
4749 GST_BUFFER_MALLOCDATA (newbuf) = GST_BUFFER_DATA (newbuf);
4750 outdata = GST_BUFFER_DATA (newbuf);
4753 outdata[outpos] = 'w';
4754 outdata[outpos + 1] = 'v';
4755 outdata[outpos + 2] = 'p';
4756 outdata[outpos + 3] = 'k';
4759 GST_WRITE_UINT32_LE (outdata + outpos,
4760 blocksize + sizeof (Wavpack4Header) - 8);
4761 GST_WRITE_UINT16_LE (outdata + outpos + 4, wvh.version);
4762 GST_WRITE_UINT8 (outdata + outpos + 6, wvh.track_no);
4763 GST_WRITE_UINT8 (outdata + outpos + 7, wvh.index_no);
4764 GST_WRITE_UINT32_LE (outdata + outpos + 8, wvh.total_samples);
4765 GST_WRITE_UINT32_LE (outdata + outpos + 12, wvh.block_index);
4766 GST_WRITE_UINT32_LE (outdata + outpos + 16, block_samples);
4767 GST_WRITE_UINT32_LE (outdata + outpos + 20, flags);
4768 GST_WRITE_UINT32_LE (outdata + outpos + 24, crc);
4771 g_memmove (outdata + outpos, data, blocksize);
4772 outpos += blocksize;
4776 gst_buffer_unref (*buf);
4778 audiocontext->wvpk_block_index += block_samples;
4784 static GstFlowReturn
4785 gst_matroska_demux_check_subtitle_buffer (GstElement * element,
4786 GstMatroskaTrackContext * stream, GstBuffer ** buf)
4788 GstMatroskaTrackSubtitleContext *sub_stream;
4789 const gchar *encoding, *data;
4795 sub_stream = (GstMatroskaTrackSubtitleContext *) stream;
4797 data = (const gchar *) GST_BUFFER_DATA (*buf);
4798 size = GST_BUFFER_SIZE (*buf);
4800 if (!sub_stream->invalid_utf8) {
4801 if (g_utf8_validate (data, size, NULL)) {
4804 GST_WARNING_OBJECT (element, "subtitle stream %d is not valid UTF-8, this "
4805 "is broken according to the matroska specification", stream->num);
4806 sub_stream->invalid_utf8 = TRUE;
4809 /* file with broken non-UTF8 subtitle, do the best we can do to fix it */
4810 encoding = g_getenv ("GST_SUBTITLE_ENCODING");
4811 if (encoding == NULL || *encoding == '\0') {
4812 /* if local encoding is UTF-8 and no encoding specified
4813 * via the environment variable, assume ISO-8859-15 */
4814 if (g_get_charset (&encoding)) {
4815 encoding = "ISO-8859-15";
4819 utf8 = g_convert_with_fallback (data, size, "UTF-8", encoding, (char *) "*",
4823 GST_LOG_OBJECT (element, "could not convert string from '%s' to UTF-8: %s",
4824 encoding, err->message);
4828 /* invalid input encoding, fall back to ISO-8859-15 (always succeeds) */
4829 encoding = "ISO-8859-15";
4830 utf8 = g_convert_with_fallback (data, size, "UTF-8", encoding, (char *) "*",
4834 GST_LOG_OBJECT (element, "converted subtitle text from %s to UTF-8 %s",
4835 encoding, (err) ? "(using ISO-8859-15 as fallback)" : "");
4838 utf8 = g_strdup ("invalid subtitle");
4840 newbuf = gst_buffer_new ();
4841 GST_BUFFER_MALLOCDATA (newbuf) = (guint8 *) utf8;
4842 GST_BUFFER_DATA (newbuf) = (guint8 *) utf8;
4843 GST_BUFFER_SIZE (newbuf) = strlen (utf8);
4844 gst_buffer_copy_metadata (newbuf, *buf,
4845 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS);
4846 gst_buffer_unref (*buf);
4852 #ifdef MKVDEMUX_MODIFICATION
4853 static GstFlowReturn
4854 gst_matroska_rewind_trickplay (GstMatroskaDemux* demux, GstMatroskaTrackContext * stream, GstBuffer* sub)
4856 GstFlowReturn ret = GST_FLOW_OK;
4858 /* Reverse trick play...*/
4859 g_queue_push_tail (stream->queue, sub);
4861 if ((demux->found_videokeyframe == TRUE) && (demux->found_audioframe == TRUE))
4863 //reached condition...so display in reverse direction
4866 for (i = 0; i < demux->src->len; i++)
4868 GstMatroskaTrackContext *tmp = g_ptr_array_index (demux->src, i);
4870 /* make sure that we empty the queue */
4871 while (!g_queue_is_empty (tmp->queue))
4873 QBuf = g_queue_pop_tail (tmp->queue);
4874 GST_DEBUG_OBJECT (demux,
4875 "Pushing data of size %d for stream %d, time=%"
4876 GST_TIME_FORMAT " and duration=%" GST_TIME_FORMAT,
4877 GST_BUFFER_SIZE (QBuf), tmp->type,
4878 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (QBuf)),
4879 GST_TIME_ARGS (GST_BUFFER_DURATION (QBuf)));
4881 ret = gst_pad_push(tmp->pad, QBuf);
4883 if (ret != GST_FLOW_OK)
4885 GST_DEBUG_OBJECT (demux, "Error in pad_push. Reason : %s\n", gst_flow_get_name (ret));
4895 static GstFlowReturn
4896 gst_matroska_demux_check_aac (GstElement * element,
4897 GstMatroskaTrackContext * stream, GstBuffer ** buf)
4902 data = GST_BUFFER_DATA (*buf);
4903 size = GST_BUFFER_SIZE (*buf);
4905 if (size > 2 && data[0] == 0xff && (data[1] >> 4 == 0x0f)) {
4909 /* tss, ADTS data, remove codec_data
4910 * still assume it is at least parsed */
4911 new_caps = gst_caps_copy (stream->caps);
4912 s = gst_caps_get_structure (new_caps, 0);
4914 gst_structure_remove_field (s, "codec_data");
4915 gst_caps_replace (&stream->caps, new_caps);
4916 gst_pad_set_caps (stream->pad, new_caps);
4917 gst_buffer_set_caps (*buf, new_caps);
4918 GST_DEBUG_OBJECT (element, "ADTS AAC audio data; removing codec-data, "
4919 "new caps: %" GST_PTR_FORMAT, new_caps);
4920 gst_caps_unref (new_caps);
4923 /* disable subsequent checking */
4924 stream->postprocess_frame = NULL;
4929 static GstFlowReturn
4930 gst_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux,
4931 GstEbmlRead * ebml, guint64 cluster_time, guint64 cluster_offset,
4932 gboolean is_simpleblock)
4934 GstMatroskaTrackContext *stream = NULL;
4935 GstFlowReturn ret = GST_FLOW_OK;
4936 gboolean readblock = FALSE;
4938 guint64 block_duration = 0;
4939 GstBuffer *buf = NULL;
4940 gint stream_num = -1, n, laces = 0;
4942 gint *lace_size = NULL;
4945 gint64 referenceblock = 0;
4948 offset = gst_ebml_read_get_offset (ebml);
4950 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
4951 if (!is_simpleblock) {
4952 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK) {
4956 id = GST_MATROSKA_ID_SIMPLEBLOCK;
4960 /* one block inside the group. Note, block parsing is one
4961 * of the harder things, so this code is a bit complicated.
4962 * See http://www.matroska.org/ for documentation. */
4963 case GST_MATROSKA_ID_SIMPLEBLOCK:
4964 case GST_MATROSKA_ID_BLOCK:
4970 gst_buffer_unref (buf);
4973 if ((ret = gst_ebml_read_buffer (ebml, &id, &buf)) != GST_FLOW_OK)
4976 data = GST_BUFFER_DATA (buf);
4977 size = GST_BUFFER_SIZE (buf);
4979 /* first byte(s): blocknum */
4980 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
4985 /* fetch stream from num */
4986 stream_num = gst_matroska_demux_stream_from_num (demux, num);
4987 if (G_UNLIKELY (size < 3)) {
4988 GST_WARNING_OBJECT (demux, "Invalid size %u", size);
4989 /* non-fatal, try next block(group) */
4992 } else if (G_UNLIKELY (stream_num < 0 ||
4993 stream_num >= demux->num_streams)) {
4994 /* let's not give up on a stray invalid track number */
4995 GST_WARNING_OBJECT (demux,
4996 "Invalid stream %d for track number %" G_GUINT64_FORMAT
4997 "; ignoring block", stream_num, num);
5001 stream = g_ptr_array_index (demux->src, stream_num);
5003 #ifdef MKVDEMUX_MODIFICATION
5004 if (demux->segment.rate < 0.0)
5006 if ((stream_num+1) == GST_MATROSKA_TRACK_TYPE_AUDIO)
5008 /* found at least one audio block */
5009 demux->found_audioframe = TRUE;
5013 /* time (relative to cluster time) */
5014 time = ((gint16) GST_READ_UINT16_BE (data));
5017 flags = GST_READ_UINT8 (data);
5021 GST_LOG_OBJECT (demux, "time %" G_GUINT64_FORMAT ", flags %d", time,
5024 switch ((flags & 0x06) >> 1) {
5025 case 0x0: /* no lacing */
5027 lace_size = g_new (gint, 1);
5028 lace_size[0] = size;
5031 case 0x1: /* xiph lacing */
5032 case 0x2: /* fixed-size lacing */
5033 case 0x3: /* EBML lacing */
5035 goto invalid_lacing;
5036 laces = GST_READ_UINT8 (data) + 1;
5039 lace_size = g_new0 (gint, laces);
5041 switch ((flags & 0x06) >> 1) {
5042 case 0x1: /* xiph lacing */ {
5043 guint temp, total = 0;
5045 for (n = 0; ret == GST_FLOW_OK && n < laces - 1; n++) {
5048 goto invalid_lacing;
5049 temp = GST_READ_UINT8 (data);
5050 lace_size[n] += temp;
5056 total += lace_size[n];
5058 lace_size[n] = size - total;
5062 case 0x2: /* fixed-size lacing */
5063 for (n = 0; n < laces; n++)
5064 lace_size[n] = size / laces;
5067 case 0x3: /* EBML lacing */ {
5070 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
5074 total = lace_size[0] = num;
5075 for (n = 1; ret == GST_FLOW_OK && n < laces - 1; n++) {
5079 if ((r = gst_matroska_ebmlnum_sint (data, size, &snum)) < 0)
5083 lace_size[n] = lace_size[n - 1] + snum;
5084 total += lace_size[n];
5087 lace_size[n] = size - total;
5094 if (stream->send_xiph_headers) {
5095 ret = gst_matroska_demux_push_xiph_codec_priv_data (demux, stream);
5096 stream->send_xiph_headers = FALSE;
5099 if (stream->send_flac_headers) {
5100 ret = gst_matroska_demux_push_flac_codec_priv_data (demux, stream);
5101 stream->send_flac_headers = FALSE;
5104 if (stream->send_speex_headers) {
5105 ret = gst_matroska_demux_push_speex_codec_priv_data (demux, stream);
5106 stream->send_speex_headers = FALSE;
5109 if (stream->send_dvd_event) {
5110 gst_matroska_demux_push_dvd_clut_change_event (demux, stream);
5111 /* FIXME: should we send this event again after (flushing) seek ? */
5112 stream->send_dvd_event = FALSE;
5115 if (ret != GST_FLOW_OK)
5122 case GST_MATROSKA_ID_BLOCKDURATION:{
5123 ret = gst_ebml_read_uint (ebml, &id, &block_duration);
5124 GST_DEBUG_OBJECT (demux, "BlockDuration: %" G_GUINT64_FORMAT,
5129 case GST_MATROSKA_ID_REFERENCEBLOCK:{
5130 ret = gst_ebml_read_sint (ebml, &id, &referenceblock);
5131 GST_DEBUG_OBJECT (demux, "ReferenceBlock: %" G_GINT64_FORMAT,
5136 case GST_MATROSKA_ID_CODECSTATE:{
5138 guint64 data_len = 0;
5141 gst_ebml_read_binary (ebml, &id, &data,
5142 &data_len)) != GST_FLOW_OK)
5145 if (G_UNLIKELY (stream == NULL)) {
5146 GST_WARNING_OBJECT (demux,
5147 "Unexpected CodecState subelement - ignoring");
5151 g_free (stream->codec_state);
5152 stream->codec_state = data;
5153 stream->codec_state_size = data_len;
5155 /* Decode if necessary */
5156 if (stream->encodings && stream->encodings->len > 0
5157 && stream->codec_state && stream->codec_state_size > 0) {
5158 if (!gst_matroska_decode_data (stream->encodings,
5159 &stream->codec_state, &stream->codec_state_size,
5160 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
5161 GST_WARNING_OBJECT (demux, "Decoding codec state failed");
5165 GST_DEBUG_OBJECT (demux, "CodecState of %u bytes",
5166 stream->codec_state_size);
5171 ret = gst_matroska_demux_parse_skip (demux, ebml, "BlockGroup", id);
5174 case GST_MATROSKA_ID_BLOCKVIRTUAL:
5175 case GST_MATROSKA_ID_BLOCKADDITIONS:
5176 case GST_MATROSKA_ID_REFERENCEPRIORITY:
5177 case GST_MATROSKA_ID_REFERENCEVIRTUAL:
5178 case GST_MATROSKA_ID_SLICES:
5179 GST_DEBUG_OBJECT (demux,
5180 "Skipping BlockGroup subelement 0x%x - ignoring", id);
5181 ret = gst_ebml_read_skip (ebml);
5189 /* reading a number or so could have failed */
5190 if (ret != GST_FLOW_OK)
5193 if (ret == GST_FLOW_OK && readblock) {
5194 guint64 duration = 0;
5195 gint64 lace_time = 0;
5196 gboolean delta_unit;
5198 stream = g_ptr_array_index (demux->src, stream_num);
5200 if (cluster_time != GST_CLOCK_TIME_NONE) {
5201 /* FIXME: What to do with negative timestamps? Give timestamp 0 or -1?
5202 * Drop unless the lace contains timestamp 0? */
5203 if (time < 0 && (-time) > cluster_time) {
5206 if (stream->timecodescale == 1.0)
5207 lace_time = (cluster_time + time) * demux->time_scale;
5210 gst_util_guint64_to_gdouble ((cluster_time + time) *
5211 demux->time_scale) * stream->timecodescale;
5214 lace_time = GST_CLOCK_TIME_NONE;
5217 /* need to refresh segment info ASAP */
5218 if (GST_CLOCK_TIME_IS_VALID (lace_time) && demux->need_newsegment) {
5219 GST_DEBUG_OBJECT (demux,
5220 "generating segment starting at %" GST_TIME_FORMAT,
5221 GST_TIME_ARGS (lace_time));
5222 /* pretend we seeked here */
5223 gst_segment_set_seek (&demux->segment, demux->segment.rate,
5224 GST_FORMAT_TIME, 0, GST_SEEK_TYPE_SET, lace_time,
5225 GST_SEEK_TYPE_SET, GST_CLOCK_TIME_NONE, NULL);
5226 /* now convey our segment notion downstream */
5227 gst_matroska_demux_send_event (demux, gst_event_new_new_segment (FALSE,
5228 demux->segment.rate, demux->segment.format, demux->segment.start,
5229 demux->segment.stop, demux->segment.start));
5230 demux->need_newsegment = FALSE;
5233 if (block_duration) {
5234 if (stream->timecodescale == 1.0)
5235 duration = gst_util_uint64_scale (block_duration, demux->time_scale, 1);
5238 gst_util_gdouble_to_guint64 (gst_util_guint64_to_gdouble
5239 (gst_util_uint64_scale (block_duration, demux->time_scale,
5240 1)) * stream->timecodescale);
5241 } else if (stream->default_duration) {
5242 duration = stream->default_duration * laces;
5244 /* else duration is diff between timecode of this and next block */
5246 /* For SimpleBlock, look at the keyframe bit in flags. Otherwise,
5247 a ReferenceBlock implies that this is not a keyframe. In either
5248 case, it only makes sense for video streams. */
5249 delta_unit = stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
5250 ((is_simpleblock && !(flags & 0x80)) || referenceblock);
5252 if (delta_unit && stream->set_discont) {
5253 /* When doing seeks or such, we need to restart on key frames or
5254 * decoders might choke. */
5255 GST_DEBUG_OBJECT (demux, "skipping delta unit");
5259 for (n = 0; n < laces; n++) {
5261 #ifdef MKVDEMUX_MODIFICATION
5262 gboolean skip_flag = FALSE;
5265 if (G_UNLIKELY (lace_size[n] > size)) {
5266 GST_WARNING_OBJECT (demux, "Invalid lace size");
5270 /* QoS for video track with an index. the assumption is that
5271 index entries point to keyframes, but if that is not true we
5272 will instad skip until the next keyframe. */
5273 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
5274 stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
5275 stream->index_table && demux->segment.rate > 0.0) {
5276 GstMatroskaTrackVideoContext *videocontext =
5277 (GstMatroskaTrackVideoContext *) stream;
5278 GstClockTime earliest_time;
5279 GstClockTime earliest_stream_time;
5281 GST_OBJECT_LOCK (demux);
5282 earliest_time = videocontext->earliest_time;
5283 GST_OBJECT_UNLOCK (demux);
5284 earliest_stream_time = gst_segment_to_position (&demux->segment,
5285 GST_FORMAT_TIME, earliest_time);
5287 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
5288 GST_CLOCK_TIME_IS_VALID (earliest_stream_time) &&
5289 lace_time <= earliest_stream_time) {
5290 /* find index entry (keyframe) <= earliest_stream_time */
5291 GstMatroskaIndex *entry =
5292 gst_util_array_binary_search (stream->index_table->data,
5293 stream->index_table->len, sizeof (GstMatroskaIndex),
5294 (GCompareDataFunc) gst_matroska_index_seek_find,
5295 GST_SEARCH_MODE_BEFORE, &earliest_stream_time, NULL);
5297 /* if that entry (keyframe) is after the current the current
5298 buffer, we can skip pushing (and thus decoding) all
5299 buffers until that keyframe. */
5300 if (entry && GST_CLOCK_TIME_IS_VALID (entry->time) &&
5301 entry->time > lace_time) {
5302 GST_LOG_OBJECT (demux, "Skipping lace before late keyframe");
5303 stream->set_discont = TRUE;
5309 sub = gst_buffer_create_sub (buf,
5310 GST_BUFFER_SIZE (buf) - size, lace_size[n]);
5311 GST_DEBUG_OBJECT (demux, "created subbuffer %p", sub);
5314 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
5316 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
5318 if (stream->encodings != NULL && stream->encodings->len > 0)
5319 sub = gst_matroska_decode_buffer (stream, sub);
5322 GST_WARNING_OBJECT (demux, "Decoding buffer failed");
5326 GST_BUFFER_TIMESTAMP (sub) = lace_time;
5328 if (GST_CLOCK_TIME_IS_VALID (lace_time)) {
5329 GstClockTime last_stop_end;
5331 #ifndef MKVDEMUX_MODIFICATION
5332 /* Check if this stream is after segment stop */
5333 if (GST_CLOCK_TIME_IS_VALID (demux->segment.stop) &&
5334 lace_time >= demux->segment.stop) {
5335 GST_DEBUG_OBJECT (demux,
5336 "Stream %d after segment stop %" GST_TIME_FORMAT, stream->index,
5337 GST_TIME_ARGS (demux->segment.stop));
5338 gst_buffer_unref (sub);
5341 if (offset >= stream->to_offset) {
5342 GST_DEBUG_OBJECT (demux, "Stream %d after playback section",
5344 gst_buffer_unref (sub);
5349 /* handle gaps, e.g. non-zero start-time, or an cue index entry
5350 * that landed us with timestamps not quite intended */
5351 if (GST_CLOCK_TIME_IS_VALID (demux->segment.last_stop) &&
5352 demux->segment.rate > 0.0) {
5353 GstClockTimeDiff diff;
5355 /* only send newsegments with increasing start times,
5356 * otherwise if these go back and forth downstream (sinks) increase
5357 * accumulated time and running_time */
5358 diff = GST_CLOCK_DIFF (demux->segment.last_stop, lace_time);
5359 if (diff > 2 * GST_SECOND && lace_time > demux->segment.start &&
5360 (!GST_CLOCK_TIME_IS_VALID (demux->segment.stop) ||
5361 lace_time < demux->segment.stop)) {
5362 GST_DEBUG_OBJECT (demux,
5363 "Gap of %" G_GINT64_FORMAT " ns detected in"
5364 "stream %d (%" GST_TIME_FORMAT " -> %" GST_TIME_FORMAT "). "
5365 "Sending updated NEWSEGMENT events", diff,
5366 stream->index, GST_TIME_ARGS (stream->pos),
5367 GST_TIME_ARGS (lace_time));
5368 /* send newsegment events such that the gap is not accounted in
5369 * accum time, hence running_time */
5370 /* close ahead of gap */
5371 gst_matroska_demux_send_event (demux,
5372 gst_event_new_new_segment (TRUE, demux->segment.rate,
5373 demux->segment.format, demux->segment.last_stop,
5374 demux->segment.last_stop, demux->segment.last_stop));
5376 gst_matroska_demux_send_event (demux,
5377 gst_event_new_new_segment (FALSE, demux->segment.rate,
5378 demux->segment.format, lace_time, demux->segment.stop,
5380 /* align segment view with downstream,
5381 * prevents double-counting accum when closing segment */
5382 gst_segment_set_newsegment (&demux->segment, FALSE,
5383 demux->segment.rate, demux->segment.format, lace_time,
5384 demux->segment.stop, lace_time);
5385 demux->segment.last_stop = lace_time;
5389 if (!GST_CLOCK_TIME_IS_VALID (demux->segment.last_stop)
5390 || demux->segment.last_stop < lace_time) {
5391 demux->segment.last_stop = lace_time;
5394 last_stop_end = lace_time;
5396 GST_BUFFER_DURATION (sub) = duration / laces;
5397 last_stop_end += GST_BUFFER_DURATION (sub);
5400 if (!GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) ||
5401 demux->last_stop_end < last_stop_end)
5402 demux->last_stop_end = last_stop_end;
5404 if (demux->segment.duration == -1 ||
5405 demux->segment.duration < lace_time) {
5406 gst_segment_set_duration (&demux->segment, GST_FORMAT_TIME,
5408 gst_element_post_message (GST_ELEMENT_CAST (demux),
5409 gst_message_new_duration (GST_OBJECT_CAST (demux),
5410 GST_FORMAT_TIME, GST_CLOCK_TIME_NONE));
5414 stream->pos = lace_time;
5416 gst_matroska_demux_sync_streams (demux);
5418 if (stream->set_discont) {
5419 GST_DEBUG_OBJECT (demux, "marking DISCONT");
5420 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DISCONT);
5421 stream->set_discont = FALSE;
5424 /* reverse playback book-keeping */
5425 if (!GST_CLOCK_TIME_IS_VALID (stream->from_time))
5426 stream->from_time = lace_time;
5427 if (stream->from_offset == -1)
5428 stream->from_offset = offset;
5431 #ifdef MKVDEMUX_MODIFICATION
5432 if ((demux->segment.rate < 0.0) && ((stream_num+1) == GST_MATROSKA_TRACK_TYPE_VIDEO))
5434 if (GST_BUFFER_FLAG_IS_SET (sub, GST_BUFFER_FLAG_DELTA_UNIT))
5436 GST_DEBUG_OBJECT (demux, "skipping delta unit");
5437 gst_buffer_unref (sub);
5442 /* found key frame*/
5443 demux->found_videokeyframe = TRUE;
5447 GST_DEBUG_OBJECT (demux,
5448 "Pushing lace %d, data of size %d for stream %d, time=%"
5449 GST_TIME_FORMAT " and duration=%" GST_TIME_FORMAT, n,
5450 GST_BUFFER_SIZE (sub), stream_num,
5451 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (sub)),
5452 GST_TIME_ARGS (GST_BUFFER_DURATION (sub)));
5454 if (demux->element_index) {
5455 if (stream->index_writer_id == -1)
5456 gst_index_get_writer_id (demux->element_index,
5457 GST_OBJECT (stream->pad), &stream->index_writer_id);
5459 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
5460 G_GUINT64_FORMAT " for writer id %d",
5461 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (sub)), cluster_offset,
5462 stream->index_writer_id);
5463 gst_index_add_association (demux->element_index,
5464 stream->index_writer_id, GST_BUFFER_FLAG_IS_SET (sub,
5465 GST_BUFFER_FLAG_DELTA_UNIT) ? 0 : GST_ASSOCIATION_FLAG_KEY_UNIT,
5466 GST_FORMAT_TIME, GST_BUFFER_TIMESTAMP (sub), GST_FORMAT_BYTES,
5467 cluster_offset, NULL);
5470 gst_buffer_set_caps (sub, GST_PAD_CAPS (stream->pad));
5472 /* Postprocess the buffers depending on the codec used */
5473 if (stream->postprocess_frame) {
5474 GST_LOG_OBJECT (demux, "running post process");
5475 ret = stream->postprocess_frame (GST_ELEMENT (demux), stream, &sub);
5477 #ifdef MKVDEMUX_MODIFICATION
5478 if (demux->video && demux->segment.rate > 1.0 &&
5479 stream->type <= GST_MATROSKA_TRACK_TYPE_AUDIO)
5482 ret = gst_sec_matroska_forward_trickplay (demux, stream, sub, &skip_flag);
5483 if (skip_flag == FALSE)
5485 ret = gst_pad_push (stream->pad, sub);
5489 gst_buffer_unref (sub);
5492 else if (demux->segment.rate < 0.0)
5494 ret = gst_matroska_rewind_trickplay (demux, stream, sub);
5499 ret = gst_pad_push (stream->pad, sub);
5501 if (demux->segment.rate < 0) {
5502 if (lace_time > demux->segment.stop && ret == GST_FLOW_UNEXPECTED) {
5503 /* In reverse playback we can get a GST_FLOW_UNEXPECTED when
5504 * we are at the end of the segment, so we just need to jump
5505 * back to the previous section. */
5506 GST_DEBUG_OBJECT (demux, "downstream has reached end of segment");
5511 ret = gst_matroska_demux_combine_flows (demux, stream, ret);
5514 size -= lace_size[n];
5515 if (lace_time != GST_CLOCK_TIME_NONE && duration)
5516 lace_time += duration / laces;
5518 lace_time = GST_CLOCK_TIME_NONE;
5524 gst_buffer_unref (buf);
5535 ret = gst_matroska_demux_combine_flows (demux, stream, ret);
5540 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Invalid lacing size"));
5541 /* non-fatal, try next block(group) */
5547 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Data error"));
5548 /* non-fatal, try next block(group) */
5554 /* return FALSE if block(group) should be skipped (due to a seek) */
5555 static inline gboolean
5556 gst_matroska_demux_seek_block (GstMatroskaDemux * demux)
5558 if (G_UNLIKELY (demux->seek_block)) {
5559 if (!(--demux->seek_block)) {
5562 GST_LOG_OBJECT (demux, "should skip block due to seek");
5570 static GstFlowReturn
5571 gst_matroska_demux_parse_contents_seekentry (GstMatroskaDemux * demux,
5575 guint64 seek_pos = (guint64) - 1;
5576 guint32 seek_id = 0;
5579 DEBUG_ELEMENT_START (demux, ebml, "Seek");
5581 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
5582 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
5586 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
5587 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
5591 case GST_MATROSKA_ID_SEEKID:
5595 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
5598 GST_DEBUG_OBJECT (demux, "SeekID: %" G_GUINT64_FORMAT, t);
5603 case GST_MATROSKA_ID_SEEKPOSITION:
5607 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
5610 if (t > G_MAXINT64) {
5611 GST_WARNING_OBJECT (demux,
5612 "Too large SeekPosition %" G_GUINT64_FORMAT, t);
5616 GST_DEBUG_OBJECT (demux, "SeekPosition: %" G_GUINT64_FORMAT, t);
5622 ret = gst_matroska_demux_parse_skip (demux, ebml, "SeekHead", id);
5627 if (ret != GST_FLOW_OK && ret != GST_FLOW_UNEXPECTED)
5630 if (!seek_id || seek_pos == (guint64) - 1) {
5631 GST_WARNING_OBJECT (demux, "Incomplete seekhead entry (0x%x/%"
5632 G_GUINT64_FORMAT ")", seek_id, seek_pos);
5637 case GST_MATROSKA_ID_SEEKHEAD:
5640 case GST_MATROSKA_ID_CUES:
5641 case GST_MATROSKA_ID_TAGS:
5642 case GST_MATROSKA_ID_TRACKS:
5643 case GST_MATROSKA_ID_SEGMENTINFO:
5644 case GST_MATROSKA_ID_ATTACHMENTS:
5645 case GST_MATROSKA_ID_CHAPTERS:
5647 guint64 before_pos, length;
5651 length = gst_matroska_demux_get_length (demux);
5652 before_pos = demux->offset;
5654 if (length == (guint64) - 1) {
5655 GST_DEBUG_OBJECT (demux, "no upstream length, skipping SeakHead entry");
5659 /* check for validity */
5660 if (seek_pos + demux->ebml_segment_start + 12 >= length) {
5661 GST_WARNING_OBJECT (demux,
5662 "SeekHead reference lies outside file!" " (%"
5663 G_GUINT64_FORMAT "+%" G_GUINT64_FORMAT "+12 >= %"
5664 G_GUINT64_FORMAT ")", seek_pos, demux->ebml_segment_start, length);
5668 /* only pick up index location when streaming */
5669 if (demux->streaming) {
5670 if (seek_id == GST_MATROSKA_ID_CUES) {
5671 demux->index_offset = seek_pos + demux->ebml_segment_start;
5672 GST_DEBUG_OBJECT (demux, "Cues located at offset %" G_GUINT64_FORMAT,
5673 demux->index_offset);
5679 demux->offset = seek_pos + demux->ebml_segment_start;
5682 if ((ret = gst_matroska_demux_peek_id_length_pull (demux, &id, &length,
5683 &needed)) != GST_FLOW_OK)
5686 if (id != seek_id) {
5687 GST_WARNING_OBJECT (demux,
5688 "We looked for ID=0x%x but got ID=0x%x (pos=%" G_GUINT64_FORMAT ")",
5689 seek_id, id, seek_pos + demux->ebml_segment_start);
5692 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
5697 demux->offset = before_pos;
5701 case GST_MATROSKA_ID_CLUSTER:
5703 guint64 pos = seek_pos + demux->ebml_segment_start;
5705 GST_LOG_OBJECT (demux, "Cluster position");
5706 if (G_UNLIKELY (!demux->clusters))
5707 demux->clusters = g_array_sized_new (TRUE, TRUE, sizeof (guint64), 100);
5708 g_array_append_val (demux->clusters, pos);
5713 GST_DEBUG_OBJECT (demux, "Ignoring Seek entry for ID=0x%x", seek_id);
5716 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
5721 static GstFlowReturn
5722 gst_matroska_demux_parse_contents (GstMatroskaDemux * demux, GstEbmlRead * ebml)
5724 GstFlowReturn ret = GST_FLOW_OK;
5727 DEBUG_ELEMENT_START (demux, ebml, "SeekHead");
5729 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
5730 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
5734 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
5735 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
5739 case GST_MATROSKA_ID_SEEKENTRY:
5741 ret = gst_matroska_demux_parse_contents_seekentry (demux, ebml);
5742 /* Ignore EOS and errors here */
5743 if (ret != GST_FLOW_OK) {
5744 GST_DEBUG_OBJECT (demux, "Ignoring %s", gst_flow_get_name (ret));
5751 ret = gst_matroska_demux_parse_skip (demux, ebml, "SeekHead", id);
5756 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
5758 /* Sort clusters by position for easier searching */
5759 if (demux->clusters)
5760 g_array_sort (demux->clusters, (GCompareFunc) gst_matroska_cluster_compare);
5765 #define GST_FLOW_OVERFLOW GST_FLOW_CUSTOM_ERROR
5767 #define MAX_BLOCK_SIZE (15 * 1024 * 1024)
5769 static inline GstFlowReturn
5770 gst_matroska_demux_check_read_size (GstMatroskaDemux * demux, guint64 bytes)
5772 if (G_UNLIKELY (bytes > MAX_BLOCK_SIZE)) {
5773 /* only a few blocks are expected/allowed to be large,
5774 * and will be recursed into, whereas others will be read and must fit */
5775 if (demux->streaming) {
5776 /* fatal in streaming case, as we can't step over easily */
5777 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
5778 ("reading large block of size %" G_GUINT64_FORMAT " not supported; "
5779 "file might be corrupt.", bytes));
5780 return GST_FLOW_ERROR;
5782 /* indicate higher level to quietly give up */
5783 GST_DEBUG_OBJECT (demux,
5784 "too large block of size %" G_GUINT64_FORMAT, bytes);
5785 return GST_FLOW_ERROR;
5792 /* returns TRUE if we truely are in error state, and should give up */
5793 static inline gboolean
5794 gst_matroska_demux_check_parse_error (GstMatroskaDemux * demux)
5796 if (!demux->streaming && demux->next_cluster_offset > 0) {
5797 /* just repositioning to where next cluster should be and try from there */
5798 GST_WARNING_OBJECT (demux, "parse error, trying next cluster expected at %"
5799 G_GUINT64_FORMAT, demux->next_cluster_offset);
5800 demux->offset = demux->next_cluster_offset;
5801 demux->next_cluster_offset = 0;
5806 /* sigh, one last attempt above and beyond call of duty ...;
5807 * search for cluster mark following current pos */
5808 pos = demux->offset;
5809 GST_WARNING_OBJECT (demux, "parse error, looking for next cluster");
5810 if (gst_matroska_demux_search_cluster (demux, &pos) != GST_FLOW_OK) {
5811 /* did not work, give up */
5814 GST_DEBUG_OBJECT (demux, "... found at %" G_GUINT64_FORMAT, pos);
5815 /* try that position */
5816 demux->offset = pos;
5822 static inline GstFlowReturn
5823 gst_matroska_demux_flush (GstMatroskaDemux * demux, guint flush)
5825 GST_LOG_OBJECT (demux, "skipping %d bytes", flush);
5826 demux->offset += flush;
5827 if (demux->streaming) {
5830 /* hard to skip large blocks when streaming */
5831 ret = gst_matroska_demux_check_read_size (demux, flush);
5832 if (ret != GST_FLOW_OK)
5834 if (flush <= gst_adapter_available (demux->adapter))
5835 gst_adapter_flush (demux->adapter, flush);
5837 return GST_FLOW_UNEXPECTED;
5842 /* initializes @ebml with @bytes from input stream at current offset.
5843 * Returns UNEXPECTED if insufficient available,
5844 * ERROR if too much was attempted to read. */
5845 static inline GstFlowReturn
5846 gst_matroska_demux_take (GstMatroskaDemux * demux, guint64 bytes,
5849 GstBuffer *buffer = NULL;
5850 GstFlowReturn ret = GST_FLOW_OK;
5852 GST_LOG_OBJECT (demux, "taking %" G_GUINT64_FORMAT " bytes for parsing",
5854 ret = gst_matroska_demux_check_read_size (demux, bytes);
5855 if (G_UNLIKELY (ret != GST_FLOW_OK)) {
5856 if (!demux->streaming) {
5857 /* in pull mode, we can skip */
5858 if ((ret = gst_matroska_demux_flush (demux, bytes)) == GST_FLOW_OK)
5859 ret = GST_FLOW_OVERFLOW;
5861 /* otherwise fatal */
5862 ret = GST_FLOW_ERROR;
5866 if (demux->streaming) {
5867 if (gst_adapter_available (demux->adapter) >= bytes)
5868 buffer = gst_adapter_take_buffer (demux->adapter, bytes);
5870 ret = GST_FLOW_UNEXPECTED;
5872 ret = gst_matroska_demux_peek_bytes (demux, demux->offset, bytes, &buffer,
5874 if (G_LIKELY (buffer)) {
5875 gst_ebml_read_init (ebml, GST_ELEMENT_CAST (demux), buffer, demux->offset);
5876 demux->offset += bytes;
5883 gst_matroska_demux_check_seekability (GstMatroskaDemux * demux)
5886 gboolean seekable = FALSE;
5887 gint64 start = -1, stop = -1;
5889 query = gst_query_new_seeking (GST_FORMAT_BYTES);
5890 if (!gst_pad_peer_query (demux->sinkpad, query)) {
5891 GST_DEBUG_OBJECT (demux, "seeking query failed");
5895 gst_query_parse_seeking (query, NULL, &seekable, &start, &stop);
5897 /* try harder to query upstream size if we didn't get it the first time */
5898 if (seekable && stop == -1) {
5899 GstFormat fmt = GST_FORMAT_BYTES;
5901 GST_DEBUG_OBJECT (demux, "doing duration query to fix up unset stop");
5902 gst_pad_query_peer_duration (demux->sinkpad, &fmt, &stop);
5905 /* if upstream doesn't know the size, it's likely that it's not seekable in
5906 * practice even if it technically may be seekable */
5907 if (seekable && (start != 0 || stop <= start)) {
5908 GST_DEBUG_OBJECT (demux, "seekable but unknown start/stop -> disable");
5913 GST_INFO_OBJECT (demux, "seekable: %d (%" G_GUINT64_FORMAT " - %"
5914 G_GUINT64_FORMAT ")", seekable, start, stop);
5915 demux->seekable = seekable;
5917 gst_query_unref (query);
5920 static GstFlowReturn
5921 gst_matroska_demux_find_tracks (GstMatroskaDemux * demux)
5927 GstFlowReturn ret = GST_FLOW_OK;
5929 GST_WARNING_OBJECT (demux,
5930 "Found Cluster element before Tracks, searching Tracks");
5933 before_pos = demux->offset;
5935 /* Search Tracks element */
5937 ret = gst_matroska_demux_peek_id_length_pull (demux, &id, &length, &needed);
5938 if (ret != GST_FLOW_OK)
5941 if (id != GST_MATROSKA_ID_TRACKS) {
5942 /* we may be skipping large cluster here, so forego size check etc */
5943 /* ... but we can't skip undefined size; force error */
5944 if (length == G_MAXUINT64) {
5945 ret = gst_matroska_demux_check_read_size (demux, length);
5948 demux->offset += needed;
5949 demux->offset += length;
5954 /* will lead to track parsing ... */
5955 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
5960 demux->offset = before_pos;
5965 #define GST_READ_CHECK(stmt) \
5967 if (G_UNLIKELY ((ret = (stmt)) != GST_FLOW_OK)) { \
5968 if (ret == GST_FLOW_OVERFLOW) { \
5969 ret = GST_FLOW_OK; \
5975 static GstFlowReturn
5976 gst_matroska_demux_parse_id (GstMatroskaDemux * demux, guint32 id,
5977 guint64 length, guint needed)
5979 GstEbmlRead ebml = { 0, };
5980 GstFlowReturn ret = GST_FLOW_OK;
5983 GST_DEBUG_OBJECT (demux, "Parsing Element id 0x%x, "
5984 "size %" G_GUINT64_FORMAT ", prefix %d", id, length, needed);
5986 /* if we plan to read and parse this element, we need prefix (id + length)
5987 * and the contents */
5988 /* mind about overflow wrap-around when dealing with undefined size */
5990 if (G_LIKELY (length != G_MAXUINT64))
5993 switch (demux->state) {
5994 case GST_MATROSKA_DEMUX_STATE_START:
5996 case GST_EBML_ID_HEADER:
5997 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5998 ret = gst_matroska_demux_parse_header (demux, &ebml);
5999 if (ret != GST_FLOW_OK)
6001 demux->state = GST_MATROSKA_DEMUX_STATE_SEGMENT;
6002 gst_matroska_demux_check_seekability (demux);
6005 goto invalid_header;
6009 case GST_MATROSKA_DEMUX_STATE_SEGMENT:
6011 case GST_MATROSKA_ID_SEGMENT:
6012 /* eat segment prefix */
6013 GST_READ_CHECK (gst_matroska_demux_flush (demux, needed));
6014 GST_DEBUG_OBJECT (demux,
6015 "Found Segment start at offset %" G_GUINT64_FORMAT,
6017 /* seeks are from the beginning of the segment,
6018 * after the segment ID/length */
6019 demux->ebml_segment_start = demux->offset;
6020 demux->state = GST_MATROSKA_DEMUX_STATE_HEADER;
6023 GST_WARNING_OBJECT (demux,
6024 "Expected a Segment ID (0x%x), but received 0x%x!",
6025 GST_MATROSKA_ID_SEGMENT, id);
6026 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
6030 case GST_MATROSKA_DEMUX_STATE_SCANNING:
6031 if (id != GST_MATROSKA_ID_CLUSTER &&
6032 id != GST_MATROSKA_ID_CLUSTERTIMECODE)
6035 case GST_MATROSKA_DEMUX_STATE_HEADER:
6036 case GST_MATROSKA_DEMUX_STATE_DATA:
6037 case GST_MATROSKA_DEMUX_STATE_SEEK:
6039 case GST_MATROSKA_ID_SEGMENTINFO:
6040 if (!demux->segmentinfo_parsed) {
6041 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
6042 ret = gst_matroska_demux_parse_info (demux, &ebml);
6044 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
6047 case GST_MATROSKA_ID_TRACKS:
6048 if (!demux->tracks_parsed) {
6049 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
6050 ret = gst_matroska_demux_parse_tracks (demux, &ebml);
6052 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
6055 case GST_MATROSKA_ID_CLUSTER:
6056 if (G_UNLIKELY (!demux->tracks_parsed)) {
6057 if (demux->streaming) {
6058 GST_DEBUG_OBJECT (demux, "Cluster before Track");
6059 goto not_streamable;
6061 ret = gst_matroska_demux_find_tracks (demux);
6062 if (!demux->tracks_parsed)
6066 if (G_UNLIKELY (demux->state == GST_MATROSKA_DEMUX_STATE_HEADER)) {
6067 demux->state = GST_MATROSKA_DEMUX_STATE_DATA;
6068 demux->first_cluster_offset = demux->offset;
6069 GST_DEBUG_OBJECT (demux, "signaling no more pads");
6070 gst_element_no_more_pads (GST_ELEMENT (demux));
6071 /* send initial newsegment */
6072 gst_matroska_demux_send_event (demux,
6073 gst_event_new_new_segment (FALSE, 1.0,
6075 (demux->segment.duration >
6076 0) ? demux->segment.duration : -1, 0));
6078 demux->cluster_time = GST_CLOCK_TIME_NONE;
6079 demux->cluster_offset = demux->offset;
6080 if (G_UNLIKELY (!demux->seek_first && demux->seek_block)) {
6081 GST_DEBUG_OBJECT (demux, "seek target block %" G_GUINT64_FORMAT
6082 " not found in Cluster, trying next Cluster's first block instead",
6084 demux->seek_block = 0;
6086 demux->seek_first = FALSE;
6087 /* record next cluster for recovery */
6088 if (read != G_MAXUINT64)
6089 demux->next_cluster_offset = demux->cluster_offset + read;
6090 /* eat cluster prefix */
6091 gst_matroska_demux_flush (demux, needed);
6094 case GST_MATROSKA_ID_CLUSTERTIMECODE:
6098 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
6099 if ((ret = gst_ebml_read_uint (&ebml, &id, &num)) != GST_FLOW_OK)
6101 GST_DEBUG_OBJECT (demux, "ClusterTimeCode: %" G_GUINT64_FORMAT, num);
6102 demux->cluster_time = num;
6103 if (demux->element_index) {
6104 if (demux->element_index_writer_id == -1)
6105 gst_index_get_writer_id (demux->element_index,
6106 GST_OBJECT (demux), &demux->element_index_writer_id);
6107 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
6108 G_GUINT64_FORMAT " for writer id %d",
6109 GST_TIME_ARGS (demux->cluster_time), demux->cluster_offset,
6110 demux->element_index_writer_id);
6111 gst_index_add_association (demux->element_index,
6112 demux->element_index_writer_id, GST_ASSOCIATION_FLAG_KEY_UNIT,
6113 GST_FORMAT_TIME, demux->cluster_time,
6114 GST_FORMAT_BYTES, demux->cluster_offset, NULL);
6118 case GST_MATROSKA_ID_BLOCKGROUP:
6119 if (!gst_matroska_demux_seek_block (demux))
6121 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
6122 DEBUG_ELEMENT_START (demux, &ebml, "BlockGroup");
6123 if ((ret = gst_ebml_read_master (&ebml, &id)) == GST_FLOW_OK) {
6124 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
6125 &ebml, demux->cluster_time, demux->cluster_offset, FALSE);
6128 #ifdef MKVDEMUX_MODIFICATION
6129 if ((demux->segment.rate < 0.0) && (demux->found_videokeyframe == TRUE) && (demux->found_audioframe == TRUE))
6131 /* Naveen: we displayed at least one one audio block and one video key frame
6132 Now, goto previous cluster */
6135 guint64 duration = 0;
6136 GstClockTime time_position;
6137 GstMatroskaIndex *entry = NULL;
6140 for (i = 0; i < demux->src->len; i++)
6142 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->src, i);
6143 if (stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO)
6145 GST_DEBUG ("video track duration = %"G_GUINT64_FORMAT"position = %"GST_TIME_FORMAT"\n",
6146 stream->default_duration, GST_TIME_ARGS(stream->pos));
6147 duration = stream->default_duration;
6148 time_position = stream->pos;
6152 if((time_position - (minusone *demux->segment.rate)*((double)duration/1000000000))> 0)
6154 time_position -= (minusone *demux->segment.rate)*((double)duration/1000000000);
6161 for (i = 0; i < demux->src->len; i++)
6163 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->src, i);
6166 GST_OBJECT_LOCK (demux);
6167 if (stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO)
6169 if ((entry = gst_matroskademux_do_index_seek (demux, stream, time_position, -1, FALSE)) == NULL) {
6170 GST_DEBUG_OBJECT (demux, "No matching seek entry in index");
6173 GST_DEBUG_OBJECT (demux, "pos = %"G_GUINT64_FORMAT", track = %d, block = %d, time = %"GST_TIME_FORMAT"\n",
6174 entry->pos, entry->track, entry->block, GST_TIME_ARGS(entry->time));
6176 offset = entry->pos + demux->ebml_segment_start;
6177 if (offset >= gst_matroska_demux_get_length(demux))
6179 GST_INFO_OBJECT (demux, " Seek failed");
6182 demux->offset = offset;
6184 stream->pos = entry->time;
6185 stream->set_discont = TRUE;
6186 stream->last_flow = GST_FLOW_OK;
6187 if (stream->pos > 0.0)
6189 stream->eos = FALSE;
6194 GST_INFO_OBJECT (demux, "Reached EOS.....");
6196 demux->segment.last_stop = entry->time;
6198 GST_OBJECT_UNLOCK (demux);
6202 if (entry->time == 0.0)
6204 gst_segment_init (&demux->segment, GST_FORMAT_TIME);
6205 gst_segment_set_duration (&demux->segment, GST_FORMAT_TIME, demux->duration);
6207 /* send new_segment event with start =0 and stop = duration */
6208 demux->new_segment = gst_event_new_new_segment_full (TRUE,
6209 demux->segment.rate, demux->segment.applied_rate, demux->segment.format,
6210 demux->segment.start, demux->segment.stop, demux->segment.time);
6213 demux->found_videokeyframe = FALSE;
6214 demux->found_audioframe = FALSE;
6219 DEBUG_ELEMENT_STOP (demux, &ebml, "BlockGroup", ret);
6221 case GST_MATROSKA_ID_SIMPLEBLOCK:
6222 if (!gst_matroska_demux_seek_block (demux))
6224 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
6225 DEBUG_ELEMENT_START (demux, &ebml, "SimpleBlock");
6227 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
6228 &ebml, demux->cluster_time, demux->cluster_offset, TRUE);
6231 #ifdef MKVDEMUX_MODIFICATION
6232 if ((demux->segment.rate < 0.0) && (demux->found_videokeyframe == TRUE) && (demux->found_audioframe == TRUE))
6234 /* Naveen: we displayed at least one one audio block and one video key frame
6235 Now, goto previous cluster */
6238 guint64 duration = 0;
6239 GstClockTime time_position;
6240 GstMatroskaIndex *entry = NULL;
6243 for (i = 0; i < demux->src->len; i++)
6245 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->src, i);
6246 if (stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO)
6248 GST_DEBUG ("video track duration = %"G_GUINT64_FORMAT"position = %"GST_TIME_FORMAT"\n",
6249 stream->default_duration, GST_TIME_ARGS(stream->pos));
6250 duration = stream->default_duration;
6251 time_position = stream->pos;
6256 if((time_position - (minusone *demux->segment.rate)*((double)duration/1000000000))> 0)
6258 time_position -= (minusone *demux->segment.rate)*((double)duration/1000000000);
6265 for (i = 0; i < demux->src->len; i++)
6267 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->src, i);
6270 GST_OBJECT_LOCK (demux);
6271 if (stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO)
6274 if ((entry = gst_matroskademux_do_index_seek (demux, stream, time_position, -1, FALSE)) == NULL) {
6275 GST_DEBUG_OBJECT (demux, "No matching seek entry in index");
6278 GST_DEBUG_OBJECT (demux, "pos = %"G_GUINT64_FORMAT", track = %d, block = %d, time = %"GST_TIME_FORMAT"\n",
6279 entry->pos, entry->track, entry->block, GST_TIME_ARGS(entry->time));
6281 /* seek (relative to matroska segment) */
6287 offset = entry->pos + demux->ebml_segment_start;
6288 if (offset >= gst_matroska_demux_get_length(demux))
6290 GST_INFO_OBJECT (demux, " Seek failed");
6293 demux->offset = offset;
6299 stream->pos = entry->time;
6300 stream->set_discont = TRUE;
6301 stream->last_flow = GST_FLOW_OK;
6302 if (stream->pos > 0.0)
6304 stream->eos = FALSE;
6310 GST_INFO_OBJECT (demux, "Reached EOS.....");
6312 demux->segment.last_stop = entry->time;
6314 GST_OBJECT_UNLOCK (demux);
6318 if (entry->time == 0.0)
6322 gst_segment_init (&demux->segment, GST_FORMAT_TIME);
6323 gst_segment_set_duration (&demux->segment, GST_FORMAT_TIME, demux->duration);
6325 /* send new_segment event with start =0 and stop = duration */
6326 demux->new_segment = gst_event_new_new_segment_full (TRUE,
6327 demux->segment.rate, demux->segment.applied_rate, demux->segment.format,
6328 demux->segment.start, demux->segment.stop, demux->segment.time);
6332 demux->found_videokeyframe = FALSE;
6333 demux->found_audioframe = FALSE;
6338 DEBUG_ELEMENT_STOP (demux, &ebml, "SimpleBlock", ret);
6340 case GST_MATROSKA_ID_ATTACHMENTS:
6341 if (!demux->attachments_parsed) {
6342 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
6343 ret = gst_matroska_demux_parse_attachments (demux, &ebml);
6345 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
6348 case GST_MATROSKA_ID_TAGS:
6349 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
6350 ret = gst_matroska_demux_parse_metadata (demux, &ebml);
6352 case GST_MATROSKA_ID_CHAPTERS:
6353 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
6354 ret = gst_matroska_demux_parse_chapters (demux, &ebml);
6356 case GST_MATROSKA_ID_SEEKHEAD:
6357 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
6358 ret = gst_matroska_demux_parse_contents (demux, &ebml);
6360 case GST_MATROSKA_ID_CUES:
6361 if (demux->index_parsed) {
6362 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
6365 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
6366 ret = gst_matroska_demux_parse_index (demux, &ebml);
6367 /* only push based; delayed index building */
6368 if (ret == GST_FLOW_OK
6369 && demux->state == GST_MATROSKA_DEMUX_STATE_SEEK) {
6372 GST_OBJECT_LOCK (demux);
6373 event = demux->seek_event;
6374 demux->seek_event = NULL;
6375 GST_OBJECT_UNLOCK (demux);
6378 /* unlikely to fail, since we managed to seek to this point */
6379 if (!gst_matroska_demux_handle_seek_event (demux, NULL, event))
6381 /* resume data handling, main thread clear to seek again */
6382 GST_OBJECT_LOCK (demux);
6383 demux->state = GST_MATROSKA_DEMUX_STATE_DATA;
6384 GST_OBJECT_UNLOCK (demux);
6387 case GST_MATROSKA_ID_POSITION:
6388 case GST_MATROSKA_ID_PREVSIZE:
6389 case GST_MATROSKA_ID_ENCRYPTEDBLOCK:
6390 case GST_MATROSKA_ID_SILENTTRACKS:
6391 GST_DEBUG_OBJECT (demux,
6392 "Skipping Cluster subelement 0x%x - ignoring", id);
6396 GST_DEBUG_OBJECT (demux, "skipping Element 0x%x", id);
6397 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
6403 if (ret == GST_FLOW_PARSE)
6407 gst_ebml_read_clear (&ebml);
6413 /* simply exit, maybe not enough data yet */
6414 /* no ebml to clear if read error */
6419 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
6420 ("Failed to parse Element 0x%x", id));
6421 ret = GST_FLOW_ERROR;
6426 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
6427 ("File layout does not permit streaming"));
6428 ret = GST_FLOW_ERROR;
6433 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
6434 ("No Tracks element found"));
6435 ret = GST_FLOW_ERROR;
6440 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Invalid header"));
6441 ret = GST_FLOW_ERROR;
6446 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Failed to seek"));
6447 ret = GST_FLOW_ERROR;
6453 gst_matroska_demux_loop (GstPad * pad)
6455 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (pad));
6461 /* If we have to close a segment, send a new segment to do this now */
6462 if (G_LIKELY (demux->state == GST_MATROSKA_DEMUX_STATE_DATA)) {
6463 if (G_UNLIKELY (demux->close_segment)) {
6464 gst_matroska_demux_send_event (demux, demux->close_segment);
6465 demux->close_segment = NULL;
6467 if (G_UNLIKELY (demux->new_segment)) {
6468 gst_matroska_demux_send_event (demux, demux->new_segment);
6469 demux->new_segment = NULL;
6473 ret = gst_matroska_demux_peek_id_length_pull (demux, &id, &length, &needed);
6474 if (ret == GST_FLOW_UNEXPECTED)
6476 if (ret != GST_FLOW_OK) {
6477 if (gst_matroska_demux_check_parse_error (demux))
6483 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
6484 "size %" G_GUINT64_FORMAT ", needed %d", demux->offset, id,
6487 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
6488 if (ret == GST_FLOW_UNEXPECTED)
6490 if (ret != GST_FLOW_OK)
6493 /* check if we're at the end of a configured segment */
6494 if (G_LIKELY (demux->src->len)) {
6497 g_assert (demux->num_streams == demux->src->len);
6498 for (i = 0; i < demux->src->len; i++) {
6499 GstMatroskaTrackContext *context = g_ptr_array_index (demux->src, i);
6500 GST_DEBUG_OBJECT (context->pad, "pos %" GST_TIME_FORMAT,
6501 GST_TIME_ARGS (context->pos));
6502 if (context->eos == FALSE)
6506 GST_INFO_OBJECT (demux, "All streams are EOS");
6507 ret = GST_FLOW_UNEXPECTED;
6512 if (G_UNLIKELY (demux->offset == gst_matroska_demux_get_length (demux))) {
6513 GST_LOG_OBJECT (demux, "Reached end of stream");
6514 ret = GST_FLOW_UNEXPECTED;
6523 if (demux->segment.rate < 0.0) {
6524 ret = gst_matroska_demux_seek_to_previous_keyframe (demux);
6525 if (ret == GST_FLOW_OK)
6532 const gchar *reason = gst_flow_get_name (ret);
6533 gboolean push_eos = FALSE;
6535 GST_LOG_OBJECT (demux, "pausing task, reason %s", reason);
6536 demux->segment_running = FALSE;
6537 gst_pad_pause_task (demux->sinkpad);
6539 if (ret == GST_FLOW_UNEXPECTED) {
6540 /* perform EOS logic */
6542 /* Close the segment, i.e. update segment stop with the duration
6543 * if no stop was set */
6544 if (GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) &&
6545 !GST_CLOCK_TIME_IS_VALID (demux->segment.stop)) {
6547 gst_event_new_new_segment_full (TRUE, demux->segment.rate,
6548 demux->segment.applied_rate, demux->segment.format,
6549 demux->segment.start,
6550 MAX (demux->last_stop_end, demux->segment.start),
6551 demux->segment.time);
6552 gst_matroska_demux_send_event (demux, event);
6555 if (demux->segment.flags & GST_SEEK_FLAG_SEGMENT) {
6558 /* for segment playback we need to post when (in stream time)
6559 * we stopped, this is either stop (when set) or the duration. */
6560 if ((stop = demux->segment.stop) == -1)
6561 stop = demux->last_stop_end;
6563 GST_LOG_OBJECT (demux, "Sending segment done, at end of segment");
6564 gst_element_post_message (GST_ELEMENT (demux),
6565 gst_message_new_segment_done (GST_OBJECT (demux), GST_FORMAT_TIME,
6570 } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_UNEXPECTED) {
6571 /* for fatal errors we post an error message */
6572 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
6573 ("stream stopped, reason %s", reason));
6577 /* send EOS, and prevent hanging if no streams yet */
6578 GST_LOG_OBJECT (demux, "Sending EOS, at end of stream");
6579 if (!gst_matroska_demux_send_event (demux, gst_event_new_eos ()) &&
6580 (ret == GST_FLOW_UNEXPECTED)) {
6581 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
6582 (NULL), ("got eos but no streams (yet)"));
6590 * Create and push a flushing seek event upstream
6593 perform_seek_to_offset (GstMatroskaDemux * demux, guint64 offset)
6598 GST_DEBUG_OBJECT (demux, "Seeking to %" G_GUINT64_FORMAT, offset);
6601 gst_event_new_seek (1.0, GST_FORMAT_BYTES,
6602 GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, GST_SEEK_TYPE_SET, offset,
6603 GST_SEEK_TYPE_NONE, -1);
6605 res = gst_pad_push_event (demux->sinkpad, event);
6607 /* newsegment event will update offset */
6611 static const guint8 *
6612 gst_matroska_demux_peek_adapter (GstMatroskaDemux * demux, guint peek)
6614 return gst_adapter_peek (demux->adapter, peek);
6617 static GstFlowReturn
6618 gst_matroska_demux_peek_id_length_push (GstMatroskaDemux * demux, guint32 * _id,
6619 guint64 * _length, guint * _needed)
6621 return gst_ebml_peek_id_length (_id, _length, _needed,
6622 (GstPeekData) gst_matroska_demux_peek_adapter, (gpointer) demux,
6623 GST_ELEMENT_CAST (demux), demux->offset);
6626 static GstFlowReturn
6627 gst_matroska_demux_chain (GstPad * pad, GstBuffer * buffer)
6629 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (pad));
6631 GstFlowReturn ret = GST_FLOW_OK;
6636 if (G_UNLIKELY (GST_BUFFER_IS_DISCONT (buffer))) {
6637 GST_DEBUG_OBJECT (demux, "got DISCONT");
6638 gst_adapter_clear (demux->adapter);
6639 GST_OBJECT_LOCK (demux);
6640 gst_matroska_demux_reset_streams (demux, GST_CLOCK_TIME_NONE, FALSE);
6641 GST_OBJECT_UNLOCK (demux);
6644 gst_adapter_push (demux->adapter, buffer);
6648 available = gst_adapter_available (demux->adapter);
6650 ret = gst_matroska_demux_peek_id_length_push (demux, &id, &length, &needed);
6651 if (G_UNLIKELY (ret != GST_FLOW_OK && ret != GST_FLOW_UNEXPECTED))
6654 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
6655 "size %" G_GUINT64_FORMAT ", needed %d, available %d", demux->offset, id,
6656 length, needed, available);
6658 if (needed > available)
6661 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
6662 if (ret == GST_FLOW_UNEXPECTED) {
6663 /* need more data */
6665 } else if (ret != GST_FLOW_OK) {
6672 gst_matroska_demux_handle_sink_event (GstPad * pad, GstEvent * event)
6674 gboolean res = TRUE;
6675 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (pad));
6677 GST_DEBUG_OBJECT (demux,
6678 "have event type %s: %p on sink pad", GST_EVENT_TYPE_NAME (event), event);
6680 switch (GST_EVENT_TYPE (event)) {
6681 case GST_EVENT_NEWSEGMENT:
6684 gdouble rate, arate;
6685 gint64 start, stop, time = 0;
6689 /* some debug output */
6690 gst_segment_init (&segment, GST_FORMAT_UNDEFINED);
6691 gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format,
6692 &start, &stop, &time);
6693 gst_segment_set_newsegment_full (&segment, update, rate, arate, format,
6695 GST_DEBUG_OBJECT (demux,
6696 "received format %d newsegment %" GST_SEGMENT_FORMAT, format,
6699 if (demux->state < GST_MATROSKA_DEMUX_STATE_DATA) {
6700 GST_DEBUG_OBJECT (demux, "still starting");
6704 /* we only expect a BYTE segment, e.g. following a seek */
6705 if (format != GST_FORMAT_BYTES) {
6706 GST_DEBUG_OBJECT (demux, "unsupported segment format, ignoring");
6710 GST_DEBUG_OBJECT (demux, "clearing segment state");
6711 /* clear current segment leftover */
6712 gst_adapter_clear (demux->adapter);
6713 /* and some streaming setup */
6714 demux->offset = start;
6715 /* do not know where we are;
6716 * need to come across a cluster and generate newsegment */
6717 demux->segment.last_stop = GST_CLOCK_TIME_NONE;
6718 demux->cluster_time = GST_CLOCK_TIME_NONE;
6719 demux->cluster_offset = 0;
6720 demux->need_newsegment = TRUE;
6721 /* but keep some of the upstream segment */
6722 demux->segment.rate = rate;
6724 /* chain will send initial newsegment after pads have been added,
6725 * or otherwise come up with one */
6726 GST_DEBUG_OBJECT (demux, "eating event");
6727 gst_event_unref (event);
6733 if (demux->state != GST_MATROSKA_DEMUX_STATE_DATA) {
6734 gst_event_unref (event);
6735 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
6736 (NULL), ("got eos and didn't receive a complete header object"));
6737 } else if (demux->num_streams == 0) {
6738 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
6739 (NULL), ("got eos but no streams (yet)"));
6741 gst_matroska_demux_send_event (demux, event);
6745 case GST_EVENT_FLUSH_STOP:
6747 gst_adapter_clear (demux->adapter);
6748 GST_OBJECT_LOCK (demux);
6749 gst_matroska_demux_reset_streams (demux, GST_CLOCK_TIME_NONE, TRUE);
6750 GST_OBJECT_UNLOCK (demux);
6751 demux->segment.last_stop = GST_CLOCK_TIME_NONE;
6752 demux->cluster_time = GST_CLOCK_TIME_NONE;
6753 demux->cluster_offset = 0;
6757 res = gst_pad_event_default (pad, event);
6765 gst_matroska_demux_sink_activate (GstPad * sinkpad)
6767 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (sinkpad));
6769 if (gst_pad_check_pull_range (sinkpad)) {
6770 GST_DEBUG ("going to pull mode");
6771 demux->streaming = FALSE;
6772 return gst_pad_activate_pull (sinkpad, TRUE);
6774 GST_DEBUG ("going to push (streaming) mode");
6775 demux->streaming = TRUE;
6776 return gst_pad_activate_push (sinkpad, TRUE);
6783 gst_matroska_demux_sink_activate_pull (GstPad * sinkpad, gboolean active)
6785 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (sinkpad));
6788 /* if we have a scheduler we can start the task */
6789 demux->segment_running = TRUE;
6790 gst_pad_start_task (sinkpad, (GstTaskFunction) gst_matroska_demux_loop,
6793 demux->segment_running = FALSE;
6794 gst_pad_stop_task (sinkpad);
6801 gst_duration_to_fraction (guint64 duration, gint * dest_n, gint * dest_d)
6803 static const int common_den[] = { 1, 2, 3, 4, 1001 };
6808 for (i = 0; i < G_N_ELEMENTS (common_den); i++) {
6810 n = floor (0.5 + (d * 1e9) / duration);
6811 a = gst_util_uint64_scale_int (1000000000, d, n);
6812 if (duration >= a - 1 && duration <= a + 1) {
6817 gst_util_double_to_fraction (1e9 / duration, &n, &d);
6826 gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext *
6827 videocontext, const gchar * codec_id, guint8 * data, guint size,
6828 gchar ** codec_name, guint32 * riff_fourcc)
6830 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) videocontext;
6831 GstCaps *caps = NULL;
6833 g_assert (videocontext != NULL);
6834 g_assert (codec_name != NULL);
6836 context->send_xiph_headers = FALSE;
6837 context->send_flac_headers = FALSE;
6838 context->send_speex_headers = FALSE;
6843 /* TODO: check if we have all codec types from matroska-ids.h
6844 * check if we have to do more special things with codec_private
6847 * GST_MATROSKA_CODEC_ID_VIDEO_QUICKTIME
6848 * GST_MATROSKA_CODEC_ID_VIDEO_SNOW
6851 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VFW_FOURCC)) {
6852 gst_riff_strf_vids *vids = NULL;
6855 GstBuffer *buf = NULL;
6857 vids = (gst_riff_strf_vids *) data;
6859 /* assure size is big enough */
6861 GST_WARNING ("Too small BITMAPINFOHEADER (%d bytes)", size);
6864 if (size < sizeof (gst_riff_strf_vids)) {
6865 vids = g_new (gst_riff_strf_vids, 1);
6866 memcpy (vids, data, size);
6869 /* little-endian -> byte-order */
6870 vids->size = GUINT32_FROM_LE (vids->size);
6871 vids->width = GUINT32_FROM_LE (vids->width);
6872 vids->height = GUINT32_FROM_LE (vids->height);
6873 vids->planes = GUINT16_FROM_LE (vids->planes);
6874 vids->bit_cnt = GUINT16_FROM_LE (vids->bit_cnt);
6875 vids->compression = GUINT32_FROM_LE (vids->compression);
6876 vids->image_size = GUINT32_FROM_LE (vids->image_size);
6877 vids->xpels_meter = GUINT32_FROM_LE (vids->xpels_meter);
6878 vids->ypels_meter = GUINT32_FROM_LE (vids->ypels_meter);
6879 vids->num_colors = GUINT32_FROM_LE (vids->num_colors);
6880 vids->imp_colors = GUINT32_FROM_LE (vids->imp_colors);
6882 if (size > sizeof (gst_riff_strf_vids)) { /* some extra_data */
6883 buf = gst_buffer_new_and_alloc (size - sizeof (gst_riff_strf_vids));
6884 memcpy (GST_BUFFER_DATA (buf),
6885 (guint8 *) vids + sizeof (gst_riff_strf_vids),
6886 GST_BUFFER_SIZE (buf));
6890 *riff_fourcc = vids->compression;
6892 caps = gst_riff_create_video_caps (vids->compression, NULL, vids,
6893 buf, NULL, codec_name);
6896 GST_WARNING ("Unhandled RIFF fourcc %" GST_FOURCC_FORMAT,
6897 GST_FOURCC_ARGS (vids->compression));
6901 gst_buffer_unref (buf);
6903 if (vids != (gst_riff_strf_vids *) data)
6906 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_UNCOMPRESSED)) {
6909 switch (videocontext->fourcc) {
6910 case GST_MAKE_FOURCC ('I', '4', '2', '0'):
6911 *codec_name = g_strdup ("Raw planar YUV 4:2:0");
6912 fourcc = videocontext->fourcc;
6914 case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
6915 *codec_name = g_strdup ("Raw packed YUV 4:2:2");
6916 fourcc = videocontext->fourcc;
6918 case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
6919 *codec_name = g_strdup ("Raw packed YUV 4:2:0");
6920 fourcc = videocontext->fourcc;
6922 case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
6923 *codec_name = g_strdup ("Raw packed YUV 4:2:2");
6924 fourcc = videocontext->fourcc;
6926 case GST_MAKE_FOURCC ('A', 'Y', 'U', 'V'):
6927 *codec_name = g_strdup ("Raw packed YUV 4:4:4 with alpha channel");
6928 fourcc = videocontext->fourcc;
6932 GST_DEBUG ("Unknown fourcc %" GST_FOURCC_FORMAT,
6933 GST_FOURCC_ARGS (videocontext->fourcc));
6937 caps = gst_caps_new_simple ("video/x-raw-yuv",
6938 "format", GST_TYPE_FOURCC, fourcc, NULL);
6939 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_SP)) {
6940 caps = gst_caps_new_simple ("video/x-divx",
6941 "divxversion", G_TYPE_INT, 4, NULL);
6942 *codec_name = g_strdup ("MPEG-4 simple profile");
6943 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP) ||
6944 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AP)) {
6946 caps = gst_caps_new_full (gst_structure_new ("video/x-divx",
6947 "divxversion", G_TYPE_INT, 5, NULL),
6948 gst_structure_new ("video/x-xvid", NULL),
6949 gst_structure_new ("video/mpeg",
6950 "mpegversion", G_TYPE_INT, 4,
6951 "systemstream", G_TYPE_BOOLEAN, FALSE, NULL), NULL);
6953 caps = gst_caps_new_simple ("video/mpeg",
6954 "mpegversion", G_TYPE_INT, 4,
6955 "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
6957 GstBuffer *priv = gst_buffer_new_and_alloc (size);
6959 memcpy (GST_BUFFER_DATA (priv), data, size);
6960 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
6961 gst_buffer_unref (priv);
6963 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP))
6964 *codec_name = g_strdup ("MPEG-4 advanced simple profile");
6966 *codec_name = g_strdup ("MPEG-4 advanced profile");
6967 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MSMPEG4V3)) {
6969 caps = gst_caps_new_full (gst_structure_new ("video/x-divx",
6970 "divxversion", G_TYPE_INT, 3, NULL),
6971 gst_structure_new ("video/x-msmpeg",
6972 "msmpegversion", G_TYPE_INT, 43, NULL), NULL);
6974 caps = gst_caps_new_simple ("video/x-msmpeg",
6975 "msmpegversion", G_TYPE_INT, 43, NULL);
6976 *codec_name = g_strdup ("Microsoft MPEG-4 v.3");
6977 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1) ||
6978 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG2)) {
6981 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1))
6986 caps = gst_caps_new_simple ("video/mpeg",
6987 "systemstream", G_TYPE_BOOLEAN, FALSE,
6988 "mpegversion", G_TYPE_INT, mpegversion, NULL);
6989 *codec_name = g_strdup_printf ("MPEG-%d video", mpegversion);
6990 context->postprocess_frame = gst_matroska_demux_add_mpeg_seq_header;
6991 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MJPEG)) {
6992 caps = gst_caps_new_simple ("image/jpeg", NULL);
6993 *codec_name = g_strdup ("Motion-JPEG");
6994 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AVC)) {
6995 caps = gst_caps_new_simple ("video/x-h264", NULL);
6997 GstBuffer *priv = gst_buffer_new_and_alloc (size);
6999 /* First byte is the version, second is the profile indication, and third
7000 * is the 5 contraint_set_flags and 3 reserved bits. Fourth byte is the
7001 * level indication. */
7002 gst_codec_utils_h264_caps_set_level_and_profile (caps, data + 1,
7005 memcpy (GST_BUFFER_DATA (priv), data, size);
7006 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
7007 gst_buffer_unref (priv);
7009 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "avc",
7010 "alignment", G_TYPE_STRING, "au", NULL);
7012 GST_WARNING ("No codec data found, assuming output is byte-stream");
7013 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
7016 *codec_name = g_strdup ("H264");
7017 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1)) ||
7018 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2)) ||
7019 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3)) ||
7020 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))) {
7021 gint rmversion = -1;
7023 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1))
7025 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2))
7027 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3))
7029 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))
7032 caps = gst_caps_new_simple ("video/x-pn-realvideo",
7033 "rmversion", G_TYPE_INT, rmversion, NULL);
7034 GST_DEBUG ("data:%p, size:0x%x", data, size);
7035 /* We need to extract the extradata ! */
7036 if (data && (size >= 0x22)) {
7041 subformat = GST_READ_UINT32_BE (data + 0x1a);
7042 rformat = GST_READ_UINT32_BE (data + 0x1e);
7044 priv = gst_buffer_new_and_alloc (size - 0x1a);
7046 memcpy (GST_BUFFER_DATA (priv), data + 0x1a, size - 0x1a);
7047 gst_caps_set_simple (caps,
7048 "codec_data", GST_TYPE_BUFFER, priv,
7049 "format", G_TYPE_INT, rformat,
7050 "subformat", G_TYPE_INT, subformat, NULL);
7051 gst_buffer_unref (priv);
7054 *codec_name = g_strdup_printf ("RealVideo %d.0", rmversion);
7055 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_THEORA)) {
7056 caps = gst_caps_new_simple ("video/x-theora", NULL);
7057 context->send_xiph_headers = TRUE;
7058 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_DIRAC)) {
7059 caps = gst_caps_new_simple ("video/x-dirac", NULL);
7060 *codec_name = g_strdup_printf ("Dirac");
7061 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8)) {
7062 caps = gst_caps_new_simple ("video/x-vp8", NULL);
7063 *codec_name = g_strdup_printf ("On2 VP8");
7065 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
7071 GstStructure *structure;
7073 for (i = 0; i < gst_caps_get_size (caps); i++) {
7074 structure = gst_caps_get_structure (caps, i);
7076 /* FIXME: use the real unit here! */
7077 GST_DEBUG ("video size %dx%d, target display size %dx%d (any unit)",
7078 videocontext->pixel_width,
7079 videocontext->pixel_height,
7080 videocontext->display_width, videocontext->display_height);
7082 /* pixel width and height are the w and h of the video in pixels */
7083 if (videocontext->pixel_width > 0 && videocontext->pixel_height > 0) {
7084 gint w = videocontext->pixel_width;
7086 gint h = videocontext->pixel_height;
7088 gst_structure_set (structure,
7089 "width", G_TYPE_INT, w, "height", G_TYPE_INT, h, NULL);
7092 if (videocontext->display_width > 0 && videocontext->display_height > 0) {
7095 /* calculate the pixel aspect ratio using the display and pixel w/h */
7096 n = videocontext->display_width * videocontext->pixel_height;
7097 d = videocontext->display_height * videocontext->pixel_width;
7098 GST_DEBUG ("setting PAR to %d/%d", n, d);
7099 gst_structure_set (structure, "pixel-aspect-ratio",
7101 videocontext->display_width * videocontext->pixel_height,
7102 videocontext->display_height * videocontext->pixel_width, NULL);
7105 if (videocontext->default_fps > 0.0) {
7106 GValue fps_double = { 0, };
7107 GValue fps_fraction = { 0, };
7109 g_value_init (&fps_double, G_TYPE_DOUBLE);
7110 g_value_init (&fps_fraction, GST_TYPE_FRACTION);
7111 g_value_set_double (&fps_double, videocontext->default_fps);
7112 g_value_transform (&fps_double, &fps_fraction);
7114 GST_DEBUG ("using default fps %f", videocontext->default_fps);
7116 gst_structure_set_value (structure, "framerate", &fps_fraction);
7117 g_value_unset (&fps_double);
7118 g_value_unset (&fps_fraction);
7119 } else if (context->default_duration > 0) {
7122 gst_duration_to_fraction (context->default_duration, &fps_n, &fps_d);
7124 GST_DEBUG ("using default duration %" G_GUINT64_FORMAT
7125 " framerate %d/%d", context->default_duration, fps_n, fps_d);
7127 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
7128 fps_n, fps_d, NULL);
7130 /* sort of a hack to get most codecs to support,
7131 * even if the default_duration is missing */
7132 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
7136 if (videocontext->parent.flags & GST_MATROSKA_VIDEOTRACK_INTERLACED)
7137 gst_structure_set (structure, "interlaced", G_TYPE_BOOLEAN, TRUE, NULL);
7140 gst_caps_do_simplify (caps);
7147 * Some AAC specific code... *sigh*
7148 * FIXME: maybe we should use '15' and code the sample rate explicitly
7149 * if the sample rate doesn't match the predefined rates exactly? (tpm)
7153 aac_rate_idx (gint rate)
7157 else if (75132 <= rate)
7159 else if (55426 <= rate)
7161 else if (46009 <= rate)
7163 else if (37566 <= rate)
7165 else if (27713 <= rate)
7167 else if (23004 <= rate)
7169 else if (18783 <= rate)
7171 else if (13856 <= rate)
7173 else if (11502 <= rate)
7175 else if (9391 <= rate)
7182 aac_profile_idx (const gchar * codec_id)
7186 if (strlen (codec_id) <= 12)
7188 else if (!strncmp (&codec_id[12], "MAIN", 4))
7190 else if (!strncmp (&codec_id[12], "LC", 2))
7192 else if (!strncmp (&codec_id[12], "SSR", 3))
7200 #define AAC_SYNC_EXTENSION_TYPE 0x02b7
7203 gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext *
7204 audiocontext, const gchar * codec_id, guint8 * data, guint size,
7205 gchar ** codec_name, guint16 * riff_audio_fmt)
7207 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) audiocontext;
7208 GstCaps *caps = NULL;
7210 g_assert (audiocontext != NULL);
7211 g_assert (codec_name != NULL);
7214 *riff_audio_fmt = 0;
7216 context->send_xiph_headers = FALSE;
7217 context->send_flac_headers = FALSE;
7218 context->send_speex_headers = FALSE;
7220 /* TODO: check if we have all codec types from matroska-ids.h
7221 * check if we have to do more special things with codec_private
7222 * check if we need bitdepth in different places too
7223 * implement channel position magic
7225 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID9
7226 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID10
7227 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDMC
7228 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDM2
7231 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1) ||
7232 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2) ||
7233 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L3)) {
7236 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1))
7238 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2))
7243 caps = gst_caps_new_simple ("audio/mpeg",
7244 "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, layer, NULL);
7245 *codec_name = g_strdup_printf ("MPEG-1 layer %d", layer);
7246 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE) ||
7247 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_LE)) {
7250 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE))
7251 endianness = G_BIG_ENDIAN;
7253 endianness = G_LITTLE_ENDIAN;
7255 caps = gst_caps_new_simple ("audio/x-raw-int",
7256 "width", G_TYPE_INT, audiocontext->bitdepth,
7257 "depth", G_TYPE_INT, audiocontext->bitdepth,
7258 "signed", G_TYPE_BOOLEAN, audiocontext->bitdepth != 8,
7259 "endianness", G_TYPE_INT, endianness, NULL);
7261 *codec_name = g_strdup_printf ("Raw %d-bit PCM audio",
7262 audiocontext->bitdepth);
7263 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_FLOAT)) {
7264 caps = gst_caps_new_simple ("audio/x-raw-float",
7265 "endianness", G_TYPE_INT, G_LITTLE_ENDIAN,
7266 "width", G_TYPE_INT, audiocontext->bitdepth, NULL);
7267 *codec_name = g_strdup_printf ("Raw %d-bit floating-point audio",
7268 audiocontext->bitdepth);
7269 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AC3,
7270 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AC3))) {
7271 caps = gst_caps_new_simple ("audio/x-ac3",
7272 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
7273 *codec_name = g_strdup ("AC-3 audio");
7274 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_EAC3,
7275 strlen (GST_MATROSKA_CODEC_ID_AUDIO_EAC3))) {
7276 caps = gst_caps_new_simple ("audio/x-eac3",
7277 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
7278 *codec_name = g_strdup ("E-AC-3 audio");
7279 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_DTS)) {
7280 caps = gst_caps_new_simple ("audio/x-dts", NULL);
7281 *codec_name = g_strdup ("DTS audio");
7282 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_VORBIS)) {
7283 caps = gst_caps_new_simple ("audio/x-vorbis", NULL);
7284 context->send_xiph_headers = TRUE;
7285 /* vorbis decoder does tags */
7286 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_FLAC)) {
7287 caps = gst_caps_new_simple ("audio/x-flac", NULL);
7288 context->send_flac_headers = TRUE;
7289 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_SPEEX)) {
7290 caps = gst_caps_new_simple ("audio/x-speex", NULL);
7291 context->send_speex_headers = TRUE;
7292 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_ACM)) {
7293 gst_riff_strf_auds auds;
7296 GstBuffer *codec_data = gst_buffer_new ();
7298 /* little-endian -> byte-order */
7299 auds.format = GST_READ_UINT16_LE (data);
7300 auds.channels = GST_READ_UINT16_LE (data + 2);
7301 auds.rate = GST_READ_UINT32_LE (data + 4);
7302 auds.av_bps = GST_READ_UINT32_LE (data + 8);
7303 auds.blockalign = GST_READ_UINT16_LE (data + 12);
7304 auds.size = GST_READ_UINT16_LE (data + 16);
7306 /* 18 is the waveformatex size */
7307 gst_buffer_set_data (codec_data, data + 18, auds.size);
7310 *riff_audio_fmt = auds.format;
7312 caps = gst_riff_create_audio_caps (auds.format, NULL, &auds, NULL,
7313 codec_data, codec_name);
7314 gst_buffer_unref (codec_data);
7317 GST_WARNING ("Unhandled RIFF audio format 0x%02x", auds.format);
7320 } else if (g_str_has_prefix (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC)) {
7321 GstBuffer *priv = NULL;
7323 gint rate_idx, profile;
7324 guint8 *data = NULL;
7326 /* unspecified AAC profile with opaque private codec data */
7327 if (strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC) == 0) {
7328 if (context->codec_priv_size >= 2) {
7329 guint obj_type, freq_index, explicit_freq_bytes = 0;
7331 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
7333 freq_index = (GST_READ_UINT16_BE (context->codec_priv) & 0x780) >> 7;
7334 obj_type = (GST_READ_UINT16_BE (context->codec_priv) & 0xF800) >> 11;
7335 if (freq_index == 15)
7336 explicit_freq_bytes = 3;
7337 GST_DEBUG ("obj_type = %u, freq_index = %u", obj_type, freq_index);
7338 priv = gst_buffer_new_and_alloc (context->codec_priv_size);
7339 memcpy (GST_BUFFER_DATA (priv), context->codec_priv,
7340 context->codec_priv_size);
7341 /* assume SBR if samplerate <= 24kHz */
7342 if (obj_type == 5 || (freq_index >= 6 && freq_index != 15) ||
7343 (context->codec_priv_size == (5 + explicit_freq_bytes))) {
7344 audiocontext->samplerate *= 2;
7347 GST_WARNING ("Opaque A_AAC codec ID, but no codec private data");
7348 /* this is pretty broken;
7349 * maybe we need to make up some default private,
7350 * or maybe ADTS data got dumped in.
7351 * Let's set up some private data now, and check actual data later */
7352 /* just try this and see what happens ... */
7353 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
7354 context->postprocess_frame = gst_matroska_demux_check_aac;
7358 /* make up decoder-specific data if it is not supplied */
7360 priv = gst_buffer_new_and_alloc (5);
7361 data = GST_BUFFER_DATA (priv);
7362 rate_idx = aac_rate_idx (audiocontext->samplerate);
7363 profile = aac_profile_idx (codec_id);
7365 data[0] = ((profile + 1) << 3) | ((rate_idx & 0xE) >> 1);
7366 data[1] = ((rate_idx & 0x1) << 7) | (audiocontext->channels << 3);
7367 GST_BUFFER_SIZE (priv) = 2;
7369 if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2,
7370 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2))) {
7372 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4,
7373 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4))) {
7376 if (g_strrstr (codec_id, "SBR")) {
7377 /* HE-AAC (aka SBR AAC) */
7378 audiocontext->samplerate *= 2;
7379 rate_idx = aac_rate_idx (audiocontext->samplerate);
7380 data[2] = AAC_SYNC_EXTENSION_TYPE >> 3;
7381 data[3] = ((AAC_SYNC_EXTENSION_TYPE & 0x07) << 5) | 5;
7382 data[4] = (1 << 7) | (rate_idx << 3);
7383 GST_BUFFER_SIZE (priv) = 5;
7386 gst_buffer_unref (priv);
7388 GST_ERROR ("Unknown AAC profile and no codec private data");
7393 caps = gst_caps_new_simple ("audio/mpeg",
7394 "mpegversion", G_TYPE_INT, mpegversion,
7395 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
7396 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
7397 *codec_name = g_strdup_printf ("MPEG-%d AAC audio", mpegversion);
7399 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TTA)) {
7400 caps = gst_caps_new_simple ("audio/x-tta",
7401 "width", G_TYPE_INT, audiocontext->bitdepth, NULL);
7402 *codec_name = g_strdup ("TTA audio");
7403 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_WAVPACK4)) {
7404 caps = gst_caps_new_simple ("audio/x-wavpack",
7405 "width", G_TYPE_INT, audiocontext->bitdepth,
7406 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
7407 *codec_name = g_strdup ("Wavpack audio");
7408 context->postprocess_frame = gst_matroska_demux_add_wvpk_header;
7409 audiocontext->wvpk_block_index = 0;
7410 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4)) ||
7411 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4)) ||
7412 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))) {
7413 gint raversion = -1;
7415 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4))
7417 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))
7422 caps = gst_caps_new_simple ("audio/x-pn-realaudio",
7423 "raversion", G_TYPE_INT, raversion, NULL);
7424 /* Extract extra information from caps, mapping varies based on codec */
7425 if (data && (size >= 0x50)) {
7432 guint extra_data_size;
7434 GST_ERROR ("real audio raversion:%d", raversion);
7435 if (raversion == 8) {
7437 flavor = GST_READ_UINT16_BE (data + 22);
7438 packet_size = GST_READ_UINT32_BE (data + 24);
7439 height = GST_READ_UINT16_BE (data + 40);
7440 leaf_size = GST_READ_UINT16_BE (data + 44);
7441 sample_width = GST_READ_UINT16_BE (data + 58);
7442 extra_data_size = GST_READ_UINT32_BE (data + 74);
7445 ("flavor:%d, packet_size:%d, height:%d, leaf_size:%d, sample_width:%d, extra_data_size:%d",
7446 flavor, packet_size, height, leaf_size, sample_width,
7448 gst_caps_set_simple (caps, "flavor", G_TYPE_INT, flavor, "packet_size",
7449 G_TYPE_INT, packet_size, "height", G_TYPE_INT, height, "leaf_size",
7450 G_TYPE_INT, leaf_size, "width", G_TYPE_INT, sample_width, NULL);
7452 if ((size - 78) >= extra_data_size) {
7453 priv = gst_buffer_new_and_alloc (extra_data_size);
7454 memcpy (GST_BUFFER_DATA (priv), data + 78, extra_data_size);
7455 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
7456 gst_buffer_unref (priv);
7461 *codec_name = g_strdup_printf ("RealAudio %d.0", raversion);
7462 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_SIPR)) {
7463 caps = gst_caps_new_simple ("audio/x-sipro", NULL);
7464 *codec_name = g_strdup ("Sipro/ACELP.NET Voice Codec");
7465 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_RALF)) {
7466 caps = gst_caps_new_simple ("audio/x-ralf-mpeg4-generic", NULL);
7467 *codec_name = g_strdup ("Real Audio Lossless");
7468 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_ATRC)) {
7469 caps = gst_caps_new_simple ("audio/x-vnd.sony.atrac3", NULL);
7470 *codec_name = g_strdup ("Sony ATRAC3");
7472 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
7477 if (audiocontext->samplerate > 0 && audiocontext->channels > 0) {
7480 for (i = 0; i < gst_caps_get_size (caps); i++) {
7481 gst_structure_set (gst_caps_get_structure (caps, i),
7482 "channels", G_TYPE_INT, audiocontext->channels,
7483 "rate", G_TYPE_INT, audiocontext->samplerate, NULL);
7487 gst_caps_do_simplify (caps);
7494 gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
7495 subtitlecontext, const gchar * codec_id, gpointer data, guint size)
7497 GstCaps *caps = NULL;
7498 GstMatroskaTrackContext *context =
7499 (GstMatroskaTrackContext *) subtitlecontext;
7501 /* for backwards compatibility */
7502 if (!g_ascii_strcasecmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASCII))
7503 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8;
7504 else if (!g_ascii_strcasecmp (codec_id, "S_SSA"))
7505 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_SSA;
7506 else if (!g_ascii_strcasecmp (codec_id, "S_ASS"))
7507 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_ASS;
7508 else if (!g_ascii_strcasecmp (codec_id, "S_USF"))
7509 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_USF;
7511 /* TODO: Add GST_MATROSKA_CODEC_ID_SUBTITLE_BMP support
7512 * Check if we have to do something with codec_private */
7513 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8)) {
7514 caps = gst_caps_new_simple ("text/plain", NULL);
7515 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
7516 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_SSA)) {
7517 caps = gst_caps_new_simple ("application/x-ssa", NULL);
7518 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
7519 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASS)) {
7520 caps = gst_caps_new_simple ("application/x-ass", NULL);
7521 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
7522 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_USF)) {
7523 caps = gst_caps_new_simple ("application/x-usf", NULL);
7524 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
7525 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB)) {
7526 caps = gst_caps_new_simple ("video/x-dvd-subpicture", NULL);
7527 ((GstMatroskaTrackContext *) subtitlecontext)->send_dvd_event = TRUE;
7528 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_HDMVPGS)) {
7529 caps = gst_caps_new_simple ("subpicture/x-pgs", NULL);
7530 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_KATE)) {
7531 caps = gst_caps_new_simple ("subtitle/x-kate", NULL);
7532 context->send_xiph_headers = TRUE;
7534 GST_DEBUG ("Unknown subtitle stream: codec_id='%s'", codec_id);
7535 caps = gst_caps_new_simple ("application/x-subtitle-unknown", NULL);
7538 if (data != NULL && size > 0) {
7541 buf = gst_buffer_new_and_alloc (size);
7542 memcpy (GST_BUFFER_DATA (buf), data, size);
7543 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, buf, NULL);
7544 gst_buffer_unref (buf);
7551 gst_matroska_demux_set_index (GstElement * element, GstIndex * index)
7553 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
7555 GST_OBJECT_LOCK (demux);
7556 if (demux->element_index)
7557 gst_object_unref (demux->element_index);
7558 demux->element_index = index ? gst_object_ref (index) : NULL;
7559 GST_OBJECT_UNLOCK (demux);
7560 GST_DEBUG_OBJECT (demux, "Set index %" GST_PTR_FORMAT, demux->element_index);
7564 gst_matroska_demux_get_index (GstElement * element)
7566 GstIndex *result = NULL;
7567 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
7569 GST_OBJECT_LOCK (demux);
7570 if (demux->element_index)
7571 result = gst_object_ref (demux->element_index);
7572 GST_OBJECT_UNLOCK (demux);
7574 GST_DEBUG_OBJECT (demux, "Returning index %" GST_PTR_FORMAT, result);
7578 #ifdef MKVDEMUX_MODIFICATION
7579 static GstFlowReturn
7580 gst_sec_matroska_demux_find_tracks (GstMatroskaDemux * demux)
7586 GstFlowReturn ret = GST_FLOW_OK;
7588 GST_WARNING_OBJECT (demux,
7589 "Found Cluster element before Tracks, searching Tracks");
7592 before_pos = demux->offset;
7594 /* Search Tracks element */
7596 ret = gst_matroska_demux_peek_id_length_pull (demux, &id, &length, &needed);
7597 if (ret != GST_FLOW_OK)
7600 if (id != GST_MATROSKA_ID_TRACKS) {
7601 /* we may be skipping large cluster here, so forego size check etc */
7602 /* ... but we can't skip undefined size; force error */
7603 if (length == G_MAXUINT64) {
7604 ret = gst_matroska_demux_check_read_size (demux, length);
7607 demux->offset += needed;
7608 demux->offset += length;
7613 /* will lead to track parsing ... */
7614 ret = gst_sec_matroska_demux_parse_id (demux, id, length, needed);
7619 demux->offset = before_pos;
7623 static GstFlowReturn
7624 gst_sec_matroska_demux_parse_id (GstMatroskaDemux * demux, guint32 id,
7625 guint64 length, guint needed)
7627 GstEbmlRead ebml = { 0, };
7628 GstFlowReturn ret = GST_FLOW_OK;
7631 GST_LOG_OBJECT (demux, "Parsing Element id 0x%x, "
7632 "size %" G_GUINT64_FORMAT ", prefix %d", id, length, needed);
7634 /* if we plan to read and parse this element, we need prefix (id + length)
7635 * and the contents */
7636 /* mind about overflow wrap-around when dealing with undefined size */
7638 if (G_LIKELY (length != G_MAXUINT64))
7641 switch (demux->state) {
7642 case GST_MATROSKA_DEMUX_STATE_START:
7644 case GST_EBML_ID_HEADER:
7645 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
7646 ret = gst_matroska_demux_parse_header (demux, &ebml);
7647 if (ret != GST_FLOW_OK)
7649 demux->state = GST_MATROSKA_DEMUX_STATE_SEGMENT;
7650 gst_matroska_demux_check_seekability (demux);
7653 goto invalid_header;
7657 case GST_MATROSKA_DEMUX_STATE_SEGMENT:
7659 case GST_MATROSKA_ID_SEGMENT:
7660 /* eat segment prefix */
7661 GST_READ_CHECK (gst_matroska_demux_flush (demux, needed));
7662 GST_DEBUG_OBJECT (demux,
7663 "Found Segment start at offset %" G_GUINT64_FORMAT,
7665 /* seeks are from the beginning of the segment,
7666 * after the segment ID/length */
7667 demux->ebml_segment_start = demux->offset;
7668 demux->state = GST_MATROSKA_DEMUX_STATE_HEADER;
7671 GST_WARNING_OBJECT (demux,
7672 "Expected a Segment ID (0x%x), but received 0x%x!",
7673 GST_MATROSKA_ID_SEGMENT, id);
7674 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
7678 case GST_MATROSKA_DEMUX_STATE_SCANNING:
7679 if (id != GST_MATROSKA_ID_CLUSTER &&
7680 id != GST_MATROSKA_ID_CLUSTERTIMECODE)
7683 case GST_MATROSKA_DEMUX_STATE_HEADER:
7684 case GST_MATROSKA_DEMUX_STATE_DATA:
7685 case GST_MATROSKA_DEMUX_STATE_SEEK:
7687 case GST_MATROSKA_ID_CLUSTER:
7688 if (G_UNLIKELY (!demux->tracks_parsed)) {
7689 if (demux->streaming) {
7690 GST_DEBUG_OBJECT (demux, "Cluster before Track");
7691 goto not_streamable;
7693 ret = gst_sec_matroska_demux_find_tracks (demux);
7694 if (!demux->tracks_parsed)
7698 if (G_UNLIKELY (demux->state == GST_MATROSKA_DEMUX_STATE_HEADER)) {
7699 demux->state = GST_MATROSKA_DEMUX_STATE_DATA;
7700 demux->first_cluster_offset = demux->offset;
7701 GST_DEBUG_OBJECT (demux, "signaling no more pads");
7702 gst_element_no_more_pads (GST_ELEMENT (demux));
7703 /* send initial newsegment */
7704 gst_matroska_demux_send_event (demux,
7705 gst_event_new_new_segment (FALSE, 1.0,
7707 (demux->segment.duration >
7708 0) ? demux->segment.duration : -1, 0));
7710 demux->cluster_time = GST_CLOCK_TIME_NONE;
7711 demux->cluster_offset = demux->offset;
7712 if (G_UNLIKELY (!demux->seek_first && demux->seek_block)) {
7713 GST_DEBUG_OBJECT (demux, "seek target block %" G_GUINT64_FORMAT
7714 " not found in Cluster, trying next Cluster's first block instead",
7716 demux->seek_block = 0;
7718 demux->seek_first = FALSE;
7719 /* record next cluster for recovery */
7720 if (read != G_MAXUINT64)
7721 demux->next_cluster_offset = demux->cluster_offset + read;
7722 /* eat cluster prefix */
7723 gst_matroska_demux_flush (demux, needed);
7725 case GST_MATROSKA_ID_CLUSTERTIMECODE:
7729 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
7730 if ((ret = gst_ebml_read_uint (&ebml, &id, &num)) != GST_FLOW_OK)
7732 GST_DEBUG_OBJECT (demux, "ClusterTimeCode: %" G_GUINT64_FORMAT, num);
7733 demux->cluster_time = num;
7734 if (demux->element_index) {
7735 if (demux->element_index_writer_id == -1)
7736 gst_index_get_writer_id (demux->element_index,
7737 GST_OBJECT (demux), &demux->element_index_writer_id);
7738 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
7739 G_GUINT64_FORMAT " for writer id %d",
7740 GST_TIME_ARGS (demux->cluster_time), demux->cluster_offset,
7741 demux->element_index_writer_id);
7742 gst_index_add_association (demux->element_index,
7743 demux->element_index_writer_id, GST_ASSOCIATION_FLAG_KEY_UNIT,
7744 GST_FORMAT_TIME, demux->cluster_time,
7745 GST_FORMAT_BYTES, demux->cluster_offset, NULL);
7749 case GST_MATROSKA_ID_BLOCKGROUP:
7750 if (!gst_matroska_demux_seek_block (demux))
7752 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
7753 DEBUG_ELEMENT_START (demux, &ebml, "BlockGroup");
7754 if ((ret = gst_ebml_read_master (&ebml, &id)) == GST_FLOW_OK) {
7755 ret = gst_sec_matroska_demux_parse_blockgroup_or_simpleblock (demux,
7756 &ebml, demux->cluster_time, demux->cluster_offset, FALSE);
7758 DEBUG_ELEMENT_STOP (demux, &ebml, "BlockGroup", ret);
7760 case GST_MATROSKA_ID_SIMPLEBLOCK:
7761 if (!gst_matroska_demux_seek_block (demux))
7763 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
7764 DEBUG_ELEMENT_START (demux, &ebml, "SimpleBlock");
7765 ret = gst_sec_matroska_demux_parse_blockgroup_or_simpleblock (demux,
7766 &ebml, demux->cluster_time, demux->cluster_offset, TRUE);
7767 DEBUG_ELEMENT_STOP (demux, &ebml, "SimpleBlock", ret);
7769 case GST_MATROSKA_ID_SEGMENTINFO:
7770 case GST_MATROSKA_ID_TRACKS:
7771 case GST_MATROSKA_ID_ATTACHMENTS:
7772 case GST_MATROSKA_ID_TAGS:
7773 case GST_MATROSKA_ID_CHAPTERS:
7774 case GST_MATROSKA_ID_SEEKHEAD:
7775 case GST_MATROSKA_ID_CUES:
7776 case GST_MATROSKA_ID_POSITION:
7777 case GST_MATROSKA_ID_PREVSIZE:
7778 case GST_MATROSKA_ID_ENCRYPTEDBLOCK:
7779 case GST_MATROSKA_ID_SILENTTRACKS:
7780 GST_DEBUG_OBJECT (demux,
7781 "Skipping Cluster subelement 0x%x - ignoring", id);
7785 GST_DEBUG_OBJECT (demux, "skipping Element 0x%x", id);
7786 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
7792 if (ret == GST_FLOW_PARSE)
7796 gst_ebml_read_clear (&ebml);
7802 /* simply exit, maybe not enough data yet */
7803 /* no ebml to clear if read error */
7808 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
7809 ("Failed to parse Element 0x%x", id));
7810 ret = GST_FLOW_ERROR;
7815 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
7816 ("File layout does not permit streaming"));
7817 ret = GST_FLOW_ERROR;
7822 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
7823 ("No Tracks element found"));
7824 ret = GST_FLOW_ERROR;
7829 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Invalid header"));
7830 ret = GST_FLOW_ERROR;
7835 static GstFlowReturn
7836 gst_sec_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux,
7837 GstEbmlRead * ebml, guint64 cluster_time, guint64 cluster_offset,
7838 gboolean is_simpleblock)
7840 GstMatroskaTrackContext *stream = NULL;
7841 GstFlowReturn ret = GST_FLOW_OK;
7842 gboolean readblock = FALSE;
7844 guint64 block_duration = 0;
7845 GstBuffer *buf = NULL;
7846 gint stream_num = -1, n, laces = 0;
7848 gint *lace_size = NULL;
7851 gint64 referenceblock = 0;
7854 offset = gst_ebml_read_get_offset (ebml);
7856 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
7857 if (!is_simpleblock) {
7858 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK) {
7862 id = GST_MATROSKA_ID_SIMPLEBLOCK;
7866 /* one block inside the group. Note, block parsing is one
7867 * of the harder things, so this code is a bit complicated.
7868 * See http://www.matroska.org/ for documentation. */
7869 case GST_MATROSKA_ID_SIMPLEBLOCK:
7870 case GST_MATROSKA_ID_BLOCK:
7876 gst_buffer_unref (buf);
7879 if ((ret = gst_ebml_read_buffer (ebml, &id, &buf)) != GST_FLOW_OK)
7882 data = GST_BUFFER_DATA (buf);
7883 size = GST_BUFFER_SIZE (buf);
7885 /* first byte(s): blocknum */
7886 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
7891 /* fetch stream from num */
7892 stream_num = gst_matroska_demux_stream_from_num (demux, num);
7893 if (G_UNLIKELY (size < 3)) {
7894 GST_WARNING_OBJECT (demux, "Invalid size %u", size);
7895 /* non-fatal, try next block(group) */
7898 } else if (G_UNLIKELY (stream_num < 0 ||
7899 stream_num >= demux->num_streams)) {
7900 /* let's not give up on a stray invalid track number */
7901 GST_WARNING_OBJECT (demux,
7902 "Invalid stream %d for track number %" G_GUINT64_FORMAT
7903 "; ignoring block", stream_num, num);
7907 stream = g_ptr_array_index (demux->src, stream_num);
7909 /* time (relative to cluster time) */
7910 time = ((gint16) GST_READ_UINT16_BE (data));
7913 flags = GST_READ_UINT8 (data);
7917 GST_LOG_OBJECT (demux, "time %" G_GUINT64_FORMAT ", flags %d", time,
7920 switch ((flags & 0x06) >> 1) {
7921 case 0x0: /* no lacing */
7925 case 0x1: /* xiph lacing */
7926 case 0x2: /* fixed-size lacing */
7927 case 0x3: /* EBML lacing */
7929 goto invalid_lacing;
7930 laces = GST_READ_UINT8 (data) + 1;
7935 if (ret != GST_FLOW_OK)
7942 case GST_MATROSKA_ID_BLOCKDURATION:{
7943 ret = gst_ebml_read_uint (ebml, &id, &block_duration);
7944 GST_DEBUG_OBJECT (demux, "BlockDuration: %" G_GUINT64_FORMAT,
7949 case GST_MATROSKA_ID_REFERENCEBLOCK:{
7950 ret = gst_ebml_read_sint (ebml, &id, &referenceblock);
7951 GST_DEBUG_OBJECT (demux, "ReferenceBlock: %" G_GINT64_FORMAT,
7957 ret = gst_matroska_demux_parse_skip (demux, ebml, "BlockGroup", id);
7960 case GST_MATROSKA_ID_BLOCKVIRTUAL:
7961 case GST_MATROSKA_ID_BLOCKADDITIONS:
7962 case GST_MATROSKA_ID_REFERENCEPRIORITY:
7963 case GST_MATROSKA_ID_REFERENCEVIRTUAL:
7964 case GST_MATROSKA_ID_SLICES:
7965 GST_DEBUG_OBJECT (demux,
7966 "Skipping BlockGroup subelement 0x%x - ignoring", id);
7967 ret = gst_ebml_read_skip (ebml);
7975 /* reading a number or so could have failed */
7976 if (ret != GST_FLOW_OK)
7979 if (ret == GST_FLOW_OK && readblock) {
7980 guint64 duration = 0;
7981 gint64 lace_time = 0;
7982 gboolean delta_unit;
7984 stream = g_ptr_array_index (demux->src, stream_num);
7986 if (cluster_time != GST_CLOCK_TIME_NONE) {
7987 /* FIXME: What to do with negative timestamps? Give timestamp 0 or -1?
7988 * Drop unless the lace contains timestamp 0? */
7989 if (time < 0 && (-time) > cluster_time) {
7992 if (stream->timecodescale == 1.0)
7993 lace_time = (cluster_time + time) * demux->time_scale;
7996 gst_util_guint64_to_gdouble ((cluster_time + time) *
7997 demux->time_scale) * stream->timecodescale;
8000 lace_time = GST_CLOCK_TIME_NONE;
8003 /* else duration is diff between timecode of this and next block */
8005 /* For SimpleBlock, look at the keyframe bit in flags. Otherwise,
8006 a ReferenceBlock implies that this is not a keyframe. In either
8007 case, it only makes sense for video streams. */
8008 delta_unit = stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
8009 ((is_simpleblock && !(flags & 0x80)) || referenceblock);
8011 if (delta_unit && stream->set_discont) {
8012 /* When doing seeks or such, we need to restart on key frames or
8013 * decoders might choke. */
8014 GST_DEBUG_OBJECT (demux, "skipping delta unit");
8018 /* last_ts used for EOS in trickplay */
8019 stream->last_ts = lace_time;
8021 if (stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO)
8023 stream->num_frames_bw_keyframes++;
8024 if (delta_unit == FALSE)
8026 stream->found_next_kframe = TRUE;
8027 demux->next_key_cluster_time = demux->cluster_time;
8028 stream->next_kframe_timestamp = lace_time;
8029 demux->segment.last_stop = lace_time - 0.5* GST_SECOND;
8032 else if (stream->type == GST_MATROSKA_TRACK_TYPE_AUDIO)
8034 stream->num_frames_bw_keyframes = stream->num_frames_bw_keyframes + laces;
8040 gst_buffer_unref (buf);
8046 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Invalid lacing size"));
8047 /* non-fatal, try next block(group) */
8053 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Data error"));
8054 /* non-fatal, try next block(group) */
8061 gst_sec_matroska_nframes2show_bw_keyframes (GstMatroskaDemux* demux, GstMatroskaTrackContext * stream)
8063 GstFlowReturn ret = GST_FLOW_OK;
8067 gint prev_offset = demux->offset;
8068 gint next_keyframe_offset = 0;
8069 guint64 prev_cluster_time = demux->cluster_time;
8070 guint64 prev_cluster_offset = demux->cluster_offset;
8071 gint nframes_bw_kframes = 0;
8074 while (stream->found_next_kframe == FALSE)
8076 next_keyframe_offset = demux->offset;
8078 ret = gst_matroska_demux_peek_id_length_pull (demux, &id, &length, &needed);
8079 if (ret == GST_FLOW_UNEXPECTED)
8081 stream->next_kframe_timestamp = stream->last_ts;
8082 stream->found_next_kframe = TRUE;
8085 GST_LOG_OBJECT (demux, "trickplay : Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
8086 "size %" G_GUINT64_FORMAT ", needed %d", demux->offset, id,
8089 if (ret != GST_FLOW_OK)
8091 GST_WARNING_OBJECT (demux, "Error in id_length_pull flow ret...reason : %s\n", gst_flow_get_name (ret));
8095 ret = gst_sec_matroska_demux_parse_id (demux, id, length, needed);
8096 if (ret == GST_FLOW_UNEXPECTED)
8098 stream->next_kframe_timestamp = stream->last_ts;
8099 stream->found_next_kframe = TRUE;
8103 if (ret != GST_FLOW_OK)
8105 GST_WARNING_OBJECT (demux, "Error in parse_id flow ret...reason : %s\n", gst_flow_get_name (ret));
8110 if (stream->found_next_kframe == TRUE)
8112 demux->next_key_frame_offset = next_keyframe_offset;
8115 for (i = 0; i < demux->src->len; i++)
8117 GstMatroskaTrackContext *context = g_ptr_array_index (demux->src, i);
8118 if (context->type <= GST_MATROSKA_TRACK_TYPE_AUDIO);
8120 context->frames_to_show_bw_keyframes = context->num_frames_bw_keyframes / demux->segment.rate;
8124 /* keeping previous offset values for normal operation */
8125 demux->offset = prev_offset;
8126 demux->cluster_offset = prev_cluster_offset;
8127 demux->cluster_time = prev_cluster_time;
8129 return stream->num_frames_bw_keyframes;
8133 static GstFlowReturn
8134 gst_sec_matroska_forward_trickplay (GstMatroskaDemux* demux, GstMatroskaTrackContext * stream, GstBuffer *buffer, gboolean *skip)
8136 GstFlowReturn ret = GST_FLOW_OK;
8139 if (stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO)
8141 if ((stream->found_next_kframe == FALSE) && (!GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT)))
8143 g_assert (!GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT));
8144 gst_sec_matroska_nframes2show_bw_keyframes (demux, stream);
8145 stream->prev_kframe_timestamp = GST_BUFFER_TIMESTAMP (buffer);
8146 stream->avg_duration_bw_keyframes = (stream->next_kframe_timestamp - stream->prev_kframe_timestamp) / stream->num_frames_bw_keyframes;
8147 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);
8148 GST_DEBUG_OBJECT (demux, "average duration of frames = %d", GST_TIME_ARGS(stream->avg_duration_bw_keyframes));
8150 for (i = 0; i < demux->src->len; i++)
8152 GstMatroskaTrackContext *context = g_ptr_array_index (demux->src, i);
8153 if (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO)
8155 context->num_frames_bw_keyframes = 0;
8161 stream->frames_to_show_bw_keyframes--;
8162 if (stream->frames_to_show_bw_keyframes == 0)
8164 stream->found_next_kframe = FALSE;
8165 demux->cluster_time = demux->next_key_cluster_time;
8166 demux->offset = demux->next_key_frame_offset;
8167 stream->num_frames_bw_keyframes = 0;
8168 GST_DEBUG_OBJECT (demux, "next key cluster time = %"GST_TIME_FORMAT" and offset = %u...\n", GST_TIME_ARGS(demux->cluster_time), demux->offset);
8170 /* GST_BUFFER_TIMESTAMP(buffer) = stream->prev_kframe_timestamp +
8171 ((stream->num_frames_bw_keyframes/demux->segment.rate) - stream->frames_to_show_bw_keyframes) * abs (demux->segment.rate) * stream->avg_duration_bw_keyframes;*/
8174 else if (stream->type == GST_MATROSKA_TRACK_TYPE_AUDIO)
8176 if (stream->frames_to_show_bw_keyframes == 0)
8179 stream->num_frames_bw_keyframes = 0;
8180 stream->frames_to_show_bw_keyframes = 0;
8184 stream->frames_to_show_bw_keyframes--;
8190 if (G_LIKELY (demux->src->len))
8193 g_assert (demux->num_streams == demux->src->len);
8194 for (i = 0; i < demux->src->len; i++)
8196 GstMatroskaTrackContext *context = g_ptr_array_index (demux->src, i);
8197 if ((context->type == GST_MATROSKA_TRACK_TYPE_VIDEO) && (context->frames_to_show_bw_keyframes == 0))
8199 context->frames_to_show_bw_keyframes = 0;
8200 context->num_frames_bw_keyframes = 0;
8212 static GstStateChangeReturn
8213 gst_matroska_demux_change_state (GstElement * element,
8214 GstStateChange transition)
8216 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
8217 GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
8219 /* handle upwards state changes here */
8220 switch (transition) {
8225 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
8227 /* handle downwards state changes */
8228 switch (transition) {
8229 case GST_STATE_CHANGE_PAUSED_TO_READY:
8230 gst_matroska_demux_reset (GST_ELEMENT (demux));
8240 gst_matroska_demux_plugin_init (GstPlugin * plugin)
8244 /* create an elementfactory for the matroska_demux element */
8245 if (!gst_element_register (plugin, "matroskademux",
8246 GST_RANK_PRIMARY, GST_TYPE_MATROSKA_DEMUX))