1 /* GStreamer Matroska muxer/demuxer
2  * (c) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
3  * (c) 2006 Tim-Philipp Müller <tim centricular net>
4  * (c) 2008 Sebastian Dröge <slomo@circular-chaos.org>
5  * (c) 2011 Debarshi Ray <rishi@gnu.org>
6  *
7  * matroska-parse.c: matroska file/stream parser
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Library General Public
11  * License as published by the Free Software Foundation; either
12  * version 2 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Library General Public License for more details.
18  *
19  * You should have received a copy of the GNU Library General Public
20  * License along with this library; if not, write to the
21  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
22  * Boston, MA 02110-1301, USA.
23  */
24 
25 /* TODO: check CRC32 if present
26  * TODO: there can be a segment after the first segment. Handle like
27  *       chained oggs. Fixes #334082
28  * TODO: Test samples: http://www.matroska.org/samples/matrix/index.html
29  *                     http://samples.mplayerhq.hu/Matroska/
30  * TODO: check if parseing is done correct for all codecs according to spec
31  * TODO: seeking with incomplete or without CUE
32  */
33 
34 /**
35  * SECTION:element-matroskaparse
36  *
37  * matroskaparse parsees a Matroska file into the different contained streams.
38  *
39  * <refsect2>
40  * <title>Example launch line</title>
41  * |[
42  * gst-launch-1.0 -v filesrc location=/path/to/mkv ! matroskaparse ! vorbisdec ! audioconvert ! audioresample ! autoaudiosink
43  * ]| This pipeline parsees a Matroska file and outputs the contained Vorbis audio.
44  * </refsect2>
45  */
46 
47 
48 #ifdef HAVE_CONFIG_H
49 #include "config.h"
50 #endif
51 
52 #include <math.h>
53 #include <string.h>
54 #include <glib/gprintf.h>
55 
56 /* For AVI compatibility mode
57    and for fourcc stuff */
58 #include <gst/riff/riff-read.h>
59 #include <gst/riff/riff-ids.h>
60 #include <gst/riff/riff-media.h>
61 
62 #include <gst/tag/tag.h>
63 
64 #include <gst/pbutils/pbutils.h>
65 
66 #include "matroska-parse.h"
67 #include "matroska-ids.h"
68 
69 GST_DEBUG_CATEGORY_STATIC (matroskaparse_debug);
70 #define GST_CAT_DEFAULT matroskaparse_debug
71 
72 #define DEBUG_ELEMENT_START(parse, ebml, element) \
73     GST_DEBUG_OBJECT (parse, "Parsing " element " element at offset %" \
74         G_GUINT64_FORMAT, gst_ebml_read_get_pos (ebml))
75 
76 #define DEBUG_ELEMENT_STOP(parse, ebml, element, ret) \
77     GST_DEBUG_OBJECT (parse, "Parsing " element " element " \
78         " finished with '%s'", gst_flow_get_name (ret))
79 
80 #define INVALID_DATA_THRESHOLD (2 * 1024 * 1024)
81 
82 enum
83 {
84   PROP_0
85 };
86 
87 static GstStaticPadTemplate sink_templ = GST_STATIC_PAD_TEMPLATE ("sink",
88     GST_PAD_SINK,
89     GST_PAD_ALWAYS,
90     GST_STATIC_CAPS ("audio/x-matroska; video/x-matroska; "
91         "video/x-matroska-3d; audio/webm; video/webm")
92     );
93 
94 static GstStaticPadTemplate src_templ = GST_STATIC_PAD_TEMPLATE ("src",
95     GST_PAD_SRC,
96     GST_PAD_ALWAYS,
97     GST_STATIC_CAPS ("audio/x-matroska; video/x-matroska; "
98         "video/x-matroska-3d; audio/webm; video/webm")
99     );
100 
101 static GstFlowReturn gst_matroska_parse_parse_id (GstMatroskaParse * parse,
102     guint32 id, guint64 length, guint needed);
103 
104 /* element functions */
105 //static void gst_matroska_parse_loop (GstPad * pad);
106 
107 static gboolean gst_matroska_parse_element_send_event (GstElement * element,
108     GstEvent * event);
109 static gboolean gst_matroska_parse_element_query (GstElement * element,
110     GstQuery * query);
111 
112 /* pad functions */
113 static gboolean gst_matroska_parse_handle_seek_event (GstMatroskaParse * parse,
114     GstPad * pad, GstEvent * event);
115 static gboolean gst_matroska_parse_handle_src_event (GstPad * pad,
116     GstObject * parent, GstEvent * event);
117 static gboolean gst_matroska_parse_handle_src_query (GstPad * pad,
118     GstObject * parent, GstQuery * query);
119 
120 static gboolean gst_matroska_parse_handle_sink_event (GstPad * pad,
121     GstObject * parent, GstEvent * event);
122 static GstFlowReturn gst_matroska_parse_chain (GstPad * pad,
123     GstObject * parent, GstBuffer * buffer);
124 
125 static GstStateChangeReturn
126 gst_matroska_parse_change_state (GstElement * element,
127     GstStateChange transition);
128 #if 0
129 static void
130 gst_matroska_parse_set_index (GstElement * element, GstIndex * index);
131 static GstIndex *gst_matroska_parse_get_index (GstElement * element);
132 #endif
133 
134 /* stream methods */
135 static void gst_matroska_parse_reset (GstElement * element);
136 static gboolean perform_seek_to_offset (GstMatroskaParse * parse,
137     guint64 offset);
138 static GstCaps *gst_matroska_parse_forge_caps (gboolean is_webm,
139     gboolean has_video);
140 
141 GType gst_matroska_parse_get_type (void);
142 #define parent_class gst_matroska_parse_parent_class
143 G_DEFINE_TYPE (GstMatroskaParse, gst_matroska_parse, GST_TYPE_ELEMENT);
144 
145 static void
gst_matroska_parse_finalize(GObject * object)146 gst_matroska_parse_finalize (GObject * object)
147 {
148   GstMatroskaParse *parse = GST_MATROSKA_PARSE (object);
149 
150   gst_matroska_read_common_finalize (&parse->common);
151   G_OBJECT_CLASS (parent_class)->finalize (object);
152 }
153 
154 static void
gst_matroska_parse_class_init(GstMatroskaParseClass * klass)155 gst_matroska_parse_class_init (GstMatroskaParseClass * klass)
156 {
157   GObjectClass *gobject_class = (GObjectClass *) klass;
158   GstElementClass *gstelement_class = (GstElementClass *) klass;
159 
160   GST_DEBUG_CATEGORY_INIT (matroskaparse_debug, "matroskaparse", 0,
161       "Matroska parser");
162 
163   gobject_class->finalize = gst_matroska_parse_finalize;
164 
165   gstelement_class->change_state =
166       GST_DEBUG_FUNCPTR (gst_matroska_parse_change_state);
167   gstelement_class->send_event =
168       GST_DEBUG_FUNCPTR (gst_matroska_parse_element_send_event);
169   gstelement_class->query =
170       GST_DEBUG_FUNCPTR (gst_matroska_parse_element_query);
171 
172 #if 0
173   gstelement_class->set_index =
174       GST_DEBUG_FUNCPTR (gst_matroska_parse_set_index);
175   gstelement_class->get_index =
176       GST_DEBUG_FUNCPTR (gst_matroska_parse_get_index);
177 #endif
178 
179   gst_element_class_add_static_pad_template (gstelement_class, &src_templ);
180   gst_element_class_add_static_pad_template (gstelement_class, &sink_templ);
181 
182   gst_element_class_set_static_metadata (gstelement_class,
183       "Matroska parser", "Codec/Parser",
184       "Parses Matroska/WebM streams into video/audio/subtitles",
185       "GStreamer maintainers <gstreamer-devel@lists.freedesktop.org>");
186 }
187 
188 static void
gst_matroska_parse_init(GstMatroskaParse * parse)189 gst_matroska_parse_init (GstMatroskaParse * parse)
190 {
191   parse->common.sinkpad = gst_pad_new_from_static_template (&sink_templ,
192       "sink");
193   gst_pad_set_chain_function (parse->common.sinkpad,
194       GST_DEBUG_FUNCPTR (gst_matroska_parse_chain));
195   gst_pad_set_event_function (parse->common.sinkpad,
196       GST_DEBUG_FUNCPTR (gst_matroska_parse_handle_sink_event));
197   gst_element_add_pad (GST_ELEMENT (parse), parse->common.sinkpad);
198 
199   parse->srcpad = gst_pad_new_from_static_template (&src_templ, "src");
200   gst_pad_set_event_function (parse->srcpad,
201       GST_DEBUG_FUNCPTR (gst_matroska_parse_handle_src_event));
202   gst_pad_set_query_function (parse->srcpad,
203       GST_DEBUG_FUNCPTR (gst_matroska_parse_handle_src_query));
204   gst_pad_use_fixed_caps (parse->srcpad);
205 
206   gst_element_add_pad (GST_ELEMENT (parse), parse->srcpad);
207 
208   /* init defaults for common read context */
209   gst_matroska_read_common_init (&parse->common);
210 
211   GST_OBJECT_FLAG_SET (parse, GST_ELEMENT_FLAG_INDEXABLE);
212 
213   /* finish off */
214   gst_matroska_parse_reset (GST_ELEMENT (parse));
215 }
216 
217 static void
gst_matroska_parse_reset(GstElement * element)218 gst_matroska_parse_reset (GstElement * element)
219 {
220   GstMatroskaParse *parse = GST_MATROSKA_PARSE (element);
221 
222   GST_DEBUG_OBJECT (parse, "Resetting state");
223 
224   gst_matroska_read_common_reset (GST_ELEMENT (parse), &parse->common);
225 
226   parse->num_a_streams = 0;
227   parse->num_t_streams = 0;
228   parse->num_v_streams = 0;
229 
230   parse->clock = NULL;
231   parse->tracks_parsed = FALSE;
232 
233   g_list_foreach (parse->seek_parsed,
234       (GFunc) gst_matroska_read_common_free_parsed_el, NULL);
235   g_list_free (parse->seek_parsed);
236   parse->seek_parsed = NULL;
237 
238   parse->last_stop_end = GST_CLOCK_TIME_NONE;
239   parse->seek_block = 0;
240   parse->cluster_time = GST_CLOCK_TIME_NONE;
241   parse->cluster_offset = 0;
242   parse->next_cluster_offset = 0;
243   parse->index_offset = 0;
244   parse->seekable = FALSE;
245   parse->need_newsegment = TRUE;
246   parse->building_index = FALSE;
247   if (parse->seek_event) {
248     gst_event_unref (parse->seek_event);
249     parse->seek_event = NULL;
250   }
251 
252   parse->seek_index = NULL;
253   parse->seek_entry = 0;
254 
255   if (parse->close_segment) {
256     gst_event_unref (parse->close_segment);
257     parse->close_segment = NULL;
258   }
259 
260   if (parse->new_segment) {
261     gst_event_unref (parse->new_segment);
262     parse->new_segment = NULL;
263   }
264 
265   if (parse->streamheader != NULL) {
266     gst_buffer_unref (parse->streamheader);
267     parse->streamheader = NULL;
268   }
269 }
270 
271 static GstFlowReturn
gst_matroska_parse_add_stream(GstMatroskaParse * parse,GstEbmlRead * ebml)272 gst_matroska_parse_add_stream (GstMatroskaParse * parse, GstEbmlRead * ebml)
273 {
274   GstMatroskaTrackContext *context;
275   GstFlowReturn ret;
276   guint32 id;
277 
278   DEBUG_ELEMENT_START (parse, ebml, "TrackEntry");
279 
280   /* start with the master */
281   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
282     DEBUG_ELEMENT_STOP (parse, ebml, "TrackEntry", ret);
283     return ret;
284   }
285 
286   /* allocate generic... if we know the type, we'll g_renew()
287    * with the precise type */
288   context = g_new0 (GstMatroskaTrackContext, 1);
289   g_ptr_array_add (parse->common.src, context);
290   context->index = parse->common.num_streams;
291   context->index_writer_id = -1;
292   context->type = 0;            /* no type yet */
293   context->default_duration = 0;
294   context->pos = 0;
295   context->set_discont = TRUE;
296   context->timecodescale = 1.0;
297   context->flags =
298       GST_MATROSKA_TRACK_ENABLED | GST_MATROSKA_TRACK_DEFAULT |
299       GST_MATROSKA_TRACK_LACING;
300   context->to_offset = G_MAXINT64;
301   context->alignment = 1;
302   parse->common.num_streams++;
303   g_assert (parse->common.src->len == parse->common.num_streams);
304 
305   GST_DEBUG_OBJECT (parse, "Stream number %d", context->index);
306 
307   /* try reading the trackentry headers */
308   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
309     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
310       break;
311 
312     switch (id) {
313         /* track number (unique stream ID) */
314       case GST_MATROSKA_ID_TRACKNUMBER:{
315         guint64 num;
316 
317         if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
318           break;
319 
320         if (num == 0) {
321           GST_ERROR_OBJECT (parse, "Invalid TrackNumber 0");
322           ret = GST_FLOW_ERROR;
323           break;
324         } else if (!gst_matroska_read_common_tracknumber_unique (&parse->common,
325                 num)) {
326           GST_ERROR_OBJECT (parse, "TrackNumber %" G_GUINT64_FORMAT
327               " is not unique", num);
328           ret = GST_FLOW_ERROR;
329           break;
330         }
331 
332         GST_DEBUG_OBJECT (parse, "TrackNumber: %" G_GUINT64_FORMAT, num);
333         context->num = num;
334         break;
335       }
336         /* track UID (unique identifier) */
337       case GST_MATROSKA_ID_TRACKUID:{
338         guint64 num;
339 
340         if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
341           break;
342 
343         if (num == 0) {
344           GST_ERROR_OBJECT (parse, "Invalid TrackUID 0");
345           ret = GST_FLOW_ERROR;
346           break;
347         }
348 
349         GST_DEBUG_OBJECT (parse, "TrackUID: %" G_GUINT64_FORMAT, num);
350         context->uid = num;
351         break;
352       }
353 
354         /* track type (video, audio, combined, subtitle, etc.) */
355       case GST_MATROSKA_ID_TRACKTYPE:{
356         guint64 track_type;
357 
358         if ((ret = gst_ebml_read_uint (ebml, &id, &track_type)) != GST_FLOW_OK) {
359           break;
360         }
361 
362         if (context->type != 0 && context->type != track_type) {
363           GST_WARNING_OBJECT (parse,
364               "More than one tracktype defined in a TrackEntry - skipping");
365           break;
366         } else if (track_type < 1 || track_type > 254) {
367           GST_WARNING_OBJECT (parse, "Invalid TrackType %" G_GUINT64_FORMAT,
368               track_type);
369           break;
370         }
371 
372         GST_DEBUG_OBJECT (parse, "TrackType: %" G_GUINT64_FORMAT, track_type);
373 
374         /* ok, so we're actually going to reallocate this thing */
375         switch (track_type) {
376           case GST_MATROSKA_TRACK_TYPE_VIDEO:
377             gst_matroska_track_init_video_context (&context);
378             parse->common.has_video = TRUE;
379             break;
380           case GST_MATROSKA_TRACK_TYPE_AUDIO:
381             gst_matroska_track_init_audio_context (&context);
382             break;
383           case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
384             gst_matroska_track_init_subtitle_context (&context);
385             break;
386           case GST_MATROSKA_TRACK_TYPE_COMPLEX:
387           case GST_MATROSKA_TRACK_TYPE_LOGO:
388           case GST_MATROSKA_TRACK_TYPE_BUTTONS:
389           case GST_MATROSKA_TRACK_TYPE_CONTROL:
390           default:
391             GST_WARNING_OBJECT (parse,
392                 "Unknown or unsupported TrackType %" G_GUINT64_FORMAT,
393                 track_type);
394             context->type = 0;
395             break;
396         }
397         g_ptr_array_index (parse->common.src, parse->common.num_streams - 1)
398             = context;
399         break;
400       }
401 
402         /* tracktype specific stuff for video */
403       case GST_MATROSKA_ID_TRACKVIDEO:{
404         GstMatroskaTrackVideoContext *videocontext;
405 
406         DEBUG_ELEMENT_START (parse, ebml, "TrackVideo");
407 
408         if (!gst_matroska_track_init_video_context (&context)) {
409           GST_WARNING_OBJECT (parse,
410               "TrackVideo element in non-video track - ignoring track");
411           ret = GST_FLOW_ERROR;
412           break;
413         } else if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
414           break;
415         }
416         videocontext = (GstMatroskaTrackVideoContext *) context;
417         g_ptr_array_index (parse->common.src, parse->common.num_streams - 1)
418             = context;
419 
420         while (ret == GST_FLOW_OK &&
421             gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
422           if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
423             break;
424 
425           switch (id) {
426               /* Should be one level up but some broken muxers write it here. */
427             case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
428               guint64 num;
429 
430               if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
431                 break;
432 
433               if (num == 0) {
434                 GST_WARNING_OBJECT (parse, "Invalid TrackDefaultDuration 0");
435                 break;
436               }
437 
438               GST_DEBUG_OBJECT (parse,
439                   "TrackDefaultDuration: %" G_GUINT64_FORMAT, num);
440               context->default_duration = num;
441               break;
442             }
443 
444               /* video framerate */
445               /* NOTE: This one is here only for backward compatibility.
446                * Use _TRACKDEFAULDURATION one level up. */
447             case GST_MATROSKA_ID_VIDEOFRAMERATE:{
448               gdouble num;
449 
450               if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
451                 break;
452 
453               if (num <= 0.0) {
454                 GST_WARNING_OBJECT (parse, "Invalid TrackVideoFPS %lf", num);
455                 break;
456               }
457 
458               GST_DEBUG_OBJECT (parse, "TrackVideoFrameRate: %lf", num);
459               if (context->default_duration == 0)
460                 context->default_duration =
461                     gst_gdouble_to_guint64 ((gdouble) GST_SECOND * (1.0 / num));
462               videocontext->default_fps = num;
463               break;
464             }
465 
466               /* width of the size to display the video at */
467             case GST_MATROSKA_ID_VIDEODISPLAYWIDTH:{
468               guint64 num;
469 
470               if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
471                 break;
472 
473               if (num == 0) {
474                 GST_WARNING_OBJECT (parse, "Invalid TrackVideoDisplayWidth 0");
475                 break;
476               }
477 
478               GST_DEBUG_OBJECT (parse,
479                   "TrackVideoDisplayWidth: %" G_GUINT64_FORMAT, num);
480               videocontext->display_width = num;
481               break;
482             }
483 
484               /* height of the size to display the video at */
485             case GST_MATROSKA_ID_VIDEODISPLAYHEIGHT:{
486               guint64 num;
487 
488               if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
489                 break;
490 
491               if (num == 0) {
492                 GST_WARNING_OBJECT (parse, "Invalid TrackVideoDisplayHeight 0");
493                 break;
494               }
495 
496               GST_DEBUG_OBJECT (parse,
497                   "TrackVideoDisplayHeight: %" G_GUINT64_FORMAT, num);
498               videocontext->display_height = num;
499               break;
500             }
501 
502               /* width of the video in the file */
503             case GST_MATROSKA_ID_VIDEOPIXELWIDTH:{
504               guint64 num;
505 
506               if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
507                 break;
508 
509               if (num == 0) {
510                 GST_WARNING_OBJECT (parse, "Invalid TrackVideoPixelWidth 0");
511                 break;
512               }
513 
514               GST_DEBUG_OBJECT (parse,
515                   "TrackVideoPixelWidth: %" G_GUINT64_FORMAT, num);
516               videocontext->pixel_width = num;
517               break;
518             }
519 
520               /* height of the video in the file */
521             case GST_MATROSKA_ID_VIDEOPIXELHEIGHT:{
522               guint64 num;
523 
524               if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
525                 break;
526 
527               if (num == 0) {
528                 GST_WARNING_OBJECT (parse, "Invalid TrackVideoPixelHeight 0");
529                 break;
530               }
531 
532               GST_DEBUG_OBJECT (parse,
533                   "TrackVideoPixelHeight: %" G_GUINT64_FORMAT, num);
534               videocontext->pixel_height = num;
535               break;
536             }
537 
538               /* whether the video is interlaced */
539             case GST_MATROSKA_ID_VIDEOFLAGINTERLACED:{
540               guint64 num;
541 
542               if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
543                 break;
544 
545               if (num == 1)
546                 videocontext->interlace_mode =
547                     GST_MATROSKA_INTERLACE_MODE_INTERLACED;
548               else if (num == 2)
549                 videocontext->interlace_mode =
550                     GST_MATROSKA_INTERLACE_MODE_PROGRESSIVE;
551               else
552                 videocontext->interlace_mode =
553                     GST_MATROSKA_INTERLACE_MODE_UNKNOWN;
554 
555               GST_DEBUG_OBJECT (parse, "video track interlacing mode: %d",
556                   videocontext->interlace_mode);
557               break;
558             }
559 
560               /* aspect ratio behaviour */
561             case GST_MATROSKA_ID_VIDEOASPECTRATIOTYPE:{
562               guint64 num;
563 
564               if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
565                 break;
566 
567               if (num != GST_MATROSKA_ASPECT_RATIO_MODE_FREE &&
568                   num != GST_MATROSKA_ASPECT_RATIO_MODE_KEEP &&
569                   num != GST_MATROSKA_ASPECT_RATIO_MODE_FIXED) {
570                 GST_WARNING_OBJECT (parse,
571                     "Unknown TrackVideoAspectRatioType 0x%x", (guint) num);
572                 break;
573               }
574               GST_DEBUG_OBJECT (parse,
575                   "TrackVideoAspectRatioType: %" G_GUINT64_FORMAT, num);
576               videocontext->asr_mode = num;
577               break;
578             }
579 
580               /* colourspace (only matters for raw video) fourcc */
581             case GST_MATROSKA_ID_VIDEOCOLOURSPACE:{
582               guint8 *data;
583               guint64 datalen;
584 
585               if ((ret =
586                       gst_ebml_read_binary (ebml, &id, &data,
587                           &datalen)) != GST_FLOW_OK)
588                 break;
589 
590               if (datalen != 4) {
591                 g_free (data);
592                 GST_WARNING_OBJECT (parse,
593                     "Invalid TrackVideoColourSpace length %" G_GUINT64_FORMAT,
594                     datalen);
595                 break;
596               }
597 
598               memcpy (&videocontext->fourcc, data, 4);
599               GST_DEBUG_OBJECT (parse,
600                   "TrackVideoColourSpace: %" GST_FOURCC_FORMAT,
601                   GST_FOURCC_ARGS (videocontext->fourcc));
602               g_free (data);
603               break;
604             }
605 
606             default:
607               GST_WARNING_OBJECT (parse,
608                   "Unknown TrackVideo subelement 0x%x - ignoring", id);
609               /* fall through */
610             case GST_MATROSKA_ID_VIDEOSTEREOMODE:
611             case GST_MATROSKA_ID_VIDEODISPLAYUNIT:
612             case GST_MATROSKA_ID_VIDEOPIXELCROPBOTTOM:
613             case GST_MATROSKA_ID_VIDEOPIXELCROPTOP:
614             case GST_MATROSKA_ID_VIDEOPIXELCROPLEFT:
615             case GST_MATROSKA_ID_VIDEOPIXELCROPRIGHT:
616             case GST_MATROSKA_ID_VIDEOGAMMAVALUE:
617               ret = gst_ebml_read_skip (ebml);
618               break;
619           }
620         }
621 
622         DEBUG_ELEMENT_STOP (parse, ebml, "TrackVideo", ret);
623         break;
624       }
625 
626         /* tracktype specific stuff for audio */
627       case GST_MATROSKA_ID_TRACKAUDIO:{
628         GstMatroskaTrackAudioContext *audiocontext;
629 
630         DEBUG_ELEMENT_START (parse, ebml, "TrackAudio");
631 
632         if (!gst_matroska_track_init_audio_context (&context)) {
633           GST_WARNING_OBJECT (parse,
634               "TrackAudio element in non-audio track - ignoring track");
635           ret = GST_FLOW_ERROR;
636           break;
637         }
638 
639         if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
640           break;
641 
642         audiocontext = (GstMatroskaTrackAudioContext *) context;
643         g_ptr_array_index (parse->common.src, parse->common.num_streams - 1)
644             = context;
645 
646         while (ret == GST_FLOW_OK &&
647             gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
648           if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
649             break;
650 
651           switch (id) {
652               /* samplerate */
653             case GST_MATROSKA_ID_AUDIOSAMPLINGFREQ:{
654               gdouble num;
655 
656               if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
657                 break;
658 
659 
660               if (num <= 0.0) {
661                 GST_WARNING_OBJECT (parse,
662                     "Invalid TrackAudioSamplingFrequency %lf", num);
663                 break;
664               }
665 
666               GST_DEBUG_OBJECT (parse, "TrackAudioSamplingFrequency: %lf", num);
667               audiocontext->samplerate = num;
668               break;
669             }
670 
671               /* bitdepth */
672             case GST_MATROSKA_ID_AUDIOBITDEPTH:{
673               guint64 num;
674 
675               if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
676                 break;
677 
678               if (num == 0) {
679                 GST_WARNING_OBJECT (parse, "Invalid TrackAudioBitDepth 0");
680                 break;
681               }
682 
683               GST_DEBUG_OBJECT (parse, "TrackAudioBitDepth: %" G_GUINT64_FORMAT,
684                   num);
685               audiocontext->bitdepth = num;
686               break;
687             }
688 
689               /* channels */
690             case GST_MATROSKA_ID_AUDIOCHANNELS:{
691               guint64 num;
692 
693               if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
694                 break;
695 
696               if (num == 0) {
697                 GST_WARNING_OBJECT (parse, "Invalid TrackAudioChannels 0");
698                 break;
699               }
700 
701               GST_DEBUG_OBJECT (parse, "TrackAudioChannels: %" G_GUINT64_FORMAT,
702                   num);
703               audiocontext->channels = num;
704               break;
705             }
706 
707             default:
708               GST_WARNING_OBJECT (parse,
709                   "Unknown TrackAudio subelement 0x%x - ignoring", id);
710               /* fall through */
711             case GST_MATROSKA_ID_AUDIOCHANNELPOSITIONS:
712             case GST_MATROSKA_ID_AUDIOOUTPUTSAMPLINGFREQ:
713               ret = gst_ebml_read_skip (ebml);
714               break;
715           }
716         }
717 
718         DEBUG_ELEMENT_STOP (parse, ebml, "TrackAudio", ret);
719 
720         break;
721       }
722 
723         /* codec identifier */
724       case GST_MATROSKA_ID_CODECID:{
725         gchar *text;
726 
727         if ((ret = gst_ebml_read_ascii (ebml, &id, &text)) != GST_FLOW_OK)
728           break;
729 
730         GST_DEBUG_OBJECT (parse, "CodecID: %s", GST_STR_NULL (text));
731         context->codec_id = text;
732         break;
733       }
734 
735         /* codec private data */
736       case GST_MATROSKA_ID_CODECPRIVATE:{
737         guint8 *data;
738         guint64 size;
739 
740         if ((ret =
741                 gst_ebml_read_binary (ebml, &id, &data, &size)) != GST_FLOW_OK)
742           break;
743 
744         context->codec_priv = data;
745         context->codec_priv_size = size;
746 
747         GST_DEBUG_OBJECT (parse, "CodecPrivate of size %" G_GUINT64_FORMAT,
748             size);
749         break;
750       }
751 
752         /* name of the codec */
753       case GST_MATROSKA_ID_CODECNAME:{
754         gchar *text;
755 
756         if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
757           break;
758 
759         GST_DEBUG_OBJECT (parse, "CodecName: %s", GST_STR_NULL (text));
760         context->codec_name = text;
761         break;
762       }
763 
764         /* name of this track */
765       case GST_MATROSKA_ID_TRACKNAME:{
766         gchar *text;
767 
768         if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
769           break;
770 
771         context->name = text;
772         GST_DEBUG_OBJECT (parse, "TrackName: %s", GST_STR_NULL (text));
773         break;
774       }
775 
776         /* language (matters for audio/subtitles, mostly) */
777       case GST_MATROSKA_ID_TRACKLANGUAGE:{
778         gchar *text;
779 
780         if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
781           break;
782 
783 
784         context->language = text;
785 
786         /* fre-ca => fre */
787         if (strlen (context->language) >= 4 && context->language[3] == '-')
788           context->language[3] = '\0';
789 
790         GST_DEBUG_OBJECT (parse, "TrackLanguage: %s",
791             GST_STR_NULL (context->language));
792         break;
793       }
794 
795         /* whether this is actually used */
796       case GST_MATROSKA_ID_TRACKFLAGENABLED:{
797         guint64 num;
798 
799         if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
800           break;
801 
802         if (num)
803           context->flags |= GST_MATROSKA_TRACK_ENABLED;
804         else
805           context->flags &= ~GST_MATROSKA_TRACK_ENABLED;
806 
807         GST_DEBUG_OBJECT (parse, "TrackEnabled: %d",
808             (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
809         break;
810       }
811 
812         /* whether it's the default for this track type */
813       case GST_MATROSKA_ID_TRACKFLAGDEFAULT:{
814         guint64 num;
815 
816         if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
817           break;
818 
819         if (num)
820           context->flags |= GST_MATROSKA_TRACK_DEFAULT;
821         else
822           context->flags &= ~GST_MATROSKA_TRACK_DEFAULT;
823 
824         GST_DEBUG_OBJECT (parse, "TrackDefault: %d",
825             (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
826         break;
827       }
828 
829         /* whether the track must be used during playback */
830       case GST_MATROSKA_ID_TRACKFLAGFORCED:{
831         guint64 num;
832 
833         if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
834           break;
835 
836         if (num)
837           context->flags |= GST_MATROSKA_TRACK_FORCED;
838         else
839           context->flags &= ~GST_MATROSKA_TRACK_FORCED;
840 
841         GST_DEBUG_OBJECT (parse, "TrackForced: %d",
842             (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
843         break;
844       }
845 
846         /* lacing (like MPEG, where blocks don't end/start on frame
847          * boundaries) */
848       case GST_MATROSKA_ID_TRACKFLAGLACING:{
849         guint64 num;
850 
851         if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
852           break;
853 
854         if (num)
855           context->flags |= GST_MATROSKA_TRACK_LACING;
856         else
857           context->flags &= ~GST_MATROSKA_TRACK_LACING;
858 
859         GST_DEBUG_OBJECT (parse, "TrackLacing: %d",
860             (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
861         break;
862       }
863 
864         /* default length (in time) of one data block in this track */
865       case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
866         guint64 num;
867 
868         if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
869           break;
870 
871 
872         if (num == 0) {
873           GST_WARNING_OBJECT (parse, "Invalid TrackDefaultDuration 0");
874           break;
875         }
876 
877         GST_DEBUG_OBJECT (parse, "TrackDefaultDuration: %" G_GUINT64_FORMAT,
878             num);
879         context->default_duration = num;
880         break;
881       }
882 
883       case GST_MATROSKA_ID_CONTENTENCODINGS:{
884         ret = gst_matroska_read_common_read_track_encodings (&parse->common,
885             ebml, context);
886         break;
887       }
888 
889       case GST_MATROSKA_ID_TRACKTIMECODESCALE:{
890         gdouble num;
891 
892         if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
893           break;
894 
895         if (num <= 0.0) {
896           GST_WARNING_OBJECT (parse, "Invalid TrackTimeCodeScale %lf", num);
897           break;
898         }
899 
900         GST_DEBUG_OBJECT (parse, "TrackTimeCodeScale: %lf", num);
901         context->timecodescale = num;
902         break;
903       }
904 
905       default:
906         GST_WARNING ("Unknown TrackEntry subelement 0x%x - ignoring", id);
907         /* pass-through */
908 
909         /* we ignore these because they're nothing useful (i.e. crap)
910          * or simply not implemented yet. */
911       case GST_MATROSKA_ID_TRACKMINCACHE:
912       case GST_MATROSKA_ID_TRACKMAXCACHE:
913       case GST_MATROSKA_ID_MAXBLOCKADDITIONID:
914       case GST_MATROSKA_ID_TRACKATTACHMENTLINK:
915       case GST_MATROSKA_ID_TRACKOVERLAY:
916       case GST_MATROSKA_ID_TRACKTRANSLATE:
917       case GST_MATROSKA_ID_TRACKOFFSET:
918       case GST_MATROSKA_ID_CODECSETTINGS:
919       case GST_MATROSKA_ID_CODECINFOURL:
920       case GST_MATROSKA_ID_CODECDOWNLOADURL:
921       case GST_MATROSKA_ID_CODECDECODEALL:
922         ret = gst_ebml_read_skip (ebml);
923         break;
924     }
925   }
926 
927   DEBUG_ELEMENT_STOP (parse, ebml, "TrackEntry", ret);
928 
929   /* Decode codec private data if necessary */
930   if (context->encodings && context->encodings->len > 0 && context->codec_priv
931       && context->codec_priv_size > 0) {
932     if (!gst_matroska_decode_data (context->encodings,
933             &context->codec_priv, &context->codec_priv_size,
934             GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
935       GST_WARNING_OBJECT (parse, "Decoding codec private data failed");
936       ret = GST_FLOW_ERROR;
937     }
938   }
939 
940   if (context->type == 0 || context->codec_id == NULL || (ret != GST_FLOW_OK
941           && ret != GST_FLOW_EOS)) {
942     if (ret == GST_FLOW_OK || ret == GST_FLOW_EOS)
943       GST_WARNING_OBJECT (ebml, "Unknown stream/codec in track entry header");
944 
945     parse->common.num_streams--;
946     g_ptr_array_remove_index (parse->common.src, parse->common.num_streams);
947     g_assert (parse->common.src->len == parse->common.num_streams);
948     gst_matroska_track_free (context);
949 
950     return ret;
951   }
952 
953   if ((context->language == NULL || *context->language == '\0') &&
954       (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO ||
955           context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
956     GST_LOG ("stream %d: language=eng (assuming default)", context->index);
957     context->language = g_strdup ("eng");
958   }
959 
960 
961   /* tadaah! */
962   return ret;
963 }
964 
965 static gboolean
gst_matroska_parse_query(GstMatroskaParse * parse,GstPad * pad,GstQuery * query)966 gst_matroska_parse_query (GstMatroskaParse * parse, GstPad * pad,
967     GstQuery * query)
968 {
969   gboolean res = FALSE;
970   GstMatroskaTrackContext *context = NULL;
971 
972   if (pad) {
973     context = gst_pad_get_element_private (pad);
974   }
975 
976   switch (GST_QUERY_TYPE (query)) {
977     case GST_QUERY_POSITION:
978     {
979       GstFormat format;
980 
981       gst_query_parse_position (query, &format, NULL);
982 
983       if (format == GST_FORMAT_TIME) {
984         GST_OBJECT_LOCK (parse);
985         if (context)
986           gst_query_set_position (query, GST_FORMAT_TIME, context->pos);
987         else
988           gst_query_set_position (query, GST_FORMAT_TIME,
989               parse->common.segment.position);
990         GST_OBJECT_UNLOCK (parse);
991       } else if (format == GST_FORMAT_DEFAULT && context
992           && context->default_duration) {
993         GST_OBJECT_LOCK (parse);
994         gst_query_set_position (query, GST_FORMAT_DEFAULT,
995             context->pos / context->default_duration);
996         GST_OBJECT_UNLOCK (parse);
997       } else {
998         GST_DEBUG_OBJECT (parse,
999             "only position query in TIME and DEFAULT format is supported");
1000       }
1001 
1002       res = TRUE;
1003       break;
1004     }
1005     case GST_QUERY_DURATION:
1006     {
1007       GstFormat format;
1008 
1009       gst_query_parse_duration (query, &format, NULL);
1010 
1011       if (format == GST_FORMAT_TIME) {
1012         GST_OBJECT_LOCK (parse);
1013         gst_query_set_duration (query, GST_FORMAT_TIME,
1014             parse->common.segment.duration);
1015         GST_OBJECT_UNLOCK (parse);
1016       } else if (format == GST_FORMAT_DEFAULT && context
1017           && context->default_duration) {
1018         GST_OBJECT_LOCK (parse);
1019         gst_query_set_duration (query, GST_FORMAT_DEFAULT,
1020             parse->common.segment.duration / context->default_duration);
1021         GST_OBJECT_UNLOCK (parse);
1022       } else {
1023         GST_DEBUG_OBJECT (parse,
1024             "only duration query in TIME and DEFAULT format is supported");
1025       }
1026 
1027       res = TRUE;
1028       break;
1029     }
1030 
1031     case GST_QUERY_SEEKING:
1032     {
1033       GstFormat fmt;
1034 
1035       gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
1036       if (fmt == GST_FORMAT_TIME) {
1037         gboolean seekable;
1038 
1039         /* assuming we'll be able to get an index ... */
1040         seekable = parse->seekable;
1041 
1042         gst_query_set_seeking (query, GST_FORMAT_TIME, seekable,
1043             0, parse->common.segment.duration);
1044         res = TRUE;
1045       }
1046       break;
1047     }
1048     default:
1049       if (pad)
1050         res = gst_pad_query_default (pad, (GstObject *) parse, query);
1051       break;
1052   }
1053 
1054   return res;
1055 }
1056 
1057 static gboolean
gst_matroska_parse_element_query(GstElement * element,GstQuery * query)1058 gst_matroska_parse_element_query (GstElement * element, GstQuery * query)
1059 {
1060   return gst_matroska_parse_query (GST_MATROSKA_PARSE (element), NULL, query);
1061 }
1062 
1063 static gboolean
gst_matroska_parse_handle_src_query(GstPad * pad,GstObject * parent,GstQuery * query)1064 gst_matroska_parse_handle_src_query (GstPad * pad, GstObject * parent,
1065     GstQuery * query)
1066 {
1067   gboolean ret;
1068   GstMatroskaParse *parse = GST_MATROSKA_PARSE (parent);
1069 
1070   ret = gst_matroska_parse_query (parse, pad, query);
1071 
1072   return ret;
1073 }
1074 
1075 static void
gst_matroska_parse_send_tags(GstMatroskaParse * parse)1076 gst_matroska_parse_send_tags (GstMatroskaParse * parse)
1077 {
1078   if (G_UNLIKELY (parse->common.global_tags_changed)) {
1079     GstEvent *tag_event;
1080     gst_tag_list_add (parse->common.global_tags, GST_TAG_MERGE_REPLACE,
1081         GST_TAG_CONTAINER_FORMAT, "Matroska", NULL);
1082     GST_DEBUG_OBJECT (parse, "Sending global_tags %p : %" GST_PTR_FORMAT,
1083         parse->common.global_tags, parse->common.global_tags);
1084 
1085     /* Send a copy as we want to keep our local ref writable to add more tags
1086      * if any are found */
1087     tag_event =
1088         gst_event_new_tag (gst_tag_list_copy (parse->common.global_tags));
1089 
1090     gst_pad_push_event (parse->srcpad, tag_event);
1091 
1092     parse->common.global_tags_changed = FALSE;
1093   }
1094 }
1095 
1096 /* returns FALSE if there are no pads to deliver event to,
1097  * otherwise TRUE (whatever the outcome of event sending),
1098  * takes ownership of the passed event! */
1099 static gboolean
gst_matroska_parse_send_event(GstMatroskaParse * parse,GstEvent * event)1100 gst_matroska_parse_send_event (GstMatroskaParse * parse, GstEvent * event)
1101 {
1102   gboolean ret = FALSE;
1103 
1104   g_return_val_if_fail (event != NULL, FALSE);
1105 
1106   GST_DEBUG_OBJECT (parse, "Sending event of type %s to all source pads",
1107       GST_EVENT_TYPE_NAME (event));
1108 
1109   gst_pad_push_event (parse->srcpad, event);
1110 
1111   return ret;
1112 }
1113 
1114 static gboolean
gst_matroska_parse_element_send_event(GstElement * element,GstEvent * event)1115 gst_matroska_parse_element_send_event (GstElement * element, GstEvent * event)
1116 {
1117   GstMatroskaParse *parse = GST_MATROSKA_PARSE (element);
1118   gboolean res;
1119 
1120   g_return_val_if_fail (event != NULL, FALSE);
1121 
1122   if (GST_EVENT_TYPE (event) == GST_EVENT_SEEK) {
1123     res = gst_matroska_parse_handle_seek_event (parse, NULL, event);
1124   } else {
1125     GST_WARNING_OBJECT (parse, "Unhandled event of type %s",
1126         GST_EVENT_TYPE_NAME (event));
1127     res = FALSE;
1128   }
1129   gst_event_unref (event);
1130   return res;
1131 }
1132 
1133 #if 0
1134 /* searches for a cluster start from @pos,
1135  * return GST_FLOW_OK and cluster position in @pos if found */
1136 static GstFlowReturn
1137 gst_matroska_parse_search_cluster (GstMatroskaParse * parse, gint64 * pos)
1138 {
1139   gint64 newpos = *pos;
1140   gint64 orig_offset;
1141   GstFlowReturn ret = GST_FLOW_OK;
1142   const guint chunk = 64 * 1024;
1143   GstBuffer *buf;
1144   GstMapInfo map;
1145   gpointer data;
1146   gsize size;
1147   guint64 length;
1148   guint32 id;
1149   guint needed;
1150 
1151   orig_offset = parse->common.offset;
1152 
1153   /* read in at newpos and scan for ebml cluster id */
1154   while (1) {
1155     GstByteReader reader;
1156     gint cluster_pos;
1157 
1158     buf = NULL;
1159     ret = gst_pad_pull_range (parse->common.sinkpad, newpos, chunk, &buf);
1160     if (ret != GST_FLOW_OK)
1161       break;
1162     GST_DEBUG_OBJECT (parse,
1163         "read buffer size %" G_GSIZE_FORMAT " at offset %" G_GINT64_FORMAT,
1164         gst_buffer_get_size (buf), newpos);
1165     gst_buffer_map (buf, &map, GST_MAP_READ);
1166     data = map.data;
1167     size = map.size;
1168     gst_byte_reader_init (&reader, data, size);
1169     cluster_pos = 0;
1170   resume:
1171     cluster_pos = gst_byte_reader_masked_scan_uint32 (&reader, 0xffffffff,
1172         GST_MATROSKA_ID_CLUSTER, cluster_pos, size - cluster_pos);
1173     if (cluster_pos >= 0) {
1174       newpos += cluster_pos;
1175       GST_DEBUG_OBJECT (parse,
1176           "found cluster ebml id at offset %" G_GINT64_FORMAT, newpos);
1177       /* extra checks whether we really sync'ed to a cluster:
1178        * - either it is the first and only cluster
1179        * - either there is a cluster after this one
1180        * - either cluster length is undefined
1181        */
1182       /* ok if first cluster (there may not a subsequent one) */
1183       if (newpos == parse->first_cluster_offset) {
1184         GST_DEBUG_OBJECT (parse, "cluster is first cluster -> OK");
1185         break;
1186       }
1187       parse->common.offset = newpos;
1188       ret = gst_matroska_read_common_peek_id_length_pull (&parse->common,
1189           GST_ELEMENT_CAST (parse), &id, &length, &needed);
1190       if (ret != GST_FLOW_OK)
1191         goto resume;
1192       g_assert (id == GST_MATROSKA_ID_CLUSTER);
1193       GST_DEBUG_OBJECT (parse, "cluster size %" G_GUINT64_FORMAT ", prefix %d",
1194           length, needed);
1195       /* ok if undefined length or first cluster */
1196       if (length == G_MAXUINT64) {
1197         GST_DEBUG_OBJECT (parse, "cluster has undefined length -> OK");
1198         break;
1199       }
1200       /* skip cluster */
1201       parse->common.offset += length + needed;
1202       ret = gst_matroska_read_common_peek_id_length_pull (&parse->common,
1203           GST_ELEMENT_CAST (parse), &id, &length, &needed);
1204       if (ret != GST_FLOW_OK)
1205         goto resume;
1206       GST_DEBUG_OBJECT (parse, "next element is %scluster",
1207           id == GST_MATROSKA_ID_CLUSTER ? "" : "not ");
1208       if (id == GST_MATROSKA_ID_CLUSTER)
1209         break;
1210       /* not ok, resume */
1211       goto resume;
1212     } else {
1213       /* partial cluster id may have been in tail of buffer */
1214       newpos += MAX (size, 4) - 3;
1215       gst_buffer_unmap (buf, &map);
1216       gst_buffer_unref (buf);
1217       buf = NULL;
1218     }
1219   }
1220 
1221   if (buf) {
1222     gst_buffer_unmap (buf, &map);
1223     gst_buffer_unref (buf);
1224     buf = NULL;
1225   }
1226 
1227   parse->common.offset = orig_offset;
1228   *pos = newpos;
1229   return ret;
1230 }
1231 #endif
1232 
1233 static gboolean
gst_matroska_parse_handle_seek_event(GstMatroskaParse * parse,GstPad * pad,GstEvent * event)1234 gst_matroska_parse_handle_seek_event (GstMatroskaParse * parse,
1235     GstPad * pad, GstEvent * event)
1236 {
1237   GstMatroskaIndex *entry = NULL;
1238   GstSeekFlags flags;
1239   GstSeekType cur_type, stop_type;
1240   GstFormat format;
1241   gdouble rate;
1242   gint64 cur, stop;
1243   GstMatroskaTrackContext *track = NULL;
1244   GstSegment seeksegment = { 0, };
1245   gboolean update;
1246   GstSearchMode snap_dir;
1247 
1248   if (pad)
1249     track = gst_pad_get_element_private (pad);
1250 
1251   track = gst_matroska_read_common_get_seek_track (&parse->common, track);
1252 
1253   gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
1254       &stop_type, &stop);
1255 
1256   /* we can only seek on time */
1257   if (format != GST_FORMAT_TIME) {
1258     GST_DEBUG_OBJECT (parse, "Can only seek on TIME");
1259     return FALSE;
1260   }
1261 
1262   /* copy segment, we need this because we still need the old
1263    * segment when we close the current segment. */
1264   memcpy (&seeksegment, &parse->common.segment, sizeof (GstSegment));
1265 
1266   if (event) {
1267     GST_DEBUG_OBJECT (parse, "configuring seek");
1268     gst_segment_do_seek (&seeksegment, rate, format, flags,
1269         cur_type, cur, stop_type, stop, &update);
1270   }
1271 
1272   GST_DEBUG_OBJECT (parse, "New segment %" GST_SEGMENT_FORMAT, &seeksegment);
1273 
1274   if (seeksegment.rate < 0)
1275     snap_dir = GST_SEARCH_MODE_AFTER;
1276   else
1277     snap_dir = GST_SEARCH_MODE_BEFORE;
1278 
1279   /* check sanity before we start flushing and all that */
1280   GST_OBJECT_LOCK (parse);
1281   if ((entry = gst_matroska_read_common_do_index_seek (&parse->common, track,
1282               seeksegment.position, &parse->seek_index, &parse->seek_entry,
1283               snap_dir)) == NULL) {
1284     /* pull mode without index can scan later on */
1285     GST_DEBUG_OBJECT (parse, "No matching seek entry in index");
1286     GST_OBJECT_UNLOCK (parse);
1287     return FALSE;
1288   }
1289   GST_DEBUG_OBJECT (parse, "Seek position looks sane");
1290   GST_OBJECT_UNLOCK (parse);
1291 
1292   /* need to seek to cluster start to pick up cluster time */
1293   /* upstream takes care of flushing and all that
1294    * ... and newsegment event handling takes care of the rest */
1295   return perform_seek_to_offset (parse, entry->pos
1296       + parse->common.ebml_segment_start);
1297 }
1298 
1299 /*
1300  * Handle whether we can perform the seek event or if we have to let the chain
1301  * function handle seeks to build the seek indexes first.
1302  */
1303 static gboolean
gst_matroska_parse_handle_seek_push(GstMatroskaParse * parse,GstPad * pad,GstEvent * event)1304 gst_matroska_parse_handle_seek_push (GstMatroskaParse * parse, GstPad * pad,
1305     GstEvent * event)
1306 {
1307   GstSeekFlags flags;
1308   GstSeekType cur_type, stop_type;
1309   GstFormat format;
1310   gdouble rate;
1311   gint64 cur, stop;
1312 
1313   gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
1314       &stop_type, &stop);
1315 
1316   /* sanity checks */
1317 
1318   /* we can only seek on time */
1319   if (format != GST_FORMAT_TIME) {
1320     GST_DEBUG_OBJECT (parse, "Can only seek on TIME");
1321     return FALSE;
1322   }
1323 
1324   if (stop_type != GST_SEEK_TYPE_NONE && stop != GST_CLOCK_TIME_NONE) {
1325     GST_DEBUG_OBJECT (parse, "Seek end-time not supported in streaming mode");
1326     return FALSE;
1327   }
1328 
1329   if (!(flags & GST_SEEK_FLAG_FLUSH)) {
1330     GST_DEBUG_OBJECT (parse,
1331         "Non-flushing seek not supported in streaming mode");
1332     return FALSE;
1333   }
1334 
1335   if (flags & GST_SEEK_FLAG_SEGMENT) {
1336     GST_DEBUG_OBJECT (parse, "Segment seek not supported in streaming mode");
1337     return FALSE;
1338   }
1339 
1340   /* check for having parsed index already */
1341   if (!parse->common.index_parsed) {
1342     gboolean building_index;
1343     guint64 offset = 0;
1344 
1345     if (!parse->index_offset) {
1346       GST_DEBUG_OBJECT (parse, "no index (location); no seek in push mode");
1347       return FALSE;
1348     }
1349 
1350     GST_OBJECT_LOCK (parse);
1351     /* handle the seek event in the chain function */
1352     parse->common.state = GST_MATROSKA_READ_STATE_SEEK;
1353     /* no more seek can be issued until state reset to _DATA */
1354 
1355     /* copy the event */
1356     if (parse->seek_event)
1357       gst_event_unref (parse->seek_event);
1358     parse->seek_event = gst_event_ref (event);
1359 
1360     /* set the building_index flag so that only one thread can setup the
1361      * structures for index seeking. */
1362     building_index = parse->building_index;
1363     if (!building_index) {
1364       parse->building_index = TRUE;
1365       offset = parse->index_offset;
1366     }
1367     GST_OBJECT_UNLOCK (parse);
1368 
1369     if (!building_index) {
1370       /* seek to the first subindex or legacy index */
1371       GST_INFO_OBJECT (parse, "Seeking to Cues at %" G_GUINT64_FORMAT, offset);
1372       return perform_seek_to_offset (parse, offset);
1373     }
1374 
1375     /* well, we are handling it already */
1376     return TRUE;
1377   }
1378 
1379   /* delegate to tweaked regular seek */
1380   return gst_matroska_parse_handle_seek_event (parse, pad, event);
1381 }
1382 
1383 static gboolean
gst_matroska_parse_handle_src_event(GstPad * pad,GstObject * parent,GstEvent * event)1384 gst_matroska_parse_handle_src_event (GstPad * pad, GstObject * parent,
1385     GstEvent * event)
1386 {
1387   GstMatroskaParse *parse = GST_MATROSKA_PARSE (parent);
1388   gboolean res = TRUE;
1389 
1390   switch (GST_EVENT_TYPE (event)) {
1391     case GST_EVENT_SEEK:
1392       /* no seeking until we are (safely) ready */
1393       if (parse->common.state != GST_MATROSKA_READ_STATE_DATA) {
1394         GST_DEBUG_OBJECT (parse, "not ready for seeking yet");
1395         return FALSE;
1396       }
1397       res = gst_matroska_parse_handle_seek_push (parse, pad, event);
1398       gst_event_unref (event);
1399       break;
1400 
1401     case GST_EVENT_QOS:
1402     {
1403       GstMatroskaTrackContext *context = gst_pad_get_element_private (pad);
1404       if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
1405         GstMatroskaTrackVideoContext *videocontext =
1406             (GstMatroskaTrackVideoContext *) context;
1407         gdouble proportion;
1408         GstClockTimeDiff diff;
1409         GstClockTime timestamp;
1410 
1411         gst_event_parse_qos (event, NULL, &proportion, &diff, &timestamp);
1412 
1413         GST_OBJECT_LOCK (parse);
1414         videocontext->earliest_time = timestamp + diff;
1415         GST_OBJECT_UNLOCK (parse);
1416       }
1417       res = TRUE;
1418       gst_event_unref (event);
1419       break;
1420     }
1421 
1422       /* events we don't need to handle */
1423     case GST_EVENT_NAVIGATION:
1424       gst_event_unref (event);
1425       res = FALSE;
1426       break;
1427 
1428     case GST_EVENT_LATENCY:
1429     default:
1430       res = gst_pad_push_event (parse->common.sinkpad, event);
1431       break;
1432   }
1433 
1434   return res;
1435 }
1436 
1437 static GstFlowReturn
gst_matroska_parse_parse_tracks(GstMatroskaParse * parse,GstEbmlRead * ebml)1438 gst_matroska_parse_parse_tracks (GstMatroskaParse * parse, GstEbmlRead * ebml)
1439 {
1440   GstFlowReturn ret = GST_FLOW_OK;
1441   guint32 id;
1442 
1443   DEBUG_ELEMENT_START (parse, ebml, "Tracks");
1444 
1445   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
1446     DEBUG_ELEMENT_STOP (parse, ebml, "Tracks", ret);
1447     return ret;
1448   }
1449 
1450   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1451     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1452       break;
1453 
1454     switch (id) {
1455         /* one track within the "all-tracks" header */
1456       case GST_MATROSKA_ID_TRACKENTRY:
1457         ret = gst_matroska_parse_add_stream (parse, ebml);
1458         break;
1459 
1460       default:
1461         ret = gst_matroska_read_common_parse_skip (&parse->common, ebml,
1462             "Track", id);
1463         break;
1464     }
1465   }
1466   DEBUG_ELEMENT_STOP (parse, ebml, "Tracks", ret);
1467 
1468   parse->tracks_parsed = TRUE;
1469 
1470   return ret;
1471 }
1472 
1473 /*
1474  * Read signed/unsigned "EBML" numbers.
1475  * Return: number of bytes processed.
1476  */
1477 
1478 static gint
gst_matroska_ebmlnum_uint(guint8 * data,guint size,guint64 * num)1479 gst_matroska_ebmlnum_uint (guint8 * data, guint size, guint64 * num)
1480 {
1481   gint len_mask = 0x80, read = 1, n = 1, num_ffs = 0;
1482   guint64 total;
1483 
1484   if (size <= 0) {
1485     return -1;
1486   }
1487 
1488   total = data[0];
1489   while (read <= 8 && !(total & len_mask)) {
1490     read++;
1491     len_mask >>= 1;
1492   }
1493   if (read > 8)
1494     return -1;
1495 
1496   if ((total &= (len_mask - 1)) == len_mask - 1)
1497     num_ffs++;
1498   if (size < read)
1499     return -1;
1500   while (n < read) {
1501     if (data[n] == 0xff)
1502       num_ffs++;
1503     total = (total << 8) | data[n];
1504     n++;
1505   }
1506 
1507   if (read == num_ffs && total != 0)
1508     *num = G_MAXUINT64;
1509   else
1510     *num = total;
1511 
1512   return read;
1513 }
1514 
1515 static gint
gst_matroska_ebmlnum_sint(guint8 * data,guint size,gint64 * num)1516 gst_matroska_ebmlnum_sint (guint8 * data, guint size, gint64 * num)
1517 {
1518   guint64 unum;
1519   gint res;
1520 
1521   /* read as unsigned number first */
1522   if ((res = gst_matroska_ebmlnum_uint (data, size, &unum)) < 0)
1523     return -1;
1524 
1525   /* make signed */
1526   if (unum == G_MAXUINT64)
1527     *num = G_MAXINT64;
1528   else
1529     *num = unum - ((1 << ((7 * res) - 1)) - 1);
1530 
1531   return res;
1532 }
1533 
1534 static GstFlowReturn
gst_matroska_parse_parse_blockgroup_or_simpleblock(GstMatroskaParse * parse,GstEbmlRead * ebml,guint64 cluster_time,guint64 cluster_offset,gboolean is_simpleblock)1535 gst_matroska_parse_parse_blockgroup_or_simpleblock (GstMatroskaParse * parse,
1536     GstEbmlRead * ebml, guint64 cluster_time, guint64 cluster_offset,
1537     gboolean is_simpleblock)
1538 {
1539   GstMatroskaTrackContext *stream = NULL;
1540   GstFlowReturn ret = GST_FLOW_OK;
1541   gboolean readblock = FALSE;
1542   guint32 id;
1543   guint64 block_duration = 0;
1544   GstBuffer *buf = NULL;
1545   GstMapInfo map;
1546   gint stream_num = -1, n, laces = 0;
1547   guint size = 0;
1548   gint *lace_size = NULL;
1549   gint64 time = 0;
1550   gint flags = 0;
1551   gint64 referenceblock = 0;
1552 
1553   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1554     if (!is_simpleblock) {
1555       if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK) {
1556         goto data_error;
1557       }
1558     } else {
1559       id = GST_MATROSKA_ID_SIMPLEBLOCK;
1560     }
1561 
1562     switch (id) {
1563         /* one block inside the group. Note, block parsing is one
1564          * of the harder things, so this code is a bit complicated.
1565          * See http://www.matroska.org/ for documentation. */
1566       case GST_MATROSKA_ID_SIMPLEBLOCK:
1567       case GST_MATROSKA_ID_BLOCK:
1568       {
1569         guint64 num;
1570         guint8 *data;
1571 
1572         if (buf) {
1573           gst_buffer_unref (buf);
1574           buf = NULL;
1575         }
1576         if ((ret = gst_ebml_read_buffer (ebml, &id, &buf)) != GST_FLOW_OK)
1577           break;
1578 
1579         gst_buffer_map (buf, &map, GST_MAP_READ);
1580         data = map.data;
1581         size = map.size;
1582 
1583         /* first byte(s): blocknum */
1584         if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
1585           goto data_error;
1586         data += n;
1587         size -= n;
1588 
1589         /* fetch stream from num */
1590         stream_num = gst_matroska_read_common_stream_from_num (&parse->common,
1591             num);
1592         if (G_UNLIKELY (size < 3)) {
1593           GST_WARNING_OBJECT (parse, "Invalid size %u", size);
1594           /* non-fatal, try next block(group) */
1595           ret = GST_FLOW_OK;
1596           goto done;
1597         } else if (G_UNLIKELY (stream_num < 0 ||
1598                 stream_num >= parse->common.num_streams)) {
1599           /* let's not give up on a stray invalid track number */
1600           GST_WARNING_OBJECT (parse,
1601               "Invalid stream %d for track number %" G_GUINT64_FORMAT
1602               "; ignoring block", stream_num, num);
1603           goto done;
1604         }
1605 
1606         stream = g_ptr_array_index (parse->common.src, stream_num);
1607 
1608         /* time (relative to cluster time) */
1609         time = ((gint16) GST_READ_UINT16_BE (data));
1610         data += 2;
1611         size -= 2;
1612         flags = GST_READ_UINT8 (data);
1613         data += 1;
1614         size -= 1;
1615 
1616         GST_LOG_OBJECT (parse, "time %" G_GUINT64_FORMAT ", flags %d", time,
1617             flags);
1618 
1619         switch ((flags & 0x06) >> 1) {
1620           case 0x0:            /* no lacing */
1621             laces = 1;
1622             lace_size = g_new (gint, 1);
1623             lace_size[0] = size;
1624             break;
1625 
1626           case 0x1:            /* xiph lacing */
1627           case 0x2:            /* fixed-size lacing */
1628           case 0x3:            /* EBML lacing */
1629             if (size == 0)
1630               goto invalid_lacing;
1631             laces = GST_READ_UINT8 (data) + 1;
1632             data += 1;
1633             size -= 1;
1634             lace_size = g_new0 (gint, laces);
1635 
1636             switch ((flags & 0x06) >> 1) {
1637               case 0x1:        /* xiph lacing */  {
1638                 guint temp, total = 0;
1639 
1640                 for (n = 0; ret == GST_FLOW_OK && n < laces - 1; n++) {
1641                   while (1) {
1642                     if (size == 0)
1643                       goto invalid_lacing;
1644                     temp = GST_READ_UINT8 (data);
1645                     lace_size[n] += temp;
1646                     data += 1;
1647                     size -= 1;
1648                     if (temp != 0xff)
1649                       break;
1650                   }
1651                   total += lace_size[n];
1652                 }
1653                 lace_size[n] = size - total;
1654                 break;
1655               }
1656 
1657               case 0x2:        /* fixed-size lacing */
1658                 for (n = 0; n < laces; n++)
1659                   lace_size[n] = size / laces;
1660                 break;
1661 
1662               case 0x3:        /* EBML lacing */  {
1663                 guint total;
1664 
1665                 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
1666                   goto data_error;
1667                 data += n;
1668                 size -= n;
1669                 total = lace_size[0] = num;
1670                 for (n = 1; ret == GST_FLOW_OK && n < laces - 1; n++) {
1671                   gint64 snum;
1672                   gint r;
1673 
1674                   if ((r = gst_matroska_ebmlnum_sint (data, size, &snum)) < 0)
1675                     goto data_error;
1676                   data += r;
1677                   size -= r;
1678                   lace_size[n] = lace_size[n - 1] + snum;
1679                   total += lace_size[n];
1680                 }
1681                 if (n < laces)
1682                   lace_size[n] = size - total;
1683                 break;
1684               }
1685             }
1686             break;
1687         }
1688 
1689         if (ret != GST_FLOW_OK)
1690           break;
1691 
1692         readblock = TRUE;
1693         break;
1694       }
1695 
1696       case GST_MATROSKA_ID_BLOCKDURATION:{
1697         ret = gst_ebml_read_uint (ebml, &id, &block_duration);
1698         GST_DEBUG_OBJECT (parse, "BlockDuration: %" G_GUINT64_FORMAT,
1699             block_duration);
1700         break;
1701       }
1702 
1703       case GST_MATROSKA_ID_REFERENCEBLOCK:{
1704         ret = gst_ebml_read_sint (ebml, &id, &referenceblock);
1705         GST_DEBUG_OBJECT (parse, "ReferenceBlock: %" G_GINT64_FORMAT,
1706             referenceblock);
1707         break;
1708       }
1709 
1710       case GST_MATROSKA_ID_CODECSTATE:{
1711         guint8 *data;
1712         guint64 data_len = 0;
1713 
1714         if ((ret =
1715                 gst_ebml_read_binary (ebml, &id, &data,
1716                     &data_len)) != GST_FLOW_OK)
1717           break;
1718 
1719         if (G_UNLIKELY (stream == NULL)) {
1720           GST_WARNING_OBJECT (parse,
1721               "Unexpected CodecState subelement - ignoring");
1722           break;
1723         }
1724 
1725         g_free (stream->codec_state);
1726         stream->codec_state = data;
1727         stream->codec_state_size = data_len;
1728 
1729         break;
1730       }
1731 
1732       default:
1733         ret = gst_matroska_read_common_parse_skip (&parse->common, ebml,
1734             "BlockGroup", id);
1735         break;
1736 
1737       case GST_MATROSKA_ID_BLOCKVIRTUAL:
1738       case GST_MATROSKA_ID_BLOCKADDITIONS:
1739       case GST_MATROSKA_ID_REFERENCEPRIORITY:
1740       case GST_MATROSKA_ID_REFERENCEVIRTUAL:
1741       case GST_MATROSKA_ID_SLICES:
1742         GST_DEBUG_OBJECT (parse,
1743             "Skipping BlockGroup subelement 0x%x - ignoring", id);
1744         ret = gst_ebml_read_skip (ebml);
1745         break;
1746     }
1747 
1748     if (is_simpleblock)
1749       break;
1750   }
1751 
1752   /* reading a number or so could have failed */
1753   if (ret != GST_FLOW_OK)
1754     goto data_error;
1755 
1756   if (ret == GST_FLOW_OK && readblock) {
1757     guint64 duration = 0;
1758     gint64 lace_time = 0;
1759     gboolean delta_unit;
1760 
1761     stream = g_ptr_array_index (parse->common.src, stream_num);
1762 
1763     if (cluster_time != GST_CLOCK_TIME_NONE) {
1764       /* FIXME: What to do with negative timestamps? Give timestamp 0 or -1?
1765        * Drop unless the lace contains timestamp 0? */
1766       if (time < 0 && (-time) > cluster_time) {
1767         lace_time = 0;
1768       } else {
1769         if (stream->timecodescale == 1.0)
1770           lace_time = (cluster_time + time) * parse->common.time_scale;
1771         else
1772           lace_time =
1773               gst_util_guint64_to_gdouble ((cluster_time + time) *
1774               parse->common.time_scale) * stream->timecodescale;
1775       }
1776     } else {
1777       lace_time = GST_CLOCK_TIME_NONE;
1778     }
1779 
1780     if (lace_time != GST_CLOCK_TIME_NONE) {
1781       parse->last_timestamp = lace_time;
1782     }
1783     /* need to refresh segment info ASAP */
1784     if (GST_CLOCK_TIME_IS_VALID (lace_time) && parse->need_newsegment) {
1785       GstSegment segment;
1786       GST_DEBUG_OBJECT (parse,
1787           "generating segment starting at %" GST_TIME_FORMAT,
1788           GST_TIME_ARGS (lace_time));
1789       /* pretend we seeked here */
1790       gst_segment_do_seek (&parse->common.segment, parse->common.segment.rate,
1791           GST_FORMAT_TIME, 0, GST_SEEK_TYPE_SET, lace_time,
1792           GST_SEEK_TYPE_SET, GST_CLOCK_TIME_NONE, NULL);
1793       /* now convey our segment notion downstream */
1794       segment = parse->common.segment;
1795       segment.position = segment.start;
1796       gst_matroska_parse_send_event (parse, gst_event_new_segment (&segment));
1797       parse->need_newsegment = FALSE;
1798     }
1799 
1800     if (block_duration) {
1801       if (stream->timecodescale == 1.0)
1802         duration = gst_util_uint64_scale (block_duration,
1803             parse->common.time_scale, 1);
1804       else
1805         duration =
1806             gst_util_gdouble_to_guint64 (gst_util_guint64_to_gdouble
1807             (gst_util_uint64_scale (block_duration, parse->common.time_scale,
1808                     1)) * stream->timecodescale);
1809     } else if (stream->default_duration) {
1810       duration = stream->default_duration * laces;
1811     }
1812     /* else duration is diff between timecode of this and next block */
1813 
1814     /* For SimpleBlock, look at the keyframe bit in flags. Otherwise,
1815        a ReferenceBlock implies that this is not a keyframe. In either
1816        case, it only makes sense for video streams. */
1817     delta_unit = stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
1818         ((is_simpleblock && !(flags & 0x80)) || referenceblock);
1819 
1820     if (delta_unit && stream->set_discont) {
1821       /* When doing seeks or such, we need to restart on key frames or
1822        * decoders might choke. */
1823       GST_DEBUG_OBJECT (parse, "skipping delta unit");
1824       goto done;
1825     }
1826 
1827     for (n = 0; n < laces; n++) {
1828       if (G_UNLIKELY (lace_size[n] > size)) {
1829         GST_WARNING_OBJECT (parse, "Invalid lace size");
1830         break;
1831       }
1832 
1833       /* QoS for video track with an index. the assumption is that
1834          index entries point to keyframes, but if that is not true we
1835          will instad skip until the next keyframe. */
1836       if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
1837           stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
1838           stream->index_table && parse->common.segment.rate > 0.0) {
1839         GstMatroskaTrackVideoContext *videocontext =
1840             (GstMatroskaTrackVideoContext *) stream;
1841         GstClockTime earliest_time;
1842         GstClockTime earliest_stream_time;
1843 
1844         GST_OBJECT_LOCK (parse);
1845         earliest_time = videocontext->earliest_time;
1846         GST_OBJECT_UNLOCK (parse);
1847         earliest_stream_time =
1848             gst_segment_position_from_running_time (&parse->common.segment,
1849             GST_FORMAT_TIME, earliest_time);
1850 
1851         if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
1852             GST_CLOCK_TIME_IS_VALID (earliest_stream_time) &&
1853             lace_time <= earliest_stream_time) {
1854           /* find index entry (keyframe) <= earliest_stream_time */
1855           GstMatroskaIndex *entry =
1856               gst_util_array_binary_search (stream->index_table->data,
1857               stream->index_table->len, sizeof (GstMatroskaIndex),
1858               (GCompareDataFunc) gst_matroska_index_seek_find,
1859               GST_SEARCH_MODE_BEFORE, &earliest_stream_time, NULL);
1860 
1861           /* if that entry (keyframe) is after the current the current
1862              buffer, we can skip pushing (and thus decoding) all
1863              buffers until that keyframe. */
1864           if (entry && GST_CLOCK_TIME_IS_VALID (entry->time) &&
1865               entry->time > lace_time) {
1866             GST_LOG_OBJECT (parse, "Skipping lace before late keyframe");
1867             stream->set_discont = TRUE;
1868             goto next_lace;
1869           }
1870         }
1871       }
1872 #if 0
1873       sub = gst_buffer_create_sub (buf,
1874           GST_BUFFER_SIZE (buf) - size, lace_size[n]);
1875       GST_DEBUG_OBJECT (parse, "created subbuffer %p", sub);
1876 
1877       if (delta_unit)
1878         GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
1879       else
1880         GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
1881 
1882       if (stream->encodings != NULL && stream->encodings->len > 0)
1883         sub = gst_matroska_decode_buffer (stream, sub);
1884 
1885       if (sub == NULL) {
1886         GST_WARNING_OBJECT (parse, "Decoding buffer failed");
1887         goto next_lace;
1888       }
1889 
1890       GST_BUFFER_TIMESTAMP (sub) = lace_time;
1891 
1892       if (GST_CLOCK_TIME_IS_VALID (lace_time)) {
1893         GstClockTime last_stop_end;
1894 
1895         /* Check if this stream is after segment stop */
1896         if (GST_CLOCK_TIME_IS_VALID (parse->common.segment.stop) &&
1897             lace_time >= parse->common.segment.stop) {
1898           GST_DEBUG_OBJECT (parse,
1899               "Stream %d after segment stop %" GST_TIME_FORMAT, stream->index,
1900               GST_TIME_ARGS (parse->common.segment.stop));
1901           gst_buffer_unref (sub);
1902           goto eos;
1903         }
1904         if (offset >= stream->to_offset) {
1905           GST_DEBUG_OBJECT (parse, "Stream %d after playback section",
1906               stream->index);
1907           gst_buffer_unref (sub);
1908           goto eos;
1909         }
1910 
1911         /* handle gaps, e.g. non-zero start-time, or an cue index entry
1912          * that landed us with timestamps not quite intended */
1913         if (GST_CLOCK_TIME_IS_VALID (parse->segment.last_stop) &&
1914             parse->segment.rate > 0.0) {
1915           GstClockTimeDiff diff;
1916 
1917           /* only send newsegments with increasing start times,
1918            * otherwise if these go back and forth downstream (sinks) increase
1919            * accumulated time and running_time */
1920           diff = GST_CLOCK_DIFF (parse->segment.last_stop, lace_time);
1921           if (diff > 2 * GST_SECOND && lace_time > parse->segment.start &&
1922               (!GST_CLOCK_TIME_IS_VALID (parse->segment.stop) ||
1923                   lace_time < parse->segment.stop)) {
1924             GST_DEBUG_OBJECT (parse,
1925                 "Gap of %" G_GINT64_FORMAT " ns detected in"
1926                 "stream %d (%" GST_TIME_FORMAT " -> %" GST_TIME_FORMAT "). "
1927                 "Sending updated NEWSEGMENT events", diff,
1928                 stream->index, GST_TIME_ARGS (stream->pos),
1929                 GST_TIME_ARGS (lace_time));
1930             /* send newsegment events such that the gap is not accounted in
1931              * accum time, hence running_time */
1932             /* close ahead of gap */
1933             gst_matroska_parse_send_event (parse,
1934                 gst_event_new_new_segment (TRUE, parse->segment.rate,
1935                     parse->segment.format, parse->segment.last_stop,
1936                     parse->segment.last_stop, parse->segment.last_stop));
1937             /* skip gap */
1938             gst_matroska_parse_send_event (parse,
1939                 gst_event_new_new_segment (FALSE, parse->segment.rate,
1940                     parse->segment.format, lace_time, parse->segment.stop,
1941                     lace_time));
1942             /* align segment view with downstream,
1943              * prevents double-counting accum when closing segment */
1944             gst_segment_set_newsegment (&parse->segment, FALSE,
1945                 parse->segment.rate, parse->segment.format, lace_time,
1946                 parse->segment.stop, lace_time);
1947             parse->segment.last_stop = lace_time;
1948           }
1949         }
1950 
1951         if (!GST_CLOCK_TIME_IS_VALID (parse->segment.last_stop)
1952             || parse->segment.last_stop < lace_time) {
1953           parse->segment.last_stop = lace_time;
1954         }
1955 
1956         last_stop_end = lace_time;
1957         if (duration) {
1958           GST_BUFFER_DURATION (sub) = duration / laces;
1959           last_stop_end += GST_BUFFER_DURATION (sub);
1960         }
1961 
1962         if (!GST_CLOCK_TIME_IS_VALID (parse->last_stop_end) ||
1963             parse->last_stop_end < last_stop_end)
1964           parse->last_stop_end = last_stop_end;
1965 
1966         if (parse->segment.duration == -1 ||
1967             parse->segment.duration < lace_time) {
1968           gst_segment_set_duration (&parse->segment, GST_FORMAT_TIME,
1969               last_stop_end);
1970           gst_element_post_message (GST_ELEMENT_CAST (parse),
1971               gst_message_new_duration (GST_OBJECT_CAST (parse),
1972                   GST_FORMAT_TIME, GST_CLOCK_TIME_NONE));
1973         }
1974       }
1975 
1976       stream->pos = lace_time;
1977 
1978       gst_matroska_parse_sync_streams (parse);
1979 
1980       if (stream->set_discont) {
1981         GST_DEBUG_OBJECT (parse, "marking DISCONT");
1982         GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DISCONT);
1983         stream->set_discont = FALSE;
1984       }
1985 
1986       /* reverse playback book-keeping */
1987       if (!GST_CLOCK_TIME_IS_VALID (stream->from_time))
1988         stream->from_time = lace_time;
1989       if (stream->from_offset == -1)
1990         stream->from_offset = offset;
1991 
1992       GST_DEBUG_OBJECT (parse,
1993           "Pushing lace %d, data of size %d for stream %d, time=%"
1994           GST_TIME_FORMAT " and duration=%" GST_TIME_FORMAT, n,
1995           GST_BUFFER_SIZE (sub), stream_num,
1996           GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (sub)),
1997           GST_TIME_ARGS (GST_BUFFER_DURATION (sub)));
1998 
1999       if (parse->element_index) {
2000         if (stream->index_writer_id == -1)
2001           gst_index_get_writer_id (parse->element_index,
2002               GST_OBJECT (stream->pad), &stream->index_writer_id);
2003 
2004         GST_LOG_OBJECT (parse, "adding association %" GST_TIME_FORMAT "-> %"
2005             G_GUINT64_FORMAT " for writer id %d",
2006             GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (sub)), cluster_offset,
2007             stream->index_writer_id);
2008         gst_index_add_association (parse->element_index,
2009             stream->index_writer_id, GST_BUFFER_FLAG_IS_SET (sub,
2010                 GST_BUFFER_FLAG_DELTA_UNIT) ? 0 : GST_ASSOCIATION_FLAG_KEY_UNIT,
2011             GST_FORMAT_TIME, GST_BUFFER_TIMESTAMP (sub), GST_FORMAT_BYTES,
2012             cluster_offset, NULL);
2013       }
2014 
2015       gst_buffer_set_caps (sub, GST_PAD_CAPS (parse->srcpad));
2016 
2017       /* Postprocess the buffers depending on the codec used */
2018       if (stream->postprocess_frame) {
2019         GST_LOG_OBJECT (parse, "running post process");
2020         ret = stream->postprocess_frame (GST_ELEMENT (parse), stream, &sub);
2021       }
2022 
2023       ret = gst_pad_push (stream->pad, sub);
2024       if (parse->segment.rate < 0) {
2025         if (lace_time > parse->segment.stop && ret == GST_FLOW_EOS) {
2026           /* In reverse playback we can get a GST_FLOW_EOS when
2027            * we are at the end of the segment, so we just need to jump
2028            * back to the previous section. */
2029           GST_DEBUG_OBJECT (parse, "downstream has reached end of segment");
2030           ret = GST_FLOW_OK;
2031         }
2032       }
2033       /* combine flows */
2034       ret = gst_matroska_parse_combine_flows (parse, stream, ret);
2035 #endif
2036 
2037     next_lace:
2038       size -= lace_size[n];
2039       if (lace_time != GST_CLOCK_TIME_NONE && duration)
2040         lace_time += duration / laces;
2041       else
2042         lace_time = GST_CLOCK_TIME_NONE;
2043     }
2044   }
2045 
2046 done:
2047   if (buf) {
2048     gst_buffer_unmap (buf, &map);
2049     gst_buffer_unref (buf);
2050   }
2051   g_free (lace_size);
2052 
2053   return ret;
2054 
2055   /* EXITS */
2056 invalid_lacing:
2057   {
2058     GST_ELEMENT_WARNING (parse, STREAM, DEMUX, (NULL), ("Invalid lacing size"));
2059     /* non-fatal, try next block(group) */
2060     ret = GST_FLOW_OK;
2061     goto done;
2062   }
2063 data_error:
2064   {
2065     GST_ELEMENT_WARNING (parse, STREAM, DEMUX, (NULL), ("Data error"));
2066     /* non-fatal, try next block(group) */
2067     ret = GST_FLOW_OK;
2068     goto done;
2069   }
2070 }
2071 
2072 /* return FALSE if block(group) should be skipped (due to a seek) */
2073 static inline gboolean
gst_matroska_parse_seek_block(GstMatroskaParse * parse)2074 gst_matroska_parse_seek_block (GstMatroskaParse * parse)
2075 {
2076   if (G_UNLIKELY (parse->seek_block)) {
2077     if (!(--parse->seek_block)) {
2078       return TRUE;
2079     } else {
2080       GST_LOG_OBJECT (parse, "should skip block due to seek");
2081       return FALSE;
2082     }
2083   } else {
2084     return TRUE;
2085   }
2086 }
2087 
2088 static GstFlowReturn
gst_matroska_parse_parse_contents_seekentry(GstMatroskaParse * parse,GstEbmlRead * ebml)2089 gst_matroska_parse_parse_contents_seekentry (GstMatroskaParse * parse,
2090     GstEbmlRead * ebml)
2091 {
2092   GstFlowReturn ret;
2093   guint64 seek_pos = (guint64) - 1;
2094   guint32 seek_id = 0;
2095   guint32 id;
2096 
2097   DEBUG_ELEMENT_START (parse, ebml, "Seek");
2098 
2099   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2100     DEBUG_ELEMENT_STOP (parse, ebml, "Seek", ret);
2101     return ret;
2102   }
2103 
2104   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
2105     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
2106       break;
2107 
2108     switch (id) {
2109       case GST_MATROSKA_ID_SEEKID:
2110       {
2111         guint64 t;
2112 
2113         if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
2114           break;
2115 
2116         GST_DEBUG_OBJECT (parse, "SeekID: %" G_GUINT64_FORMAT, t);
2117         seek_id = t;
2118         break;
2119       }
2120 
2121       case GST_MATROSKA_ID_SEEKPOSITION:
2122       {
2123         guint64 t;
2124 
2125         if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
2126           break;
2127 
2128         if (t > G_MAXINT64) {
2129           GST_WARNING_OBJECT (parse,
2130               "Too large SeekPosition %" G_GUINT64_FORMAT, t);
2131           break;
2132         }
2133 
2134         GST_DEBUG_OBJECT (parse, "SeekPosition: %" G_GUINT64_FORMAT, t);
2135         seek_pos = t;
2136         break;
2137       }
2138 
2139       default:
2140         ret = gst_matroska_read_common_parse_skip (&parse->common, ebml,
2141             "SeekHead", id);
2142         break;
2143     }
2144   }
2145 
2146   if (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)
2147     return ret;
2148 
2149   if (!seek_id || seek_pos == (guint64) - 1) {
2150     GST_WARNING_OBJECT (parse, "Incomplete seekhead entry (0x%x/%"
2151         G_GUINT64_FORMAT ")", seek_id, seek_pos);
2152     return GST_FLOW_OK;
2153   }
2154 
2155   switch (seek_id) {
2156     case GST_MATROSKA_ID_SEEKHEAD:
2157     {
2158     }
2159     case GST_MATROSKA_ID_CUES:
2160     case GST_MATROSKA_ID_TAGS:
2161     case GST_MATROSKA_ID_TRACKS:
2162     case GST_MATROSKA_ID_SEGMENTINFO:
2163     case GST_MATROSKA_ID_ATTACHMENTS:
2164     case GST_MATROSKA_ID_CHAPTERS:
2165     {
2166       guint64 length;
2167 
2168       /* remember */
2169       length = gst_matroska_read_common_get_length (&parse->common);
2170 
2171       if (length == (guint64) - 1) {
2172         GST_DEBUG_OBJECT (parse, "no upstream length, skipping SeakHead entry");
2173         break;
2174       }
2175 
2176       /* check for validity */
2177       if (seek_pos + parse->common.ebml_segment_start + 12 >= length) {
2178         GST_WARNING_OBJECT (parse,
2179             "SeekHead reference lies outside file!" " (%"
2180             G_GUINT64_FORMAT "+%" G_GUINT64_FORMAT "+12 >= %"
2181             G_GUINT64_FORMAT ")", seek_pos, parse->common.ebml_segment_start,
2182             length);
2183         break;
2184       }
2185 
2186       /* only pick up index location when streaming */
2187       if (seek_id == GST_MATROSKA_ID_CUES) {
2188         parse->index_offset = seek_pos + parse->common.ebml_segment_start;
2189         GST_DEBUG_OBJECT (parse, "Cues located at offset %" G_GUINT64_FORMAT,
2190             parse->index_offset);
2191       }
2192       break;
2193     }
2194 
2195     default:
2196       GST_DEBUG_OBJECT (parse, "Ignoring Seek entry for ID=0x%x", seek_id);
2197       break;
2198   }
2199   DEBUG_ELEMENT_STOP (parse, ebml, "Seek", ret);
2200 
2201   return ret;
2202 }
2203 
2204 static GstFlowReturn
gst_matroska_parse_parse_contents(GstMatroskaParse * parse,GstEbmlRead * ebml)2205 gst_matroska_parse_parse_contents (GstMatroskaParse * parse, GstEbmlRead * ebml)
2206 {
2207   GstFlowReturn ret = GST_FLOW_OK;
2208   guint32 id;
2209 
2210   DEBUG_ELEMENT_START (parse, ebml, "SeekHead");
2211 
2212   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2213     DEBUG_ELEMENT_STOP (parse, ebml, "SeekHead", ret);
2214     return ret;
2215   }
2216 
2217   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
2218     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
2219       break;
2220 
2221     switch (id) {
2222       case GST_MATROSKA_ID_SEEKENTRY:
2223       {
2224         ret = gst_matroska_parse_parse_contents_seekentry (parse, ebml);
2225         /* Ignore EOS and errors here */
2226         if (ret != GST_FLOW_OK) {
2227           GST_DEBUG_OBJECT (parse, "Ignoring %s", gst_flow_get_name (ret));
2228           ret = GST_FLOW_OK;
2229         }
2230         break;
2231       }
2232 
2233       default:
2234         ret = gst_matroska_read_common_parse_skip (&parse->common, ebml,
2235             "SeekHead", id);
2236         break;
2237     }
2238   }
2239 
2240   DEBUG_ELEMENT_STOP (parse, ebml, "SeekHead", ret);
2241 
2242   return ret;
2243 }
2244 
2245 #define GST_FLOW_OVERFLOW   GST_FLOW_CUSTOM_ERROR
2246 
2247 #define MAX_BLOCK_SIZE (15 * 1024 * 1024)
2248 
2249 static inline GstFlowReturn
gst_matroska_parse_check_read_size(GstMatroskaParse * parse,guint64 bytes)2250 gst_matroska_parse_check_read_size (GstMatroskaParse * parse, guint64 bytes)
2251 {
2252   if (G_UNLIKELY (bytes > MAX_BLOCK_SIZE)) {
2253     /* only a few blocks are expected/allowed to be large,
2254      * and will be recursed into, whereas others will be read and must fit */
2255     /* fatal in streaming case, as we can't step over easily */
2256     GST_ELEMENT_ERROR (parse, STREAM, DEMUX, (NULL),
2257         ("reading large block of size %" G_GUINT64_FORMAT " not supported; "
2258             "file might be corrupt.", bytes));
2259     return GST_FLOW_ERROR;
2260   } else {
2261     return GST_FLOW_OK;
2262   }
2263 }
2264 
2265 #if 0
2266 /* returns TRUE if we truely are in error state, and should give up */
2267 static inline gboolean
2268 gst_matroska_parse_check_parse_error (GstMatroskaParse * parse)
2269 {
2270   gint64 pos;
2271 
2272   /* sigh, one last attempt above and beyond call of duty ...;
2273    * search for cluster mark following current pos */
2274   pos = parse->common.offset;
2275   GST_WARNING_OBJECT (parse, "parse error, looking for next cluster");
2276   if (gst_matroska_parse_search_cluster (parse, &pos) != GST_FLOW_OK) {
2277     /* did not work, give up */
2278     return TRUE;
2279   } else {
2280     GST_DEBUG_OBJECT (parse, "... found at  %" G_GUINT64_FORMAT, pos);
2281     /* try that position */
2282     parse->common.offset = pos;
2283     return FALSE;
2284   }
2285 }
2286 #endif
2287 
2288 /* initializes @ebml with @bytes from input stream at current offset.
2289  * Returns EOS if insufficient available,
2290  * ERROR if too much was attempted to read. */
2291 static inline GstFlowReturn
gst_matroska_parse_take(GstMatroskaParse * parse,guint64 bytes,GstEbmlRead * ebml)2292 gst_matroska_parse_take (GstMatroskaParse * parse, guint64 bytes,
2293     GstEbmlRead * ebml)
2294 {
2295   GstBuffer *buffer = NULL;
2296   GstFlowReturn ret = GST_FLOW_OK;
2297 
2298   GST_LOG_OBJECT (parse, "taking %" G_GUINT64_FORMAT " bytes for parsing",
2299       bytes);
2300   ret = gst_matroska_parse_check_read_size (parse, bytes);
2301   if (G_UNLIKELY (ret != GST_FLOW_OK)) {
2302     /* otherwise fatal */
2303     ret = GST_FLOW_ERROR;
2304     goto exit;
2305   }
2306   if (gst_adapter_available (parse->common.adapter) < bytes)
2307     return GST_FLOW_EOS;
2308 
2309   buffer = gst_adapter_take_buffer (parse->common.adapter, bytes);
2310   if (G_LIKELY (buffer)) {
2311     gst_ebml_read_init (ebml, GST_ELEMENT_CAST (parse), buffer,
2312         parse->common.offset);
2313     parse->common.offset += bytes;
2314   } else {
2315     ret = GST_FLOW_ERROR;
2316   }
2317 exit:
2318 
2319   return ret;
2320 }
2321 
2322 static void
gst_matroska_parse_check_seekability(GstMatroskaParse * parse)2323 gst_matroska_parse_check_seekability (GstMatroskaParse * parse)
2324 {
2325   GstQuery *query;
2326   gboolean seekable = FALSE;
2327   gint64 start = -1, stop = -1;
2328 
2329   query = gst_query_new_seeking (GST_FORMAT_BYTES);
2330   if (!gst_pad_peer_query (parse->common.sinkpad, query)) {
2331     GST_DEBUG_OBJECT (parse, "seeking query failed");
2332     goto done;
2333   }
2334 
2335   gst_query_parse_seeking (query, NULL, &seekable, &start, &stop);
2336 
2337   /* try harder to query upstream size if we didn't get it the first time */
2338   if (seekable && stop == -1) {
2339     GST_DEBUG_OBJECT (parse, "doing duration query to fix up unset stop");
2340     gst_pad_peer_query_duration (parse->common.sinkpad, GST_FORMAT_BYTES,
2341         &stop);
2342   }
2343 
2344   /* if upstream doesn't know the size, it's likely that it's not seekable in
2345    * practice even if it technically may be seekable */
2346   if (seekable && (start != 0 || stop <= start)) {
2347     GST_DEBUG_OBJECT (parse, "seekable but unknown start/stop -> disable");
2348     seekable = FALSE;
2349   }
2350 
2351 done:
2352   GST_INFO_OBJECT (parse, "seekable: %d (%" G_GUINT64_FORMAT " - %"
2353       G_GUINT64_FORMAT ")", seekable, start, stop);
2354   parse->seekable = seekable;
2355 
2356   gst_query_unref (query);
2357 }
2358 
2359 #if 0
2360 static GstFlowReturn
2361 gst_matroska_parse_find_tracks (GstMatroskaParse * parse)
2362 {
2363   guint32 id;
2364   guint64 before_pos;
2365   guint64 length;
2366   guint needed;
2367   GstFlowReturn ret = GST_FLOW_OK;
2368 
2369   GST_WARNING_OBJECT (parse,
2370       "Found Cluster element before Tracks, searching Tracks");
2371 
2372   /* remember */
2373   before_pos = parse->common.offset;
2374 
2375   /* Search Tracks element */
2376   while (TRUE) {
2377     ret = gst_matroska_read_common_peek_id_length_pull (&parse->common,
2378         GST_ELEMENT_CAST (parse), &id, &length, &needed);
2379     if (ret != GST_FLOW_OK)
2380       break;
2381 
2382     if (id != GST_MATROSKA_ID_TRACKS) {
2383       /* we may be skipping large cluster here, so forego size check etc */
2384       /* ... but we can't skip undefined size; force error */
2385       if (length == G_MAXUINT64) {
2386         ret = gst_matroska_parse_check_read_size (parse, length);
2387         break;
2388       } else {
2389         parse->common.offset += needed;
2390         parse->offset += length;
2391       }
2392       continue;
2393     }
2394 
2395     /* will lead to track parsing ... */
2396     ret = gst_matroska_parse_parse_id (parse, id, length, needed);
2397     break;
2398   }
2399 
2400   /* seek back */
2401   parse->offset = before_pos;
2402 
2403   return ret;
2404 }
2405 #endif
2406 
2407 #define GST_READ_CHECK(stmt)  \
2408 G_STMT_START { \
2409   if (G_UNLIKELY ((ret = (stmt)) != GST_FLOW_OK)) { \
2410     if (ret == GST_FLOW_OVERFLOW) { \
2411       ret = GST_FLOW_OK; \
2412     } \
2413     goto read_error; \
2414   } \
2415 } G_STMT_END
2416 
2417 static void
gst_matroska_parse_accumulate_streamheader(GstMatroskaParse * parse,GstBuffer * buffer)2418 gst_matroska_parse_accumulate_streamheader (GstMatroskaParse * parse,
2419     GstBuffer * buffer)
2420 {
2421   if (parse->pushed_headers) {
2422     GST_WARNING_OBJECT (parse,
2423         "Accumulating headers, but headers are already pushed");
2424   }
2425 
2426   if (parse->streamheader) {
2427     parse->streamheader = gst_buffer_append (parse->streamheader,
2428         gst_buffer_ref (buffer));
2429   } else {
2430     parse->streamheader = gst_buffer_ref (buffer);
2431   }
2432 
2433   GST_DEBUG ("%" G_GSIZE_FORMAT, gst_buffer_get_size (parse->streamheader));
2434 }
2435 
2436 static GstFlowReturn
gst_matroska_parse_output(GstMatroskaParse * parse,GstBuffer * buffer,gboolean keyframe)2437 gst_matroska_parse_output (GstMatroskaParse * parse, GstBuffer * buffer,
2438     gboolean keyframe)
2439 {
2440   GstFlowReturn ret;
2441 
2442   if (!parse->pushed_headers) {
2443     GstCaps *caps;
2444     GstStructure *s;
2445     GValue streamheader = { 0 };
2446     GValue bufval = { 0 };
2447     GstBuffer *buf;
2448 
2449     caps = gst_pad_get_current_caps (parse->common.sinkpad);
2450     if (caps == NULL) {
2451       caps = gst_matroska_parse_forge_caps (parse->common.is_webm,
2452           parse->common.has_video);
2453     } else
2454       caps = gst_caps_make_writable (caps);
2455 
2456     s = gst_caps_get_structure (caps, 0);
2457     g_value_init (&streamheader, GST_TYPE_ARRAY);
2458     g_value_init (&bufval, GST_TYPE_BUFFER);
2459     buf = gst_buffer_copy (parse->streamheader);
2460     GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
2461     gst_value_set_buffer (&bufval, buf);
2462     gst_buffer_unref (buf);
2463     gst_value_array_append_value (&streamheader, &bufval);
2464     g_value_unset (&bufval);
2465     gst_structure_set_value (s, "streamheader", &streamheader);
2466     g_value_unset (&streamheader);
2467     //gst_caps_replace (parse->caps, caps);
2468     gst_pad_set_caps (parse->srcpad, caps);
2469 
2470     if (parse->need_newsegment) {
2471       gst_pad_push_event (parse->srcpad,
2472           gst_event_new_segment (&parse->common.segment));
2473       parse->need_newsegment = FALSE;
2474     }
2475 
2476     buf = gst_buffer_copy (parse->streamheader);
2477     gst_caps_unref (caps);
2478 
2479     GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
2480     GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
2481     GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT);
2482 
2483     ret = gst_pad_push (parse->srcpad, buf);
2484     if (ret != GST_FLOW_OK) {
2485       GST_WARNING_OBJECT (parse, "Failed to push buffer");
2486       return ret;
2487     }
2488 
2489     parse->pushed_headers = TRUE;
2490   }
2491 
2492   if (!keyframe) {
2493     GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
2494   } else {
2495     GST_BUFFER_FLAG_UNSET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
2496   }
2497   if (GST_BUFFER_TIMESTAMP (buffer) != GST_CLOCK_TIME_NONE) {
2498     parse->last_timestamp = GST_BUFFER_TIMESTAMP (buffer);
2499   } else {
2500     GST_BUFFER_TIMESTAMP (buffer) = parse->last_timestamp;
2501   }
2502 
2503   return gst_pad_push (parse->srcpad, gst_buffer_ref (buffer));
2504 }
2505 
2506 static GstFlowReturn
gst_matroska_parse_parse_id(GstMatroskaParse * parse,guint32 id,guint64 length,guint needed)2507 gst_matroska_parse_parse_id (GstMatroskaParse * parse, guint32 id,
2508     guint64 length, guint needed)
2509 {
2510   GstEbmlRead ebml = { 0, };
2511   GstFlowReturn ret = GST_FLOW_OK;
2512   guint64 read;
2513   //GstBuffer *buffer;
2514 
2515   GST_DEBUG_OBJECT (parse, "Parsing Element id 0x%x, "
2516       "size %" G_GUINT64_FORMAT ", prefix %d", id, length, needed);
2517 
2518 #if 0
2519   if (gst_adapter_available (parse->adapter) >= length + needed) {
2520     buffer = gst_adapter_take_buffer (parse->adapter, length + needed);
2521     gst_pad_push (parse->srcpad, buffer);
2522   } else {
2523     ret = GST_FLOW_EOS;
2524   }
2525   //GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2526 
2527   return ret;
2528 #endif
2529 
2530 
2531 
2532   /* if we plan to read and parse this element, we need prefix (id + length)
2533    * and the contents */
2534   /* mind about overflow wrap-around when dealing with undefined size */
2535   read = length;
2536   if (G_LIKELY (length != G_MAXUINT64))
2537     read += needed;
2538 
2539   switch (parse->common.state) {
2540     case GST_MATROSKA_READ_STATE_START:
2541       switch (id) {
2542         case GST_EBML_ID_HEADER:
2543           GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2544           ret = gst_matroska_read_common_parse_header (&parse->common, &ebml);
2545           if (ret != GST_FLOW_OK)
2546             goto parse_failed;
2547           parse->common.state = GST_MATROSKA_READ_STATE_SEGMENT;
2548           gst_matroska_parse_check_seekability (parse);
2549           gst_matroska_parse_accumulate_streamheader (parse, ebml.buf);
2550           break;
2551         default:
2552           goto invalid_header;
2553           break;
2554       }
2555       break;
2556     case GST_MATROSKA_READ_STATE_SEGMENT:
2557       switch (id) {
2558         case GST_MATROSKA_ID_SEGMENT:
2559           /* eat segment prefix */
2560           GST_READ_CHECK (gst_matroska_parse_take (parse, needed, &ebml));
2561           GST_DEBUG_OBJECT (parse,
2562               "Found Segment start at offset %" G_GUINT64_FORMAT " with size %"
2563               G_GUINT64_FORMAT, parse->common.offset, length);
2564           /* seeks are from the beginning of the segment,
2565            * after the segment ID/length */
2566           parse->common.ebml_segment_start = parse->common.offset;
2567           if (length == 0)
2568             length = G_MAXUINT64;
2569           parse->common.ebml_segment_length = length;
2570           parse->common.state = GST_MATROSKA_READ_STATE_HEADER;
2571           gst_matroska_parse_accumulate_streamheader (parse, ebml.buf);
2572           break;
2573         default:
2574           GST_WARNING_OBJECT (parse,
2575               "Expected a Segment ID (0x%x), but received 0x%x!",
2576               GST_MATROSKA_ID_SEGMENT, id);
2577           GST_READ_CHECK (gst_matroska_parse_take (parse, needed, &ebml));
2578           gst_matroska_parse_accumulate_streamheader (parse, ebml.buf);
2579           break;
2580       }
2581       break;
2582     case GST_MATROSKA_READ_STATE_SCANNING:
2583       if (id != GST_MATROSKA_ID_CLUSTER &&
2584           id != GST_MATROSKA_ID_CLUSTERTIMECODE) {
2585         /* we need to skip byte per byte if we are scanning for a new cluster */
2586         read = 1;
2587         goto skip;
2588       } else {
2589         GST_LOG_OBJECT (parse, "Resync done, new cluster found!");
2590         parse->common.start_resync_offset = -1;
2591         parse->common.state = parse->common.state_to_restore;
2592       }
2593       /* fall-through */
2594     case GST_MATROSKA_READ_STATE_HEADER:
2595     case GST_MATROSKA_READ_STATE_DATA:
2596     case GST_MATROSKA_READ_STATE_SEEK:
2597       switch (id) {
2598         case GST_MATROSKA_ID_SEGMENTINFO:
2599           GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2600           if (!parse->common.segmentinfo_parsed) {
2601             ret = gst_matroska_read_common_parse_info (&parse->common,
2602                 GST_ELEMENT_CAST (parse), &ebml);
2603             if (ret == GST_FLOW_OK)
2604               gst_matroska_parse_send_tags (parse);
2605           }
2606           gst_matroska_parse_accumulate_streamheader (parse, ebml.buf);
2607           break;
2608         case GST_MATROSKA_ID_TRACKS:
2609           GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2610           if (!parse->tracks_parsed) {
2611             ret = gst_matroska_parse_parse_tracks (parse, &ebml);
2612           }
2613           gst_matroska_parse_accumulate_streamheader (parse, ebml.buf);
2614           break;
2615         case GST_MATROSKA_ID_CLUSTER:
2616           if (G_UNLIKELY (!parse->tracks_parsed)) {
2617             GST_DEBUG_OBJECT (parse, "Cluster before Track");
2618             goto not_streamable;
2619           }
2620           if (G_UNLIKELY (parse->common.state
2621                   == GST_MATROSKA_READ_STATE_HEADER)) {
2622             parse->common.state = GST_MATROSKA_READ_STATE_DATA;
2623             parse->first_cluster_offset = parse->common.offset;
2624             GST_DEBUG_OBJECT (parse, "signaling no more pads");
2625           }
2626           parse->cluster_time = GST_CLOCK_TIME_NONE;
2627           parse->cluster_offset = parse->common.offset;
2628           if (G_UNLIKELY (!parse->seek_first && parse->seek_block)) {
2629             GST_DEBUG_OBJECT (parse, "seek target block %" G_GUINT64_FORMAT
2630                 " not found in Cluster, trying next Cluster's first block instead",
2631                 parse->seek_block);
2632             parse->seek_block = 0;
2633           }
2634           parse->seek_first = FALSE;
2635           /* record next cluster for recovery */
2636           if (read != G_MAXUINT64)
2637             parse->next_cluster_offset = parse->cluster_offset + read;
2638           /* eat cluster prefix */
2639           GST_READ_CHECK (gst_matroska_parse_take (parse, needed, &ebml));
2640           ret = gst_matroska_parse_output (parse, ebml.buf, TRUE);
2641           //gst_matroska_parse_accumulate_streamheader (parse, ebml.buf);
2642           break;
2643         case GST_MATROSKA_ID_CLUSTERTIMECODE:
2644         {
2645           guint64 num;
2646 
2647           GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2648           if ((ret = gst_ebml_read_uint (&ebml, &id, &num)) != GST_FLOW_OK)
2649             goto parse_failed;
2650           GST_DEBUG_OBJECT (parse, "ClusterTimeCode: %" G_GUINT64_FORMAT, num);
2651           parse->cluster_time = num;
2652 #if 0
2653           if (parse->common.element_index) {
2654             if (parse->common.element_index_writer_id == -1)
2655               gst_index_get_writer_id (parse->common.element_index,
2656                   GST_OBJECT (parse), &parse->common.element_index_writer_id);
2657             GST_LOG_OBJECT (parse, "adding association %" GST_TIME_FORMAT "-> %"
2658                 G_GUINT64_FORMAT " for writer id %d",
2659                 GST_TIME_ARGS (parse->cluster_time), parse->cluster_offset,
2660                 parse->common.element_index_writer_id);
2661             gst_index_add_association (parse->common.element_index,
2662                 parse->common.element_index_writer_id,
2663                 GST_ASSOCIATION_FLAG_KEY_UNIT,
2664                 GST_FORMAT_TIME, parse->cluster_time,
2665                 GST_FORMAT_BYTES, parse->cluster_offset, NULL);
2666           }
2667 #endif
2668           gst_matroska_parse_output (parse, ebml.buf, FALSE);
2669           break;
2670         }
2671         case GST_MATROSKA_ID_BLOCKGROUP:
2672           if (!gst_matroska_parse_seek_block (parse))
2673             goto skip;
2674           GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2675           DEBUG_ELEMENT_START (parse, &ebml, "BlockGroup");
2676           if ((ret = gst_ebml_read_master (&ebml, &id)) == GST_FLOW_OK) {
2677             ret = gst_matroska_parse_parse_blockgroup_or_simpleblock (parse,
2678                 &ebml, parse->cluster_time, parse->cluster_offset, FALSE);
2679           }
2680           DEBUG_ELEMENT_STOP (parse, &ebml, "BlockGroup", ret);
2681           gst_matroska_parse_output (parse, ebml.buf, FALSE);
2682           break;
2683         case GST_MATROSKA_ID_SIMPLEBLOCK:
2684           if (!gst_matroska_parse_seek_block (parse))
2685             goto skip;
2686           GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2687           DEBUG_ELEMENT_START (parse, &ebml, "SimpleBlock");
2688           ret = gst_matroska_parse_parse_blockgroup_or_simpleblock (parse,
2689               &ebml, parse->cluster_time, parse->cluster_offset, TRUE);
2690           DEBUG_ELEMENT_STOP (parse, &ebml, "SimpleBlock", ret);
2691           gst_matroska_parse_output (parse, ebml.buf, FALSE);
2692           break;
2693         case GST_MATROSKA_ID_ATTACHMENTS:
2694           GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2695           if (!parse->common.attachments_parsed) {
2696             ret = gst_matroska_read_common_parse_attachments (&parse->common,
2697                 GST_ELEMENT_CAST (parse), &ebml);
2698             if (ret == GST_FLOW_OK)
2699               gst_matroska_parse_send_tags (parse);
2700           }
2701           gst_matroska_parse_output (parse, ebml.buf, FALSE);
2702           break;
2703         case GST_MATROSKA_ID_TAGS:
2704           GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2705           ret = gst_matroska_read_common_parse_metadata (&parse->common,
2706               GST_ELEMENT_CAST (parse), &ebml);
2707           if (ret == GST_FLOW_OK)
2708             gst_matroska_parse_send_tags (parse);
2709           gst_matroska_parse_accumulate_streamheader (parse, ebml.buf);
2710           break;
2711         case GST_MATROSKA_ID_CHAPTERS:
2712           GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2713           ret = gst_matroska_read_common_parse_chapters (&parse->common, &ebml);
2714           gst_matroska_parse_output (parse, ebml.buf, FALSE);
2715           break;
2716         case GST_MATROSKA_ID_SEEKHEAD:
2717           GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2718           ret = gst_matroska_parse_parse_contents (parse, &ebml);
2719           gst_matroska_parse_output (parse, ebml.buf, FALSE);
2720           break;
2721         case GST_MATROSKA_ID_CUES:
2722           GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2723           if (!parse->common.index_parsed) {
2724             ret = gst_matroska_read_common_parse_index (&parse->common, &ebml);
2725             /* only push based; delayed index building */
2726             if (ret == GST_FLOW_OK
2727                 && parse->common.state == GST_MATROSKA_READ_STATE_SEEK) {
2728               GstEvent *event;
2729 
2730               GST_OBJECT_LOCK (parse);
2731               event = parse->seek_event;
2732               parse->seek_event = NULL;
2733               GST_OBJECT_UNLOCK (parse);
2734 
2735               g_assert (event);
2736               /* unlikely to fail, since we managed to seek to this point */
2737               if (!gst_matroska_parse_handle_seek_event (parse, NULL, event))
2738                 goto seek_failed;
2739               /* resume data handling, main thread clear to seek again */
2740               GST_OBJECT_LOCK (parse);
2741               parse->common.state = GST_MATROSKA_READ_STATE_DATA;
2742               GST_OBJECT_UNLOCK (parse);
2743             }
2744           }
2745           gst_matroska_parse_output (parse, ebml.buf, FALSE);
2746           break;
2747         case GST_MATROSKA_ID_POSITION:
2748         case GST_MATROSKA_ID_PREVSIZE:
2749         case GST_MATROSKA_ID_ENCRYPTEDBLOCK:
2750         case GST_MATROSKA_ID_SILENTTRACKS:
2751           GST_DEBUG_OBJECT (parse,
2752               "Skipping Cluster subelement 0x%x - ignoring", id);
2753           /* fall-through */
2754         default:
2755         skip:
2756           GST_DEBUG_OBJECT (parse, "skipping Element 0x%x", id);
2757           GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2758           gst_matroska_parse_output (parse, ebml.buf, FALSE);
2759           break;
2760       }
2761       break;
2762   }
2763 
2764   if (ret == GST_FLOW_PARSE)
2765     goto parse_failed;
2766 
2767 exit:
2768   gst_ebml_read_clear (&ebml);
2769   return ret;
2770 
2771   /* ERRORS */
2772 read_error:
2773   {
2774     /* simply exit, maybe not enough data yet */
2775     /* no ebml to clear if read error */
2776     return ret;
2777   }
2778 parse_failed:
2779   {
2780     GST_ELEMENT_ERROR (parse, STREAM, DEMUX, (NULL),
2781         ("Failed to parse Element 0x%x", id));
2782     ret = GST_FLOW_ERROR;
2783     goto exit;
2784   }
2785 not_streamable:
2786   {
2787     GST_ELEMENT_ERROR (parse, STREAM, DEMUX, (NULL),
2788         ("File layout does not permit streaming"));
2789     ret = GST_FLOW_ERROR;
2790     goto exit;
2791   }
2792 #if 0
2793 no_tracks:
2794   {
2795     GST_ELEMENT_ERROR (parse, STREAM, DEMUX, (NULL),
2796         ("No Tracks element found"));
2797     ret = GST_FLOW_ERROR;
2798     goto exit;
2799   }
2800 #endif
2801 invalid_header:
2802   {
2803     GST_ELEMENT_ERROR (parse, STREAM, DEMUX, (NULL), ("Invalid header"));
2804     ret = GST_FLOW_ERROR;
2805     goto exit;
2806   }
2807 seek_failed:
2808   {
2809     GST_ELEMENT_ERROR (parse, STREAM, DEMUX, (NULL), ("Failed to seek"));
2810     ret = GST_FLOW_ERROR;
2811     goto exit;
2812   }
2813 }
2814 
2815 #if 0
2816 static void
2817 gst_matroska_parse_loop (GstPad * pad)
2818 {
2819   GstMatroskaParse *parse = GST_MATROSKA_PARSE (GST_PAD_PARENT (pad));
2820   GstFlowReturn ret;
2821   guint32 id;
2822   guint64 length;
2823   guint needed;
2824 
2825   /* If we have to close a segment, send a new segment to do this now */
2826   if (G_LIKELY (parse->common.state == GST_MATROSKA_READ_STATE_DATA)) {
2827     if (G_UNLIKELY (parse->close_segment)) {
2828       gst_matroska_parse_send_event (parse, parse->close_segment);
2829       parse->close_segment = NULL;
2830     }
2831     if (G_UNLIKELY (parse->new_segment)) {
2832       gst_matroska_parse_send_event (parse, parse->new_segment);
2833       parse->new_segment = NULL;
2834     }
2835   }
2836 
2837   ret = gst_matroska_read_common_peek_id_length_pull (&parse->common,
2838       GST_ELEMENT_CAST (parse), &id, &length, &needed);
2839   if (ret == GST_FLOW_EOS)
2840     goto eos;
2841   if (ret != GST_FLOW_OK) {
2842     if (gst_matroska_parse_check_parse_error (parse))
2843       goto pause;
2844     else
2845       return;
2846   }
2847 
2848   GST_LOG_OBJECT (parse, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
2849       "size %" G_GUINT64_FORMAT ", needed %d", parse->offset, id,
2850       length, needed);
2851 
2852   ret = gst_matroska_parse_parse_id (parse, id, length, needed);
2853   if (ret == GST_FLOW_EOS)
2854     goto eos;
2855   if (ret != GST_FLOW_OK)
2856     goto pause;
2857 
2858   /* check if we're at the end of a configured segment */
2859   if (G_LIKELY (parse->src->len)) {
2860     guint i;
2861 
2862     g_assert (parse->num_streams == parse->src->len);
2863     for (i = 0; i < parse->src->len; i++) {
2864       GstMatroskaTrackContext *context = g_ptr_array_index (parse->src, i);
2865       GST_DEBUG_OBJECT (context->pad, "pos %" GST_TIME_FORMAT,
2866           GST_TIME_ARGS (context->pos));
2867       if (context->eos == FALSE)
2868         goto next;
2869     }
2870 
2871     GST_INFO_OBJECT (parse, "All streams are EOS");
2872     ret = GST_FLOW_EOS;
2873     goto eos;
2874   }
2875 
2876 next:
2877   if (G_UNLIKELY (parse->offset ==
2878           gst_matroska_read_common_get_length (&parse->common))) {
2879     GST_LOG_OBJECT (parse, "Reached end of stream");
2880     ret = GST_FLOW_EOS;
2881     goto eos;
2882   }
2883 
2884   return;
2885 
2886   /* ERRORS */
2887 eos:
2888   {
2889     if (parse->segment.rate < 0.0) {
2890       ret = gst_matroska_parse_seek_to_previous_keyframe (parse);
2891       if (ret == GST_FLOW_OK)
2892         return;
2893     }
2894     /* fall-through */
2895   }
2896 pause:
2897   {
2898     const gchar *reason = gst_flow_get_name (ret);
2899     gboolean push_eos = FALSE;
2900 
2901     GST_LOG_OBJECT (parse, "pausing task, reason %s", reason);
2902     parse->segment_running = FALSE;
2903     gst_pad_pause_task (parse->common.sinkpad);
2904 
2905     if (ret == GST_FLOW_EOS) {
2906       /* perform EOS logic */
2907 
2908       /* Close the segment, i.e. update segment stop with the duration
2909        * if no stop was set */
2910       if (GST_CLOCK_TIME_IS_VALID (parse->last_stop_end) &&
2911           !GST_CLOCK_TIME_IS_VALID (parse->segment.stop)) {
2912         GstEvent *event =
2913             gst_event_new_new_segment_full (TRUE, parse->segment.rate,
2914             parse->segment.applied_rate, parse->segment.format,
2915             parse->segment.start,
2916             MAX (parse->last_stop_end, parse->segment.start),
2917             parse->segment.time);
2918         gst_matroska_parse_send_event (parse, event);
2919       }
2920 
2921       if (parse->segment.flags & GST_SEEK_FLAG_SEGMENT) {
2922         gint64 stop;
2923 
2924         /* for segment playback we need to post when (in stream time)
2925          * we stopped, this is either stop (when set) or the duration. */
2926         if ((stop = parse->segment.stop) == -1)
2927           stop = parse->last_stop_end;
2928 
2929         GST_LOG_OBJECT (parse, "Sending segment done, at end of segment");
2930         gst_element_post_message (GST_ELEMENT (parse),
2931             gst_message_new_segment_done (GST_OBJECT (parse), GST_FORMAT_TIME,
2932                 stop));
2933         gst_matroska_parse_send_event (parse,
2934             gst_event_new_segment_done (GST_FORMAT_TIME, stop));
2935       } else {
2936         push_eos = TRUE;
2937       }
2938     } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS) {
2939       /* for fatal errors we post an error message */
2940       GST_ELEMENT_FLOW_ERROR (parse, ret);
2941       push_eos = TRUE;
2942     }
2943     if (push_eos) {
2944       /* send EOS, and prevent hanging if no streams yet */
2945       GST_LOG_OBJECT (parse, "Sending EOS, at end of stream");
2946       if (!gst_matroska_parse_send_event (parse, gst_event_new_eos ()) &&
2947           (ret == GST_FLOW_EOS)) {
2948         GST_ELEMENT_ERROR (parse, STREAM, DEMUX,
2949             (NULL), ("got eos but no streams (yet)"));
2950       }
2951     }
2952     return;
2953   }
2954 }
2955 #endif
2956 
2957 /*
2958  * Create and push a flushing seek event upstream
2959  */
2960 static gboolean
perform_seek_to_offset(GstMatroskaParse * parse,guint64 offset)2961 perform_seek_to_offset (GstMatroskaParse * parse, guint64 offset)
2962 {
2963   GstEvent *event;
2964   gboolean res = 0;
2965 
2966   GST_DEBUG_OBJECT (parse, "Seeking to %" G_GUINT64_FORMAT, offset);
2967 
2968   event =
2969       gst_event_new_seek (1.0, GST_FORMAT_BYTES,
2970       GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, GST_SEEK_TYPE_SET, offset,
2971       GST_SEEK_TYPE_NONE, -1);
2972 
2973   res = gst_pad_push_event (parse->common.sinkpad, event);
2974 
2975   /* newsegment event will update offset */
2976   return res;
2977 }
2978 
2979 /*
2980  * Forge empty default caps when all we know is the stream's EBML
2981  * type and whether it has video or not.
2982  *
2983  * FIXME: Do something with video/x-matroska-3d if possible
2984  */
2985 static GstCaps *
gst_matroska_parse_forge_caps(gboolean is_webm,gboolean has_video)2986 gst_matroska_parse_forge_caps (gboolean is_webm, gboolean has_video)
2987 {
2988   GstCaps *caps;
2989 
2990   if (is_webm) {
2991     if (has_video)
2992       caps = gst_caps_new_empty_simple ("video/webm");
2993     else
2994       caps = gst_caps_new_empty_simple ("audio/webm");
2995   } else {
2996     if (has_video)
2997       caps = gst_caps_new_empty_simple ("video/x-matroska");
2998     else
2999       caps = gst_caps_new_empty_simple ("audio/x-matroska");
3000   }
3001   return caps;
3002 }
3003 
3004 static GstFlowReturn
gst_matroska_parse_chain(GstPad * pad,GstObject * parent,GstBuffer * buffer)3005 gst_matroska_parse_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
3006 {
3007   GstMatroskaParse *parse = GST_MATROSKA_PARSE (parent);
3008   guint available;
3009   GstFlowReturn ret = GST_FLOW_OK;
3010   guint needed = 0;
3011   guint32 id;
3012   guint64 length;
3013 
3014   if (G_UNLIKELY (GST_BUFFER_IS_DISCONT (buffer))) {
3015     GST_DEBUG_OBJECT (parse, "got DISCONT");
3016     gst_adapter_clear (parse->common.adapter);
3017     GST_OBJECT_LOCK (parse);
3018     gst_matroska_read_common_reset_streams (&parse->common,
3019         GST_CLOCK_TIME_NONE, FALSE);
3020     GST_OBJECT_UNLOCK (parse);
3021   }
3022 
3023   gst_adapter_push (parse->common.adapter, buffer);
3024   buffer = NULL;
3025 
3026 next:
3027   available = gst_adapter_available (parse->common.adapter);
3028 
3029   ret = gst_matroska_read_common_peek_id_length_push (&parse->common,
3030       GST_ELEMENT_CAST (parse), &id, &length, &needed);
3031   if (G_UNLIKELY (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)) {
3032     if (parse->common.ebml_segment_length != G_MAXUINT64
3033         && parse->common.offset >=
3034         parse->common.ebml_segment_start + parse->common.ebml_segment_length) {
3035       return GST_FLOW_EOS;
3036     } else {
3037       /*
3038        * parsing error: we need to flush a byte from the adapter if the id is
3039        * not a cluster and so on until we found a new cluser or the
3040        * INVALID_DATA_THRESHOLD is exceeded, we reuse gst_matroska_parse_parse_id
3041        * setting the state to GST_MATROSKA_READ_STATE_SCANNING so the bytes
3042        * are skipped until a new cluster is found
3043        */
3044       gint64 bytes_scanned;
3045       if (parse->common.start_resync_offset == -1) {
3046         parse->common.start_resync_offset = parse->common.offset;
3047         parse->common.state_to_restore = parse->common.state;
3048       }
3049       bytes_scanned = parse->common.offset - parse->common.start_resync_offset;
3050       if (bytes_scanned <= INVALID_DATA_THRESHOLD) {
3051         GST_WARNING_OBJECT (parse,
3052             "parse error, looking for next cluster, actual offset %"
3053             G_GUINT64_FORMAT ", start resync offset %" G_GUINT64_FORMAT,
3054             parse->common.offset, parse->common.start_resync_offset);
3055         parse->common.state = GST_MATROSKA_READ_STATE_SCANNING;
3056         ret = GST_FLOW_OK;
3057       } else {
3058         GST_WARNING_OBJECT (parse,
3059             "unrecoverable parse error, next cluster not found and threshold "
3060             "exceeded, bytes scanned %" G_GINT64_FORMAT, bytes_scanned);
3061         return ret;
3062       }
3063     }
3064   }
3065 
3066   GST_LOG_OBJECT (parse, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
3067       "size %" G_GUINT64_FORMAT ", needed %d, available %d",
3068       parse->common.offset, id, length, needed, available);
3069 
3070   if (needed > available)
3071     return GST_FLOW_OK;
3072 
3073   ret = gst_matroska_parse_parse_id (parse, id, length, needed);
3074   if (ret == GST_FLOW_EOS) {
3075     /* need more data */
3076     return GST_FLOW_OK;
3077   } else if (ret != GST_FLOW_OK) {
3078     return ret;
3079   } else
3080     goto next;
3081 }
3082 
3083 static gboolean
gst_matroska_parse_handle_sink_event(GstPad * pad,GstObject * parent,GstEvent * event)3084 gst_matroska_parse_handle_sink_event (GstPad * pad, GstObject * parent,
3085     GstEvent * event)
3086 {
3087   gboolean res = TRUE;
3088   GstMatroskaParse *parse = GST_MATROSKA_PARSE (GST_PAD_PARENT (pad));
3089 
3090   GST_DEBUG_OBJECT (parse,
3091       "have event type %s: %p on sink pad", GST_EVENT_TYPE_NAME (event), event);
3092 
3093   switch (GST_EVENT_TYPE (event)) {
3094     case GST_EVENT_SEGMENT:
3095     {
3096       const GstSegment *segment;
3097 
3098       /* some debug output */
3099       gst_event_parse_segment (event, &segment);
3100       GST_DEBUG_OBJECT (parse,
3101           "received format %d newsegment %" GST_SEGMENT_FORMAT,
3102           segment->format, segment);
3103 
3104       if (parse->common.state < GST_MATROSKA_READ_STATE_DATA) {
3105         GST_DEBUG_OBJECT (parse, "still starting");
3106         goto exit;
3107       }
3108 
3109       /* we only expect a BYTE segment, e.g. following a seek */
3110       if (segment->format != GST_FORMAT_BYTES) {
3111         GST_DEBUG_OBJECT (parse, "unsupported segment format, ignoring");
3112         goto exit;
3113       }
3114 
3115       GST_DEBUG_OBJECT (parse, "clearing segment state");
3116       /* clear current segment leftover */
3117       gst_adapter_clear (parse->common.adapter);
3118       /* and some streaming setup */
3119       parse->common.offset = segment->start;
3120       /* do not know where we are;
3121        * need to come across a cluster and generate newsegment */
3122       parse->common.segment.position = GST_CLOCK_TIME_NONE;
3123       parse->cluster_time = GST_CLOCK_TIME_NONE;
3124       parse->cluster_offset = 0;
3125       parse->need_newsegment = TRUE;
3126       /* but keep some of the upstream segment */
3127       parse->common.segment.rate = segment->rate;
3128     exit:
3129       /* chain will send initial newsegment after pads have been added,
3130        * or otherwise come up with one */
3131       GST_DEBUG_OBJECT (parse, "eating event");
3132       gst_event_unref (event);
3133       res = TRUE;
3134       break;
3135     }
3136     case GST_EVENT_EOS:
3137     {
3138       if (parse->common.state != GST_MATROSKA_READ_STATE_DATA
3139           && parse->common.state != GST_MATROSKA_READ_STATE_SCANNING) {
3140         gst_event_unref (event);
3141         GST_ELEMENT_ERROR (parse, STREAM, DEMUX,
3142             (NULL), ("got eos and didn't receive a complete header object"));
3143       } else if (parse->common.num_streams == 0) {
3144         GST_ELEMENT_ERROR (parse, STREAM, DEMUX,
3145             (NULL), ("got eos but no streams (yet)"));
3146       } else {
3147         gst_matroska_parse_send_event (parse, event);
3148       }
3149       break;
3150     }
3151     case GST_EVENT_FLUSH_STOP:
3152     {
3153       gst_adapter_clear (parse->common.adapter);
3154       GST_OBJECT_LOCK (parse);
3155       gst_matroska_read_common_reset_streams (&parse->common,
3156           GST_CLOCK_TIME_NONE, TRUE);
3157       GST_OBJECT_UNLOCK (parse);
3158       parse->common.segment.position = GST_CLOCK_TIME_NONE;
3159       parse->cluster_time = GST_CLOCK_TIME_NONE;
3160       parse->cluster_offset = 0;
3161       /* fall-through */
3162     }
3163     default:
3164       res = gst_pad_event_default (pad, parent, event);
3165       break;
3166   }
3167 
3168   return res;
3169 }
3170 
3171 #if 0
3172 static void
3173 gst_matroska_parse_set_index (GstElement * element, GstIndex * index)
3174 {
3175   GstMatroskaParse *parse = GST_MATROSKA_PARSE (element);
3176 
3177   GST_OBJECT_LOCK (parse);
3178   if (parse->common.element_index)
3179     gst_object_unref (parse->common.element_index);
3180   parse->common.element_index = index ? gst_object_ref (index) : NULL;
3181   GST_OBJECT_UNLOCK (parse);
3182   GST_DEBUG_OBJECT (parse, "Set index %" GST_PTR_FORMAT,
3183       parse->common.element_index);
3184 }
3185 
3186 static GstIndex *
3187 gst_matroska_parse_get_index (GstElement * element)
3188 {
3189   GstIndex *result = NULL;
3190   GstMatroskaParse *parse = GST_MATROSKA_PARSE (element);
3191 
3192   GST_OBJECT_LOCK (parse);
3193   if (parse->common.element_index)
3194     result = gst_object_ref (parse->common.element_index);
3195   GST_OBJECT_UNLOCK (parse);
3196 
3197   GST_DEBUG_OBJECT (parse, "Returning index %" GST_PTR_FORMAT, result);
3198 
3199   return result;
3200 }
3201 #endif
3202 
3203 static GstStateChangeReturn
gst_matroska_parse_change_state(GstElement * element,GstStateChange transition)3204 gst_matroska_parse_change_state (GstElement * element,
3205     GstStateChange transition)
3206 {
3207   GstMatroskaParse *parse = GST_MATROSKA_PARSE (element);
3208   GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
3209 
3210   /* handle upwards state changes here */
3211   switch (transition) {
3212     default:
3213       break;
3214   }
3215 
3216   ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
3217 
3218   /* handle downwards state changes */
3219   switch (transition) {
3220     case GST_STATE_CHANGE_PAUSED_TO_READY:
3221       gst_matroska_parse_reset (GST_ELEMENT (parse));
3222       break;
3223     default:
3224       break;
3225   }
3226 
3227   return ret;
3228 }
3229 
3230 gboolean
gst_matroska_parse_plugin_init(GstPlugin * plugin)3231 gst_matroska_parse_plugin_init (GstPlugin * plugin)
3232 {
3233   gst_riff_init ();
3234 
3235   /* create an elementfactory for the matroska_parse element */
3236   if (!gst_element_register (plugin, "matroskaparse",
3237           GST_RANK_NONE, GST_TYPE_MATROSKA_PARSE))
3238     return FALSE;
3239 
3240   return TRUE;
3241 }
3242