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-demux.c: matroska file/stream demuxer
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 demuxing is done correct for all codecs according to spec
31  * TODO: seeking with incomplete or without CUE
32  */
33 
34 /**
35  * SECTION:element-matroskademux
36  *
37  * matroskademux demuxes 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 ! matroskademux ! vorbisdec ! audioconvert ! audioresample ! autoaudiosink
43  * ]| This pipeline demuxes 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 #include <gst/base/base.h>
57 
58 /* For AVI compatibility mode
59    and for fourcc stuff */
60 #include <gst/riff/riff-read.h>
61 #include <gst/riff/riff-ids.h>
62 #include <gst/riff/riff-media.h>
63 
64 #include <gst/audio/audio.h>
65 #include <gst/tag/tag.h>
66 #include <gst/pbutils/pbutils.h>
67 #include <gst/video/video.h>
68 
69 #include "matroska-demux.h"
70 #include "matroska-ids.h"
71 
72 GST_DEBUG_CATEGORY_STATIC (matroskademux_debug);
73 #define GST_CAT_DEFAULT matroskademux_debug
74 
75 #define DEBUG_ELEMENT_START(demux, ebml, element) \
76     GST_DEBUG_OBJECT (demux, "Parsing " element " element at offset %" \
77         G_GUINT64_FORMAT, gst_ebml_read_get_pos (ebml))
78 
79 #define DEBUG_ELEMENT_STOP(demux, ebml, element, ret) \
80     GST_DEBUG_OBJECT (demux, "Parsing " element " element " \
81         " finished with '%s'", gst_flow_get_name (ret))
82 
83 enum
84 {
85   PROP_0,
86   PROP_METADATA,
87   PROP_STREAMINFO,
88   PROP_MAX_GAP_TIME,
89   PROP_MAX_BACKTRACK_DISTANCE
90 };
91 
92 #define DEFAULT_MAX_GAP_TIME           (2 * GST_SECOND)
93 #define DEFAULT_MAX_BACKTRACK_DISTANCE 30
94 #define INVALID_DATA_THRESHOLD         (2 * 1024 * 1024)
95 
96 static GstStaticPadTemplate sink_templ = GST_STATIC_PAD_TEMPLATE ("sink",
97     GST_PAD_SINK,
98     GST_PAD_ALWAYS,
99     GST_STATIC_CAPS ("audio/x-matroska; video/x-matroska; "
100         "video/x-matroska-3d; audio/webm; video/webm")
101     );
102 
103 /* TODO: fill in caps! */
104 
105 static GstStaticPadTemplate audio_src_templ =
106 GST_STATIC_PAD_TEMPLATE ("audio_%u",
107     GST_PAD_SRC,
108     GST_PAD_SOMETIMES,
109     GST_STATIC_CAPS ("ANY")
110     );
111 
112 static GstStaticPadTemplate video_src_templ =
113 GST_STATIC_PAD_TEMPLATE ("video_%u",
114     GST_PAD_SRC,
115     GST_PAD_SOMETIMES,
116     GST_STATIC_CAPS ("ANY")
117     );
118 
119 static GstStaticPadTemplate subtitle_src_templ =
120     GST_STATIC_PAD_TEMPLATE ("subtitle_%u",
121     GST_PAD_SRC,
122     GST_PAD_SOMETIMES,
123     GST_STATIC_CAPS ("text/x-raw, format=pango-markup; application/x-ssa; "
124         "application/x-ass;application/x-usf; subpicture/x-dvd; "
125         "subpicture/x-pgs; subtitle/x-kate; " "application/x-subtitle-unknown")
126     );
127 
128 static GstFlowReturn gst_matroska_demux_parse_id (GstMatroskaDemux * demux,
129     guint32 id, guint64 length, guint needed);
130 
131 /* element functions */
132 static void gst_matroska_demux_loop (GstPad * pad);
133 
134 static gboolean gst_matroska_demux_element_send_event (GstElement * element,
135     GstEvent * event);
136 static gboolean gst_matroska_demux_element_query (GstElement * element,
137     GstQuery * query);
138 
139 /* pad functions */
140 static gboolean gst_matroska_demux_sink_activate (GstPad * sinkpad,
141     GstObject * parent);
142 static gboolean gst_matroska_demux_sink_activate_mode (GstPad * sinkpad,
143     GstObject * parent, GstPadMode mode, gboolean active);
144 
145 static gboolean gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
146     GstPad * pad, GstEvent * event);
147 static gboolean gst_matroska_demux_handle_src_event (GstPad * pad,
148     GstObject * parent, GstEvent * event);
149 static gboolean gst_matroska_demux_handle_src_query (GstPad * pad,
150     GstObject * parent, GstQuery * query);
151 
152 static gboolean gst_matroska_demux_handle_sink_event (GstPad * pad,
153     GstObject * parent, GstEvent * event);
154 static gboolean gst_matroska_demux_handle_sink_query (GstPad * pad,
155     GstObject * parent, GstQuery * query);
156 static GstFlowReturn gst_matroska_demux_chain (GstPad * pad,
157     GstObject * object, GstBuffer * buffer);
158 
159 static GstStateChangeReturn
160 gst_matroska_demux_change_state (GstElement * element,
161     GstStateChange transition);
162 #if 0
163 static void
164 gst_matroska_demux_set_index (GstElement * element, GstIndex * index);
165 static GstIndex *gst_matroska_demux_get_index (GstElement * element);
166 #endif
167 
168 /* caps functions */
169 static GstCaps *gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext
170     * videocontext, const gchar * codec_id, guint8 * data, guint size,
171     gchar ** codec_name, guint32 * riff_fourcc);
172 static GstCaps *gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext
173     * audiocontext, const gchar * codec_id, guint8 * data, guint size,
174     gchar ** codec_name, guint16 * riff_audio_fmt);
175 static GstCaps
176     * gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
177     subtitlecontext, const gchar * codec_id, gpointer data, guint size);
178 static const gchar *gst_matroska_track_encryption_algorithm_name (gint val);
179 static const gchar *gst_matroska_track_encryption_cipher_mode_name (gint val);
180 static const gchar *gst_matroska_track_encoding_scope_name (gint val);
181 
182 /* stream methods */
183 static void gst_matroska_demux_reset (GstElement * element);
184 static gboolean perform_seek_to_offset (GstMatroskaDemux * demux,
185     gdouble rate, guint64 offset, guint32 seqnum, GstSeekFlags flags);
186 
187 /* gobject functions */
188 static void gst_matroska_demux_set_property (GObject * object,
189     guint prop_id, const GValue * value, GParamSpec * pspec);
190 static void gst_matroska_demux_get_property (GObject * object,
191     guint prop_id, GValue * value, GParamSpec * pspec);
192 
193 GType gst_matroska_demux_get_type (void);
194 #define parent_class gst_matroska_demux_parent_class
195 G_DEFINE_TYPE (GstMatroskaDemux, gst_matroska_demux, GST_TYPE_ELEMENT);
196 
197 static void
gst_matroska_demux_finalize(GObject * object)198 gst_matroska_demux_finalize (GObject * object)
199 {
200   GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (object);
201 
202   gst_matroska_read_common_finalize (&demux->common);
203   gst_flow_combiner_free (demux->flowcombiner);
204   G_OBJECT_CLASS (parent_class)->finalize (object);
205 }
206 
207 static void
gst_matroska_demux_class_init(GstMatroskaDemuxClass * klass)208 gst_matroska_demux_class_init (GstMatroskaDemuxClass * klass)
209 {
210   GObjectClass *gobject_class = (GObjectClass *) klass;
211   GstElementClass *gstelement_class = (GstElementClass *) klass;
212 
213   GST_DEBUG_CATEGORY_INIT (matroskademux_debug, "matroskademux", 0,
214       "Matroska demuxer");
215 
216   gobject_class->finalize = gst_matroska_demux_finalize;
217 
218   gobject_class->get_property = gst_matroska_demux_get_property;
219   gobject_class->set_property = gst_matroska_demux_set_property;
220 
221   g_object_class_install_property (gobject_class, PROP_MAX_GAP_TIME,
222       g_param_spec_uint64 ("max-gap-time", "Maximum gap time",
223           "The demuxer sends out segment events for skipping "
224           "gaps longer than this (0 = disabled).", 0, G_MAXUINT64,
225           DEFAULT_MAX_GAP_TIME, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
226 
227   g_object_class_install_property (gobject_class, PROP_MAX_BACKTRACK_DISTANCE,
228       g_param_spec_uint ("max-backtrack-distance",
229           "Maximum backtrack distance",
230           "Maximum backtrack distance in seconds when seeking without "
231           "and index in pull mode and search for a keyframe "
232           "(0 = disable backtracking).",
233           0, G_MAXUINT, DEFAULT_MAX_BACKTRACK_DISTANCE,
234           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
235 
236   gstelement_class->change_state =
237       GST_DEBUG_FUNCPTR (gst_matroska_demux_change_state);
238   gstelement_class->send_event =
239       GST_DEBUG_FUNCPTR (gst_matroska_demux_element_send_event);
240   gstelement_class->query =
241       GST_DEBUG_FUNCPTR (gst_matroska_demux_element_query);
242 #if 0
243   gstelement_class->set_index =
244       GST_DEBUG_FUNCPTR (gst_matroska_demux_set_index);
245   gstelement_class->get_index =
246       GST_DEBUG_FUNCPTR (gst_matroska_demux_get_index);
247 #endif
248 
249   gst_element_class_add_static_pad_template (gstelement_class,
250       &video_src_templ);
251   gst_element_class_add_static_pad_template (gstelement_class,
252       &audio_src_templ);
253   gst_element_class_add_static_pad_template (gstelement_class,
254       &subtitle_src_templ);
255   gst_element_class_add_static_pad_template (gstelement_class, &sink_templ);
256 
257   gst_element_class_set_static_metadata (gstelement_class, "Matroska demuxer",
258       "Codec/Demuxer",
259       "Demuxes Matroska/WebM streams into video/audio/subtitles",
260       "GStreamer maintainers <gstreamer-devel@lists.freedesktop.org>");
261 }
262 
263 static void
gst_matroska_demux_init(GstMatroskaDemux * demux)264 gst_matroska_demux_init (GstMatroskaDemux * demux)
265 {
266   demux->common.sinkpad = gst_pad_new_from_static_template (&sink_templ,
267       "sink");
268   gst_pad_set_activate_function (demux->common.sinkpad,
269       GST_DEBUG_FUNCPTR (gst_matroska_demux_sink_activate));
270   gst_pad_set_activatemode_function (demux->common.sinkpad,
271       GST_DEBUG_FUNCPTR (gst_matroska_demux_sink_activate_mode));
272   gst_pad_set_chain_function (demux->common.sinkpad,
273       GST_DEBUG_FUNCPTR (gst_matroska_demux_chain));
274   gst_pad_set_event_function (demux->common.sinkpad,
275       GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_sink_event));
276   gst_pad_set_query_function (demux->common.sinkpad,
277       GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_sink_query));
278   gst_element_add_pad (GST_ELEMENT (demux), demux->common.sinkpad);
279 
280   /* init defaults for common read context */
281   gst_matroska_read_common_init (&demux->common);
282 
283   /* property defaults */
284   demux->max_gap_time = DEFAULT_MAX_GAP_TIME;
285   demux->max_backtrack_distance = DEFAULT_MAX_BACKTRACK_DISTANCE;
286 
287   GST_OBJECT_FLAG_SET (demux, GST_ELEMENT_FLAG_INDEXABLE);
288 
289   demux->flowcombiner = gst_flow_combiner_new ();
290 
291   /* finish off */
292   gst_matroska_demux_reset (GST_ELEMENT (demux));
293 }
294 
295 static void
gst_matroska_demux_reset(GstElement * element)296 gst_matroska_demux_reset (GstElement * element)
297 {
298   GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
299 
300   GST_DEBUG_OBJECT (demux, "Resetting state");
301 
302   gst_matroska_read_common_reset (GST_ELEMENT (demux), &demux->common);
303 
304   demux->num_a_streams = 0;
305   demux->num_t_streams = 0;
306   demux->num_v_streams = 0;
307   demux->have_nonintraonly_v_streams = FALSE;
308 
309   demux->have_group_id = FALSE;
310   demux->group_id = G_MAXUINT;
311 
312   demux->clock = NULL;
313   demux->tracks_parsed = FALSE;
314 
315   if (demux->clusters) {
316     g_array_free (demux->clusters, TRUE);
317     demux->clusters = NULL;
318   }
319 
320   g_list_foreach (demux->seek_parsed,
321       (GFunc) gst_matroska_read_common_free_parsed_el, NULL);
322   g_list_free (demux->seek_parsed);
323   demux->seek_parsed = NULL;
324 
325   demux->last_stop_end = GST_CLOCK_TIME_NONE;
326   demux->seek_block = 0;
327   demux->stream_start_time = GST_CLOCK_TIME_NONE;
328   demux->to_time = GST_CLOCK_TIME_NONE;
329   demux->cluster_time = GST_CLOCK_TIME_NONE;
330   demux->cluster_offset = 0;
331   demux->cluster_prevsize = 0;
332   demux->seen_cluster_prevsize = FALSE;
333   demux->next_cluster_offset = 0;
334   demux->stream_last_time = GST_CLOCK_TIME_NONE;
335   demux->last_cluster_offset = 0;
336   demux->index_offset = 0;
337   demux->seekable = FALSE;
338   demux->need_segment = FALSE;
339   demux->segment_seqnum = 0;
340   demux->requested_seek_time = GST_CLOCK_TIME_NONE;
341   demux->seek_offset = -1;
342   demux->building_index = FALSE;
343   if (demux->seek_event) {
344     gst_event_unref (demux->seek_event);
345     demux->seek_event = NULL;
346   }
347 
348   demux->seek_index = NULL;
349   demux->seek_entry = 0;
350 
351   if (demux->new_segment) {
352     gst_event_unref (demux->new_segment);
353     demux->new_segment = NULL;
354   }
355 
356   demux->invalid_duration = FALSE;
357 
358   demux->cached_length = G_MAXUINT64;
359 
360   if (demux->deferred_seek_event)
361     gst_event_unref (demux->deferred_seek_event);
362   demux->deferred_seek_event = NULL;
363   demux->deferred_seek_pad = NULL;
364 
365   gst_flow_combiner_clear (demux->flowcombiner);
366 }
367 
368 static GstBuffer *
gst_matroska_decode_buffer(GstMatroskaTrackContext * context,GstBuffer * buf)369 gst_matroska_decode_buffer (GstMatroskaTrackContext * context, GstBuffer * buf)
370 {
371   GstMapInfo map;
372   gpointer data;
373   gsize size;
374   GstBuffer *out_buf = buf;
375 
376   g_return_val_if_fail (GST_IS_BUFFER (buf), NULL);
377 
378   GST_DEBUG ("decoding buffer %p", buf);
379 
380   gst_buffer_map (out_buf, &map, GST_MAP_READ);
381   data = map.data;
382   size = map.size;
383 
384   g_return_val_if_fail (size > 0, buf);
385 
386   if (gst_matroska_decode_data (context->encodings, &data, &size,
387           GST_MATROSKA_TRACK_ENCODING_SCOPE_FRAME, FALSE)) {
388     if (data != map.data) {
389       gst_buffer_unmap (out_buf, &map);
390       gst_buffer_unref (out_buf);
391       out_buf = gst_buffer_new_wrapped (data, size);
392     } else {
393       gst_buffer_unmap (out_buf, &map);
394     }
395   } else {
396     GST_DEBUG ("decode data failed");
397     gst_buffer_unmap (out_buf, &map);
398     gst_buffer_unref (out_buf);
399     return NULL;
400   }
401   /* Encrypted stream */
402   if (context->protection_info) {
403 
404     GstStructure *info_protect = gst_structure_copy (context->protection_info);
405     gboolean encrypted = FALSE;
406 
407     gst_buffer_map (out_buf, &map, GST_MAP_READ);
408     data = map.data;
409     size = map.size;
410 
411     if (gst_matroska_parse_protection_meta (&data, &size, info_protect,
412             &encrypted)) {
413       if (data != map.data) {
414         GstBuffer *tmp_buf;
415 
416         gst_buffer_unmap (out_buf, &map);
417         tmp_buf = out_buf;
418         out_buf = gst_buffer_copy_region (tmp_buf, GST_BUFFER_COPY_ALL,
419             gst_buffer_get_size (tmp_buf) - size, size);
420         gst_buffer_unref (tmp_buf);
421         if (encrypted)
422           gst_buffer_add_protection_meta (out_buf, info_protect);
423         else
424           gst_structure_free (info_protect);
425       } else {
426         gst_buffer_unmap (out_buf, &map);
427         gst_structure_free (info_protect);
428       }
429     } else {
430       GST_WARNING ("Adding protection metadata failed");
431       gst_buffer_unmap (out_buf, &map);
432       gst_buffer_unref (out_buf);
433       gst_structure_free (info_protect);
434       return NULL;
435     }
436   }
437 
438   return out_buf;
439 }
440 
441 static void
gst_matroska_demux_add_stream_headers_to_caps(GstMatroskaDemux * demux,GstBufferList * list,GstCaps * caps)442 gst_matroska_demux_add_stream_headers_to_caps (GstMatroskaDemux * demux,
443     GstBufferList * list, GstCaps * caps)
444 {
445   GstStructure *s;
446   GValue arr_val = G_VALUE_INIT;
447   GValue buf_val = G_VALUE_INIT;
448   gint i, num;
449 
450   g_assert (gst_caps_is_writable (caps));
451 
452   g_value_init (&arr_val, GST_TYPE_ARRAY);
453   g_value_init (&buf_val, GST_TYPE_BUFFER);
454 
455   num = gst_buffer_list_length (list);
456   for (i = 0; i < num; ++i) {
457     g_value_set_boxed (&buf_val, gst_buffer_list_get (list, i));
458     gst_value_array_append_value (&arr_val, &buf_val);
459   }
460 
461   s = gst_caps_get_structure (caps, 0);
462   gst_structure_take_value (s, "streamheader", &arr_val);
463   g_value_unset (&buf_val);
464 }
465 
466 static GstFlowReturn
gst_matroska_demux_parse_colour(GstMatroskaDemux * demux,GstEbmlRead * ebml,GstMatroskaTrackVideoContext * video_context)467 gst_matroska_demux_parse_colour (GstMatroskaDemux * demux, GstEbmlRead * ebml,
468     GstMatroskaTrackVideoContext * video_context)
469 {
470   GstFlowReturn ret;
471   GstVideoColorimetry colorimetry;
472   guint32 id;
473   guint64 num;
474 
475   colorimetry.range = GST_VIDEO_COLOR_RANGE_UNKNOWN;
476   colorimetry.matrix = GST_VIDEO_COLOR_MATRIX_UNKNOWN;
477   colorimetry.transfer = GST_VIDEO_TRANSFER_UNKNOWN;
478   colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_UNKNOWN;
479 
480   DEBUG_ELEMENT_START (demux, ebml, "TrackVideoColour");
481 
482   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
483     goto beach;
484 
485   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
486     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
487       goto beach;
488 
489     switch (id) {
490       case GST_MATROSKA_ID_VIDEOMATRIXCOEFFICIENTS:{
491         if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
492           goto beach;
493 
494         switch (num) {
495           case 0:
496             colorimetry.matrix = GST_VIDEO_COLOR_MATRIX_RGB;
497             break;
498           case 1:
499             colorimetry.matrix = GST_VIDEO_COLOR_MATRIX_BT709;
500             break;
501           case 2:
502             colorimetry.matrix = GST_VIDEO_COLOR_MATRIX_UNKNOWN;
503             break;
504           case 4:
505             colorimetry.matrix = GST_VIDEO_COLOR_MATRIX_FCC;
506             break;
507             /* FIXME: "5: BT470BG" is undefined in GstVideoColorMatrix
508              * but it's functionally same as "6: BT601" */
509           case 5:
510           case 6:
511             colorimetry.matrix = GST_VIDEO_COLOR_MATRIX_BT601;
512             break;
513           case 7:
514             colorimetry.matrix = GST_VIDEO_COLOR_MATRIX_SMPTE240M;
515             break;
516           case 9:
517             colorimetry.matrix = GST_VIDEO_COLOR_MATRIX_BT2020;
518             break;
519           default:
520             GST_FIXME_OBJECT (demux, "Unsupported color matrix coefficients  %"
521                 G_GUINT64_FORMAT, num);
522             break;
523         }
524         break;
525       }
526 
527       case GST_MATROSKA_ID_VIDEORANGE:{
528         if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
529           goto beach;
530 
531         switch (num) {
532           case 0:
533             colorimetry.range = GST_VIDEO_COLOR_RANGE_UNKNOWN;
534             break;
535           case 1:
536             colorimetry.range = GST_VIDEO_COLOR_RANGE_16_235;
537             break;
538           case 2:
539             colorimetry.range = GST_VIDEO_COLOR_RANGE_0_255;
540             break;
541           default:
542             GST_FIXME_OBJECT (demux, "Unsupported color range  %"
543                 G_GUINT64_FORMAT, num);
544             break;
545         }
546         break;
547       }
548 
549       case GST_MATROSKA_ID_VIDEOTRANSFERCHARACTERISTICS:{
550         if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
551           goto beach;
552 
553         switch (num) {
554             /* FIXME: "6: BT601" and "14: BT2020_10" are undefined in
555              * GstVideoTransferFunction, but functionally same as "1: BT709" */
556           case 1:
557           case 6:
558           case 14:
559             colorimetry.transfer = GST_VIDEO_TRANSFER_BT709;
560             break;
561           case 2:
562             colorimetry.transfer = GST_VIDEO_TRANSFER_UNKNOWN;
563             break;
564           case 4:
565             colorimetry.transfer = GST_VIDEO_TRANSFER_GAMMA22;
566             break;
567           case 5:
568             colorimetry.transfer = GST_VIDEO_TRANSFER_GAMMA28;
569             break;
570           case 7:
571             colorimetry.transfer = GST_VIDEO_TRANSFER_SMPTE240M;
572             break;
573           case 8:
574             colorimetry.transfer = GST_VIDEO_TRANSFER_GAMMA10;
575             break;
576           case 9:
577             colorimetry.transfer = GST_VIDEO_TRANSFER_LOG100;
578             break;
579           case 10:
580             colorimetry.transfer = GST_VIDEO_TRANSFER_LOG316;
581             break;
582           case 13:
583             colorimetry.transfer = GST_VIDEO_TRANSFER_SRGB;
584             break;
585           case 15:
586             colorimetry.transfer = GST_VIDEO_TRANSFER_BT2020_12;
587             break;
588           default:
589             GST_FIXME_OBJECT (demux,
590                 "Unsupported color transfer characteristics  %"
591                 G_GUINT64_FORMAT, num);
592             break;
593         }
594         break;
595       }
596 
597       case GST_MATROSKA_ID_VIDEOPRIMARIES:{
598         if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
599           goto beach;
600 
601         switch (num) {
602           case 1:
603             colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_BT709;
604             break;
605           case 2:
606             colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_UNKNOWN;
607             break;
608           case 4:
609             colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_BT470M;
610             break;
611           case 5:
612             colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_BT470BG;
613             break;
614           case 6:
615             colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_SMPTE170M;
616             break;
617           case 7:
618             colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_SMPTE240M;
619             break;
620           case 8:
621             colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_FILM;
622             break;
623           case 9:
624             colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_BT2020;
625             break;
626           default:
627             GST_FIXME_OBJECT (demux, "Unsupported color primaries  %"
628                 G_GUINT64_FORMAT, num);
629             break;
630         }
631         break;
632       }
633 
634       default:
635         GST_FIXME_OBJECT (demux, "Unsupported subelement 0x%x in Colour", id);
636         ret = gst_ebml_read_skip (ebml);
637         break;
638     }
639   }
640 
641   memcpy (&video_context->colorimetry, &colorimetry,
642       sizeof (GstVideoColorimetry));
643 
644 beach:
645   DEBUG_ELEMENT_STOP (demux, ebml, "TrackVideoColour", ret);
646   return ret;
647 }
648 
649 static GstFlowReturn
gst_matroska_demux_parse_stream(GstMatroskaDemux * demux,GstEbmlRead * ebml,GstMatroskaTrackContext ** dest_context)650 gst_matroska_demux_parse_stream (GstMatroskaDemux * demux, GstEbmlRead * ebml,
651     GstMatroskaTrackContext ** dest_context)
652 {
653   GstMatroskaTrackContext *context;
654   GstCaps *caps = NULL;
655   GstTagList *cached_taglist;
656   GstFlowReturn ret;
657   guint32 id, riff_fourcc = 0;
658   guint16 riff_audio_fmt = 0;
659   gchar *codec = NULL;
660 
661   DEBUG_ELEMENT_START (demux, ebml, "TrackEntry");
662 
663   /* start with the master */
664   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
665     DEBUG_ELEMENT_STOP (demux, ebml, "TrackEntry", ret);
666     return ret;
667   }
668 
669   /* allocate generic... if we know the type, we'll g_renew()
670    * with the precise type */
671   context = g_new0 (GstMatroskaTrackContext, 1);
672   context->index_writer_id = -1;
673   context->type = 0;            /* no type yet */
674   context->default_duration = 0;
675   context->pos = 0;
676   context->set_discont = TRUE;
677   context->timecodescale = 1.0;
678   context->flags =
679       GST_MATROSKA_TRACK_ENABLED | GST_MATROSKA_TRACK_DEFAULT |
680       GST_MATROSKA_TRACK_LACING;
681   context->from_time = GST_CLOCK_TIME_NONE;
682   context->from_offset = -1;
683   context->to_offset = G_MAXINT64;
684   context->alignment = 1;
685   context->dts_only = FALSE;
686   context->intra_only = FALSE;
687   context->tags = gst_tag_list_new_empty ();
688   g_queue_init (&context->protection_event_queue);
689   context->protection_info = NULL;
690 
691   GST_DEBUG_OBJECT (demux, "Parsing a TrackEntry (%d tracks parsed so far)",
692       demux->common.num_streams);
693 
694   /* try reading the trackentry headers */
695   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
696     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
697       break;
698 
699     switch (id) {
700         /* track number (unique stream ID) */
701       case GST_MATROSKA_ID_TRACKNUMBER:{
702         guint64 num;
703 
704         if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
705           break;
706 
707         if (num == 0) {
708           GST_ERROR_OBJECT (demux, "Invalid TrackNumber 0");
709           ret = GST_FLOW_ERROR;
710           break;
711         }
712 
713         GST_DEBUG_OBJECT (demux, "TrackNumber: %" G_GUINT64_FORMAT, num);
714         context->num = num;
715         break;
716       }
717         /* track UID (unique identifier) */
718       case GST_MATROSKA_ID_TRACKUID:{
719         guint64 num;
720 
721         if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
722           break;
723 
724         if (num == 0) {
725           GST_ERROR_OBJECT (demux, "Invalid TrackUID 0");
726           ret = GST_FLOW_ERROR;
727           break;
728         }
729 
730         GST_DEBUG_OBJECT (demux, "TrackUID: %" G_GUINT64_FORMAT, num);
731         context->uid = num;
732         break;
733       }
734 
735         /* track type (video, audio, combined, subtitle, etc.) */
736       case GST_MATROSKA_ID_TRACKTYPE:{
737         guint64 track_type;
738 
739         if ((ret = gst_ebml_read_uint (ebml, &id, &track_type)) != GST_FLOW_OK) {
740           break;
741         }
742 
743         if (context->type != 0 && context->type != track_type) {
744           GST_WARNING_OBJECT (demux,
745               "More than one tracktype defined in a TrackEntry - skipping");
746           break;
747         } else if (track_type < 1 || track_type > 254) {
748           GST_WARNING_OBJECT (demux, "Invalid TrackType %" G_GUINT64_FORMAT,
749               track_type);
750           break;
751         }
752 
753         GST_DEBUG_OBJECT (demux, "TrackType: %" G_GUINT64_FORMAT, track_type);
754 
755         /* ok, so we're actually going to reallocate this thing */
756         switch (track_type) {
757           case GST_MATROSKA_TRACK_TYPE_VIDEO:
758             gst_matroska_track_init_video_context (&context);
759             break;
760           case GST_MATROSKA_TRACK_TYPE_AUDIO:
761             gst_matroska_track_init_audio_context (&context);
762             break;
763           case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
764             gst_matroska_track_init_subtitle_context (&context);
765             break;
766           case GST_MATROSKA_TRACK_TYPE_COMPLEX:
767           case GST_MATROSKA_TRACK_TYPE_LOGO:
768           case GST_MATROSKA_TRACK_TYPE_BUTTONS:
769           case GST_MATROSKA_TRACK_TYPE_CONTROL:
770           default:
771             GST_WARNING_OBJECT (demux,
772                 "Unknown or unsupported TrackType %" G_GUINT64_FORMAT,
773                 track_type);
774             context->type = 0;
775             break;
776         }
777         break;
778       }
779 
780         /* tracktype specific stuff for video */
781       case GST_MATROSKA_ID_TRACKVIDEO:{
782         GstMatroskaTrackVideoContext *videocontext;
783 
784         DEBUG_ELEMENT_START (demux, ebml, "TrackVideo");
785 
786         if (!gst_matroska_track_init_video_context (&context)) {
787           GST_WARNING_OBJECT (demux,
788               "TrackVideo element in non-video track - ignoring track");
789           ret = GST_FLOW_ERROR;
790           break;
791         } else if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
792           break;
793         }
794         videocontext = (GstMatroskaTrackVideoContext *) context;
795 
796         while (ret == GST_FLOW_OK &&
797             gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
798           if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
799             break;
800 
801           switch (id) {
802               /* Should be one level up but some broken muxers write it here. */
803             case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
804               guint64 num;
805 
806               if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
807                 break;
808 
809               if (num == 0) {
810                 GST_WARNING_OBJECT (demux, "Invalid TrackDefaultDuration 0");
811                 break;
812               }
813 
814               GST_DEBUG_OBJECT (demux,
815                   "TrackDefaultDuration: %" G_GUINT64_FORMAT, num);
816               context->default_duration = num;
817               break;
818             }
819 
820               /* video framerate */
821               /* NOTE: This one is here only for backward compatibility.
822                * Use _TRACKDEFAULDURATION one level up. */
823             case GST_MATROSKA_ID_VIDEOFRAMERATE:{
824               gdouble num;
825 
826               if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
827                 break;
828 
829               if (num <= 0.0) {
830                 GST_WARNING_OBJECT (demux, "Invalid TrackVideoFPS %lf", num);
831                 break;
832               }
833 
834               GST_DEBUG_OBJECT (demux, "TrackVideoFrameRate: %lf", num);
835               if (context->default_duration == 0)
836                 context->default_duration =
837                     gst_gdouble_to_guint64 ((gdouble) GST_SECOND * (1.0 / num));
838               videocontext->default_fps = num;
839               break;
840             }
841 
842               /* width of the size to display the video at */
843             case GST_MATROSKA_ID_VIDEODISPLAYWIDTH:{
844               guint64 num;
845 
846               if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
847                 break;
848 
849               if (num == 0) {
850                 GST_WARNING_OBJECT (demux, "Invalid TrackVideoDisplayWidth 0");
851                 break;
852               }
853 
854               GST_DEBUG_OBJECT (demux,
855                   "TrackVideoDisplayWidth: %" G_GUINT64_FORMAT, num);
856               videocontext->display_width = num;
857               break;
858             }
859 
860               /* height of the size to display the video at */
861             case GST_MATROSKA_ID_VIDEODISPLAYHEIGHT:{
862               guint64 num;
863 
864               if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
865                 break;
866 
867               if (num == 0) {
868                 GST_WARNING_OBJECT (demux, "Invalid TrackVideoDisplayHeight 0");
869                 break;
870               }
871 
872               GST_DEBUG_OBJECT (demux,
873                   "TrackVideoDisplayHeight: %" G_GUINT64_FORMAT, num);
874               videocontext->display_height = num;
875               break;
876             }
877 
878               /* width of the video in the file */
879             case GST_MATROSKA_ID_VIDEOPIXELWIDTH:{
880               guint64 num;
881 
882               if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
883                 break;
884 
885               if (num == 0) {
886                 GST_WARNING_OBJECT (demux, "Invalid TrackVideoPixelWidth 0");
887                 break;
888               }
889 
890               GST_DEBUG_OBJECT (demux,
891                   "TrackVideoPixelWidth: %" G_GUINT64_FORMAT, num);
892               videocontext->pixel_width = num;
893               break;
894             }
895 
896               /* height of the video in the file */
897             case GST_MATROSKA_ID_VIDEOPIXELHEIGHT:{
898               guint64 num;
899 
900               if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
901                 break;
902 
903               if (num == 0) {
904                 GST_WARNING_OBJECT (demux, "Invalid TrackVideoPixelHeight 0");
905                 break;
906               }
907 
908               GST_DEBUG_OBJECT (demux,
909                   "TrackVideoPixelHeight: %" G_GUINT64_FORMAT, num);
910               videocontext->pixel_height = num;
911               break;
912             }
913 
914               /* whether the video is interlaced */
915             case GST_MATROSKA_ID_VIDEOFLAGINTERLACED:{
916               guint64 num;
917 
918               if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
919                 break;
920 
921               if (num == 1)
922                 videocontext->interlace_mode =
923                     GST_MATROSKA_INTERLACE_MODE_INTERLACED;
924               else if (num == 2)
925                 videocontext->interlace_mode =
926                     GST_MATROSKA_INTERLACE_MODE_PROGRESSIVE;
927               else
928                 videocontext->interlace_mode =
929                     GST_MATROSKA_INTERLACE_MODE_UNKNOWN;
930 
931               GST_DEBUG_OBJECT (demux, "video track interlacing mode: %d",
932                   videocontext->interlace_mode);
933               break;
934             }
935 
936               /* aspect ratio behaviour */
937             case GST_MATROSKA_ID_VIDEOASPECTRATIOTYPE:{
938               guint64 num;
939 
940               if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
941                 break;
942 
943               if (num != GST_MATROSKA_ASPECT_RATIO_MODE_FREE &&
944                   num != GST_MATROSKA_ASPECT_RATIO_MODE_KEEP &&
945                   num != GST_MATROSKA_ASPECT_RATIO_MODE_FIXED) {
946                 GST_WARNING_OBJECT (demux,
947                     "Unknown TrackVideoAspectRatioType 0x%x", (guint) num);
948                 break;
949               }
950               GST_DEBUG_OBJECT (demux,
951                   "TrackVideoAspectRatioType: %" G_GUINT64_FORMAT, num);
952               videocontext->asr_mode = num;
953               break;
954             }
955 
956               /* colourspace (only matters for raw video) fourcc */
957             case GST_MATROSKA_ID_VIDEOCOLOURSPACE:{
958               guint8 *data;
959               guint64 datalen;
960 
961               if ((ret =
962                       gst_ebml_read_binary (ebml, &id, &data,
963                           &datalen)) != GST_FLOW_OK)
964                 break;
965 
966               if (datalen != 4) {
967                 g_free (data);
968                 GST_WARNING_OBJECT (demux,
969                     "Invalid TrackVideoColourSpace length %" G_GUINT64_FORMAT,
970                     datalen);
971                 break;
972               }
973 
974               memcpy (&videocontext->fourcc, data, 4);
975               GST_DEBUG_OBJECT (demux,
976                   "TrackVideoColourSpace: %" GST_FOURCC_FORMAT,
977                   GST_FOURCC_ARGS (videocontext->fourcc));
978               g_free (data);
979               break;
980             }
981 
982               /* color info */
983             case GST_MATROSKA_ID_VIDEOCOLOUR:{
984               ret = gst_matroska_demux_parse_colour (demux, ebml, videocontext);
985               break;
986             }
987 
988             case GST_MATROSKA_ID_VIDEOSTEREOMODE:
989             {
990               guint64 num;
991 
992               if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
993                 break;
994 
995               GST_DEBUG_OBJECT (demux, "StereoMode: %" G_GUINT64_FORMAT, num);
996 
997               switch (num) {
998                 case GST_MATROSKA_STEREO_MODE_SBS_RL:
999                   videocontext->multiview_flags =
1000                       GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST;
1001                   /* fall through */
1002                 case GST_MATROSKA_STEREO_MODE_SBS_LR:
1003                   videocontext->multiview_mode =
1004                       GST_VIDEO_MULTIVIEW_MODE_SIDE_BY_SIDE;
1005                   break;
1006                 case GST_MATROSKA_STEREO_MODE_TB_RL:
1007                   videocontext->multiview_flags =
1008                       GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST;
1009                   /* fall through */
1010                 case GST_MATROSKA_STEREO_MODE_TB_LR:
1011                   videocontext->multiview_mode =
1012                       GST_VIDEO_MULTIVIEW_MODE_TOP_BOTTOM;
1013                   break;
1014                 case GST_MATROSKA_STEREO_MODE_CHECKER_RL:
1015                   videocontext->multiview_flags =
1016                       GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST;
1017                   /* fall through */
1018                 case GST_MATROSKA_STEREO_MODE_CHECKER_LR:
1019                   videocontext->multiview_mode =
1020                       GST_VIDEO_MULTIVIEW_MODE_CHECKERBOARD;
1021                   break;
1022                 case GST_MATROSKA_STEREO_MODE_FBF_RL:
1023                   videocontext->multiview_flags =
1024                       GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST;
1025                   /* fall through */
1026                 case GST_MATROSKA_STEREO_MODE_FBF_LR:
1027                   videocontext->multiview_mode =
1028                       GST_VIDEO_MULTIVIEW_MODE_FRAME_BY_FRAME;
1029                   /* FIXME: In frame-by-frame mode, left/right frame buffers are
1030                    * laced within one block, and we'll need to apply FIRST_IN_BUNDLE
1031                    * accordingly. See http://www.matroska.org/technical/specs/index.html#StereoMode */
1032                   GST_FIXME_OBJECT (demux,
1033                       "Frame-by-frame stereoscopic mode not fully implemented");
1034                   break;
1035               }
1036               break;
1037             }
1038 
1039             default:
1040               GST_WARNING_OBJECT (demux,
1041                   "Unknown TrackVideo subelement 0x%x - ignoring", id);
1042               /* fall through */
1043             case GST_MATROSKA_ID_VIDEODISPLAYUNIT:
1044             case GST_MATROSKA_ID_VIDEOPIXELCROPBOTTOM:
1045             case GST_MATROSKA_ID_VIDEOPIXELCROPTOP:
1046             case GST_MATROSKA_ID_VIDEOPIXELCROPLEFT:
1047             case GST_MATROSKA_ID_VIDEOPIXELCROPRIGHT:
1048             case GST_MATROSKA_ID_VIDEOGAMMAVALUE:
1049               ret = gst_ebml_read_skip (ebml);
1050               break;
1051           }
1052         }
1053 
1054         DEBUG_ELEMENT_STOP (demux, ebml, "TrackVideo", ret);
1055         break;
1056       }
1057 
1058         /* tracktype specific stuff for audio */
1059       case GST_MATROSKA_ID_TRACKAUDIO:{
1060         GstMatroskaTrackAudioContext *audiocontext;
1061 
1062         DEBUG_ELEMENT_START (demux, ebml, "TrackAudio");
1063 
1064         if (!gst_matroska_track_init_audio_context (&context)) {
1065           GST_WARNING_OBJECT (demux,
1066               "TrackAudio element in non-audio track - ignoring track");
1067           ret = GST_FLOW_ERROR;
1068           break;
1069         }
1070 
1071         if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
1072           break;
1073 
1074         audiocontext = (GstMatroskaTrackAudioContext *) context;
1075 
1076         while (ret == GST_FLOW_OK &&
1077             gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1078           if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1079             break;
1080 
1081           switch (id) {
1082               /* samplerate */
1083             case GST_MATROSKA_ID_AUDIOSAMPLINGFREQ:{
1084               gdouble num;
1085 
1086               if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
1087                 break;
1088 
1089 
1090               if (num <= 0.0) {
1091                 GST_WARNING_OBJECT (demux,
1092                     "Invalid TrackAudioSamplingFrequency %lf", num);
1093                 break;
1094               }
1095 
1096               GST_DEBUG_OBJECT (demux, "TrackAudioSamplingFrequency: %lf", num);
1097               audiocontext->samplerate = num;
1098               break;
1099             }
1100 
1101               /* bitdepth */
1102             case GST_MATROSKA_ID_AUDIOBITDEPTH:{
1103               guint64 num;
1104 
1105               if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1106                 break;
1107 
1108               if (num == 0) {
1109                 GST_WARNING_OBJECT (demux, "Invalid TrackAudioBitDepth 0");
1110                 break;
1111               }
1112 
1113               GST_DEBUG_OBJECT (demux, "TrackAudioBitDepth: %" G_GUINT64_FORMAT,
1114                   num);
1115               audiocontext->bitdepth = num;
1116               break;
1117             }
1118 
1119               /* channels */
1120             case GST_MATROSKA_ID_AUDIOCHANNELS:{
1121               guint64 num;
1122 
1123               if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1124                 break;
1125 
1126               if (num == 0) {
1127                 GST_WARNING_OBJECT (demux, "Invalid TrackAudioChannels 0");
1128                 break;
1129               }
1130 
1131               GST_DEBUG_OBJECT (demux, "TrackAudioChannels: %" G_GUINT64_FORMAT,
1132                   num);
1133               audiocontext->channels = num;
1134               break;
1135             }
1136 
1137             default:
1138               GST_WARNING_OBJECT (demux,
1139                   "Unknown TrackAudio subelement 0x%x - ignoring", id);
1140               /* fall through */
1141             case GST_MATROSKA_ID_AUDIOCHANNELPOSITIONS:
1142             case GST_MATROSKA_ID_AUDIOOUTPUTSAMPLINGFREQ:
1143               ret = gst_ebml_read_skip (ebml);
1144               break;
1145           }
1146         }
1147 
1148         DEBUG_ELEMENT_STOP (demux, ebml, "TrackAudio", ret);
1149 
1150         break;
1151       }
1152 
1153         /* codec identifier */
1154       case GST_MATROSKA_ID_CODECID:{
1155         gchar *text;
1156 
1157         if ((ret = gst_ebml_read_ascii (ebml, &id, &text)) != GST_FLOW_OK)
1158           break;
1159 
1160         GST_DEBUG_OBJECT (demux, "CodecID: %s", GST_STR_NULL (text));
1161         context->codec_id = text;
1162         break;
1163       }
1164 
1165         /* codec private data */
1166       case GST_MATROSKA_ID_CODECPRIVATE:{
1167         guint8 *data;
1168         guint64 size;
1169 
1170         if ((ret =
1171                 gst_ebml_read_binary (ebml, &id, &data, &size)) != GST_FLOW_OK)
1172           break;
1173 
1174         context->codec_priv = data;
1175         context->codec_priv_size = size;
1176 
1177         GST_DEBUG_OBJECT (demux, "CodecPrivate of size %" G_GUINT64_FORMAT,
1178             size);
1179         break;
1180       }
1181 
1182         /* name of the codec */
1183       case GST_MATROSKA_ID_CODECNAME:{
1184         gchar *text;
1185 
1186         if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1187           break;
1188 
1189         GST_DEBUG_OBJECT (demux, "CodecName: %s", GST_STR_NULL (text));
1190         context->codec_name = text;
1191         break;
1192       }
1193 
1194         /* codec delay */
1195       case GST_MATROSKA_ID_CODECDELAY:{
1196         guint64 num;
1197 
1198         if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1199           break;
1200 
1201         context->codec_delay = num;
1202 
1203         GST_DEBUG_OBJECT (demux, "CodecDelay: %" GST_TIME_FORMAT,
1204             GST_TIME_ARGS (num));
1205         break;
1206       }
1207 
1208         /* codec delay */
1209       case GST_MATROSKA_ID_SEEKPREROLL:{
1210         guint64 num;
1211 
1212         if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1213           break;
1214 
1215         context->seek_preroll = num;
1216 
1217         GST_DEBUG_OBJECT (demux, "SeekPreroll: %" GST_TIME_FORMAT,
1218             GST_TIME_ARGS (num));
1219         break;
1220       }
1221 
1222         /* name of this track */
1223       case GST_MATROSKA_ID_TRACKNAME:{
1224         gchar *text;
1225 
1226         if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1227           break;
1228 
1229         context->name = text;
1230         GST_DEBUG_OBJECT (demux, "TrackName: %s", GST_STR_NULL (text));
1231         break;
1232       }
1233 
1234         /* language (matters for audio/subtitles, mostly) */
1235       case GST_MATROSKA_ID_TRACKLANGUAGE:{
1236         gchar *text;
1237 
1238         if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1239           break;
1240 
1241 
1242         context->language = text;
1243 
1244         /* fre-ca => fre */
1245         if (strlen (context->language) >= 4 && context->language[3] == '-')
1246           context->language[3] = '\0';
1247 
1248         GST_DEBUG_OBJECT (demux, "TrackLanguage: %s",
1249             GST_STR_NULL (context->language));
1250         break;
1251       }
1252 
1253         /* whether this is actually used */
1254       case GST_MATROSKA_ID_TRACKFLAGENABLED:{
1255         guint64 num;
1256 
1257         if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1258           break;
1259 
1260         if (num)
1261           context->flags |= GST_MATROSKA_TRACK_ENABLED;
1262         else
1263           context->flags &= ~GST_MATROSKA_TRACK_ENABLED;
1264 
1265         GST_DEBUG_OBJECT (demux, "TrackEnabled: %d",
1266             (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
1267         break;
1268       }
1269 
1270         /* whether it's the default for this track type */
1271       case GST_MATROSKA_ID_TRACKFLAGDEFAULT:{
1272         guint64 num;
1273 
1274         if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1275           break;
1276 
1277         if (num)
1278           context->flags |= GST_MATROSKA_TRACK_DEFAULT;
1279         else
1280           context->flags &= ~GST_MATROSKA_TRACK_DEFAULT;
1281 
1282         GST_DEBUG_OBJECT (demux, "TrackDefault: %d",
1283             (context->flags & GST_MATROSKA_TRACK_DEFAULT) ? 1 : 0);
1284         break;
1285       }
1286 
1287         /* whether the track must be used during playback */
1288       case GST_MATROSKA_ID_TRACKFLAGFORCED:{
1289         guint64 num;
1290 
1291         if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1292           break;
1293 
1294         if (num)
1295           context->flags |= GST_MATROSKA_TRACK_FORCED;
1296         else
1297           context->flags &= ~GST_MATROSKA_TRACK_FORCED;
1298 
1299         GST_DEBUG_OBJECT (demux, "TrackForced: %d",
1300             (context->flags & GST_MATROSKA_TRACK_FORCED) ? 1 : 0);
1301         break;
1302       }
1303 
1304         /* lacing (like MPEG, where blocks don't end/start on frame
1305          * boundaries) */
1306       case GST_MATROSKA_ID_TRACKFLAGLACING:{
1307         guint64 num;
1308 
1309         if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1310           break;
1311 
1312         if (num)
1313           context->flags |= GST_MATROSKA_TRACK_LACING;
1314         else
1315           context->flags &= ~GST_MATROSKA_TRACK_LACING;
1316 
1317         GST_DEBUG_OBJECT (demux, "TrackLacing: %d",
1318             (context->flags & GST_MATROSKA_TRACK_LACING) ? 1 : 0);
1319         break;
1320       }
1321 
1322         /* default length (in time) of one data block in this track */
1323       case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
1324         guint64 num;
1325 
1326         if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1327           break;
1328 
1329 
1330         if (num == 0) {
1331           GST_WARNING_OBJECT (demux, "Invalid TrackDefaultDuration 0");
1332           break;
1333         }
1334 
1335         GST_DEBUG_OBJECT (demux, "TrackDefaultDuration: %" G_GUINT64_FORMAT,
1336             num);
1337         context->default_duration = num;
1338         break;
1339       }
1340 
1341       case GST_MATROSKA_ID_CONTENTENCODINGS:{
1342         ret = gst_matroska_read_common_read_track_encodings (&demux->common,
1343             ebml, context);
1344         break;
1345       }
1346 
1347       case GST_MATROSKA_ID_TRACKTIMECODESCALE:{
1348         gdouble num;
1349 
1350         if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
1351           break;
1352 
1353         if (num <= 0.0) {
1354           GST_WARNING_OBJECT (demux, "Invalid TrackTimeCodeScale %lf", num);
1355           break;
1356         }
1357 
1358         GST_DEBUG_OBJECT (demux, "TrackTimeCodeScale: %lf", num);
1359         context->timecodescale = num;
1360         break;
1361       }
1362 
1363       default:
1364         GST_WARNING ("Unknown TrackEntry subelement 0x%x - ignoring", id);
1365         /* pass-through */
1366 
1367         /* we ignore these because they're nothing useful (i.e. crap)
1368          * or simply not implemented yet. */
1369       case GST_MATROSKA_ID_TRACKMINCACHE:
1370       case GST_MATROSKA_ID_TRACKMAXCACHE:
1371       case GST_MATROSKA_ID_MAXBLOCKADDITIONID:
1372       case GST_MATROSKA_ID_TRACKATTACHMENTLINK:
1373       case GST_MATROSKA_ID_TRACKOVERLAY:
1374       case GST_MATROSKA_ID_TRACKTRANSLATE:
1375       case GST_MATROSKA_ID_TRACKOFFSET:
1376       case GST_MATROSKA_ID_CODECSETTINGS:
1377       case GST_MATROSKA_ID_CODECINFOURL:
1378       case GST_MATROSKA_ID_CODECDOWNLOADURL:
1379       case GST_MATROSKA_ID_CODECDECODEALL:
1380         ret = gst_ebml_read_skip (ebml);
1381         break;
1382     }
1383   }
1384 
1385   DEBUG_ELEMENT_STOP (demux, ebml, "TrackEntry", ret);
1386 
1387   /* Decode codec private data if necessary */
1388   if (context->encodings && context->encodings->len > 0 && context->codec_priv
1389       && context->codec_priv_size > 0) {
1390     if (!gst_matroska_decode_data (context->encodings,
1391             &context->codec_priv, &context->codec_priv_size,
1392             GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
1393       GST_WARNING_OBJECT (demux, "Decoding codec private data failed");
1394       ret = GST_FLOW_ERROR;
1395     }
1396   }
1397 
1398   if (context->type == 0 || context->codec_id == NULL || (ret != GST_FLOW_OK
1399           && ret != GST_FLOW_EOS)) {
1400     if (ret == GST_FLOW_OK || ret == GST_FLOW_EOS)
1401       GST_WARNING_OBJECT (ebml, "Unknown stream/codec in track entry header");
1402 
1403     gst_matroska_track_free (context);
1404     context = NULL;
1405     *dest_context = NULL;
1406     return ret;
1407   }
1408 
1409   /* check for a cached track taglist  */
1410   cached_taglist =
1411       (GstTagList *) g_hash_table_lookup (demux->common.cached_track_taglists,
1412       GUINT_TO_POINTER (context->uid));
1413   if (cached_taglist)
1414     gst_tag_list_insert (context->tags, cached_taglist, GST_TAG_MERGE_APPEND);
1415 
1416   /* compute caps */
1417   switch (context->type) {
1418     case GST_MATROSKA_TRACK_TYPE_VIDEO:{
1419       GstMatroskaTrackVideoContext *videocontext =
1420           (GstMatroskaTrackVideoContext *) context;
1421 
1422       caps = gst_matroska_demux_video_caps (videocontext,
1423           context->codec_id, context->codec_priv,
1424           context->codec_priv_size, &codec, &riff_fourcc);
1425 
1426       if (codec) {
1427         gst_tag_list_add (context->tags, GST_TAG_MERGE_REPLACE,
1428             GST_TAG_VIDEO_CODEC, codec, NULL);
1429         context->tags_changed = TRUE;
1430         g_free (codec);
1431       }
1432       break;
1433     }
1434 
1435     case GST_MATROSKA_TRACK_TYPE_AUDIO:{
1436       GstMatroskaTrackAudioContext *audiocontext =
1437           (GstMatroskaTrackAudioContext *) context;
1438 
1439       caps = gst_matroska_demux_audio_caps (audiocontext,
1440           context->codec_id, context->codec_priv, context->codec_priv_size,
1441           &codec, &riff_audio_fmt);
1442 
1443       if (codec) {
1444         gst_tag_list_add (context->tags, GST_TAG_MERGE_REPLACE,
1445             GST_TAG_AUDIO_CODEC, codec, NULL);
1446         context->tags_changed = TRUE;
1447         g_free (codec);
1448       }
1449       break;
1450     }
1451 
1452     case GST_MATROSKA_TRACK_TYPE_SUBTITLE:{
1453       GstMatroskaTrackSubtitleContext *subtitlecontext =
1454           (GstMatroskaTrackSubtitleContext *) context;
1455 
1456       caps = gst_matroska_demux_subtitle_caps (subtitlecontext,
1457           context->codec_id, context->codec_priv, context->codec_priv_size);
1458       break;
1459     }
1460 
1461     case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1462     case GST_MATROSKA_TRACK_TYPE_LOGO:
1463     case GST_MATROSKA_TRACK_TYPE_BUTTONS:
1464     case GST_MATROSKA_TRACK_TYPE_CONTROL:
1465     default:
1466       /* we should already have quit by now */
1467       g_assert_not_reached ();
1468   }
1469 
1470   if ((context->language == NULL || *context->language == '\0') &&
1471       (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO ||
1472           context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
1473     GST_LOG ("stream %d: language=eng (assuming default)", context->index);
1474     context->language = g_strdup ("eng");
1475   }
1476 
1477   if (context->language) {
1478     const gchar *lang;
1479 
1480     /* Matroska contains ISO 639-2B codes, we want ISO 639-1 */
1481     lang = gst_tag_get_language_code (context->language);
1482     gst_tag_list_add (context->tags, GST_TAG_MERGE_REPLACE,
1483         GST_TAG_LANGUAGE_CODE, (lang) ? lang : context->language, NULL);
1484 
1485     if (context->name) {
1486       gst_tag_list_add (context->tags, GST_TAG_MERGE_REPLACE,
1487           GST_TAG_TITLE, context->name, NULL);
1488     }
1489     context->tags_changed = TRUE;
1490   }
1491 
1492   if (caps == NULL) {
1493     GST_WARNING_OBJECT (demux, "could not determine caps for stream with "
1494         "codec_id='%s'", context->codec_id);
1495     switch (context->type) {
1496       case GST_MATROSKA_TRACK_TYPE_VIDEO:
1497         caps = gst_caps_new_empty_simple ("video/x-unknown");
1498         break;
1499       case GST_MATROSKA_TRACK_TYPE_AUDIO:
1500         caps = gst_caps_new_empty_simple ("audio/x-unknown");
1501         break;
1502       case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
1503         caps = gst_caps_new_empty_simple ("application/x-subtitle-unknown");
1504         break;
1505       case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1506       default:
1507         caps = gst_caps_new_empty_simple ("application/x-matroska-unknown");
1508         break;
1509     }
1510     gst_caps_set_simple (caps, "codec-id", G_TYPE_STRING, context->codec_id,
1511         NULL);
1512 
1513     /* add any unrecognised riff fourcc / audio format, but after codec-id */
1514     if (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO && riff_audio_fmt != 0)
1515       gst_caps_set_simple (caps, "format", G_TYPE_INT, riff_audio_fmt, NULL);
1516     else if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO && riff_fourcc != 0) {
1517       gchar *fstr = g_strdup_printf ("%" GST_FOURCC_FORMAT,
1518           GST_FOURCC_ARGS (riff_fourcc));
1519       gst_caps_set_simple (caps, "fourcc", G_TYPE_STRING, fstr, NULL);
1520       g_free (fstr);
1521     }
1522   } else if (context->stream_headers != NULL) {
1523     gst_matroska_demux_add_stream_headers_to_caps (demux,
1524         context->stream_headers, caps);
1525   }
1526 
1527   if (context->encodings) {
1528     GstMatroskaTrackEncoding *enc;
1529     guint i;
1530 
1531     for (i = 0; i < context->encodings->len; i++) {
1532       enc = &g_array_index (context->encodings, GstMatroskaTrackEncoding, i);
1533       if (enc->type == GST_MATROSKA_ENCODING_ENCRYPTION /* encryption */ ) {
1534         GstStructure *s = gst_caps_get_structure (caps, 0);
1535         if (!gst_structure_has_name (s, "application/x-webm-enc")) {
1536           gst_structure_set (s, "original-media-type", G_TYPE_STRING,
1537               gst_structure_get_name (s), NULL);
1538           gst_structure_set (s, "encryption-algorithm", G_TYPE_STRING,
1539               gst_matroska_track_encryption_algorithm_name (enc->enc_algo),
1540               NULL);
1541           gst_structure_set (s, "encoding-scope", G_TYPE_STRING,
1542               gst_matroska_track_encoding_scope_name (enc->scope), NULL);
1543           gst_structure_set (s, "cipher-mode", G_TYPE_STRING,
1544               gst_matroska_track_encryption_cipher_mode_name
1545               (enc->enc_cipher_mode), NULL);
1546           gst_structure_set_name (s, "application/x-webm-enc");
1547         }
1548       }
1549     }
1550   }
1551 
1552   context->caps = caps;
1553 
1554   /* tadaah! */
1555   *dest_context = context;
1556   return ret;
1557 }
1558 
1559 static void
gst_matroska_demux_add_stream(GstMatroskaDemux * demux,GstMatroskaTrackContext * context)1560 gst_matroska_demux_add_stream (GstMatroskaDemux * demux,
1561     GstMatroskaTrackContext * context)
1562 {
1563   GstElementClass *klass = GST_ELEMENT_GET_CLASS (demux);
1564   gchar *padname = NULL;
1565   GstPadTemplate *templ = NULL;
1566   GstStreamFlags stream_flags;
1567 
1568   GstEvent *stream_start;
1569 
1570   gchar *stream_id;
1571 
1572   g_ptr_array_add (demux->common.src, context);
1573   context->index = demux->common.num_streams++;
1574   g_assert (demux->common.src->len == demux->common.num_streams);
1575   g_ptr_array_index (demux->common.src, demux->common.num_streams - 1) =
1576       context;
1577 
1578   /* now create the GStreamer connectivity */
1579   switch (context->type) {
1580     case GST_MATROSKA_TRACK_TYPE_VIDEO:
1581       padname = g_strdup_printf ("video_%u", demux->num_v_streams++);
1582       templ = gst_element_class_get_pad_template (klass, "video_%u");
1583 
1584       if (!context->intra_only)
1585         demux->have_nonintraonly_v_streams = TRUE;
1586       break;
1587 
1588     case GST_MATROSKA_TRACK_TYPE_AUDIO:
1589       padname = g_strdup_printf ("audio_%u", demux->num_a_streams++);
1590       templ = gst_element_class_get_pad_template (klass, "audio_%u");
1591       break;
1592 
1593     case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
1594       padname = g_strdup_printf ("subtitle_%u", demux->num_t_streams++);
1595       templ = gst_element_class_get_pad_template (klass, "subtitle_%u");
1596       break;
1597 
1598     default:
1599       /* we should already have quit by now */
1600       g_assert_not_reached ();
1601   }
1602 
1603   /* the pad in here */
1604   context->pad = gst_pad_new_from_template (templ, padname);
1605 
1606   gst_pad_set_event_function (context->pad,
1607       GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_event));
1608   gst_pad_set_query_function (context->pad,
1609       GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_query));
1610 
1611   GST_INFO_OBJECT (demux, "Adding pad '%s' with caps %" GST_PTR_FORMAT,
1612       padname, context->caps);
1613 
1614   gst_pad_set_element_private (context->pad, context);
1615 
1616   gst_pad_use_fixed_caps (context->pad);
1617   gst_pad_set_active (context->pad, TRUE);
1618 
1619   stream_id =
1620       gst_pad_create_stream_id_printf (context->pad, GST_ELEMENT_CAST (demux),
1621       "%03" G_GUINT64_FORMAT ":%03" G_GUINT64_FORMAT,
1622       context->num, context->uid);
1623   stream_start =
1624       gst_pad_get_sticky_event (demux->common.sinkpad, GST_EVENT_STREAM_START,
1625       0);
1626   if (stream_start) {
1627     if (gst_event_parse_group_id (stream_start, &demux->group_id))
1628       demux->have_group_id = TRUE;
1629     else
1630       demux->have_group_id = FALSE;
1631     gst_event_unref (stream_start);
1632   } else if (!demux->have_group_id) {
1633     demux->have_group_id = TRUE;
1634     demux->group_id = gst_util_group_id_next ();
1635   }
1636 
1637   stream_start = gst_event_new_stream_start (stream_id);
1638   g_free (stream_id);
1639   if (demux->have_group_id)
1640     gst_event_set_group_id (stream_start, demux->group_id);
1641   stream_flags = GST_STREAM_FLAG_NONE;
1642   if (context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)
1643     stream_flags |= GST_STREAM_FLAG_SPARSE;
1644   if (context->flags & GST_MATROSKA_TRACK_DEFAULT)
1645     stream_flags |= GST_STREAM_FLAG_SELECT;
1646   else if (!(context->flags & GST_MATROSKA_TRACK_ENABLED))
1647     stream_flags |= GST_STREAM_FLAG_UNSELECT;
1648 
1649   gst_event_set_stream_flags (stream_start, stream_flags);
1650   gst_pad_push_event (context->pad, stream_start);
1651   gst_pad_set_caps (context->pad, context->caps);
1652 
1653 
1654   if (demux->common.global_tags) {
1655     GstEvent *tag_event;
1656 
1657     gst_tag_list_add (demux->common.global_tags, GST_TAG_MERGE_REPLACE,
1658         GST_TAG_CONTAINER_FORMAT, "Matroska", NULL);
1659     GST_DEBUG_OBJECT (context->pad, "Sending global_tags %p: %" GST_PTR_FORMAT,
1660         demux->common.global_tags, demux->common.global_tags);
1661 
1662     tag_event =
1663         gst_event_new_tag (gst_tag_list_copy (demux->common.global_tags));
1664 
1665     gst_pad_push_event (context->pad, tag_event);
1666   }
1667 
1668   if (G_UNLIKELY (context->tags_changed)) {
1669     GST_DEBUG_OBJECT (context->pad, "Sending tags %p: %"
1670         GST_PTR_FORMAT, context->tags, context->tags);
1671     gst_pad_push_event (context->pad,
1672         gst_event_new_tag (gst_tag_list_copy (context->tags)));
1673     context->tags_changed = FALSE;
1674   }
1675 
1676   gst_element_add_pad (GST_ELEMENT (demux), context->pad);
1677   gst_flow_combiner_add_pad (demux->flowcombiner, context->pad);
1678 
1679   g_free (padname);
1680 }
1681 
1682 static gboolean
gst_matroska_demux_query(GstMatroskaDemux * demux,GstPad * pad,GstQuery * query)1683 gst_matroska_demux_query (GstMatroskaDemux * demux, GstPad * pad,
1684     GstQuery * query)
1685 {
1686   gboolean res = FALSE;
1687   GstMatroskaTrackContext *context = NULL;
1688 
1689   if (pad) {
1690     context = gst_pad_get_element_private (pad);
1691   }
1692 
1693   switch (GST_QUERY_TYPE (query)) {
1694     case GST_QUERY_POSITION:
1695     {
1696       GstFormat format;
1697 
1698       gst_query_parse_position (query, &format, NULL);
1699 
1700       res = TRUE;
1701       if (format == GST_FORMAT_TIME) {
1702         GST_OBJECT_LOCK (demux);
1703         if (context)
1704           gst_query_set_position (query, GST_FORMAT_TIME,
1705               MAX (context->pos, demux->stream_start_time) -
1706               demux->stream_start_time);
1707         else
1708           gst_query_set_position (query, GST_FORMAT_TIME,
1709               MAX (demux->common.segment.position, demux->stream_start_time) -
1710               demux->stream_start_time);
1711         GST_OBJECT_UNLOCK (demux);
1712       } else if (format == GST_FORMAT_DEFAULT && context
1713           && context->default_duration) {
1714         GST_OBJECT_LOCK (demux);
1715         gst_query_set_position (query, GST_FORMAT_DEFAULT,
1716             context->pos / context->default_duration);
1717         GST_OBJECT_UNLOCK (demux);
1718       } else {
1719         GST_DEBUG_OBJECT (demux,
1720             "only position query in TIME and DEFAULT format is supported");
1721         res = FALSE;
1722       }
1723 
1724       break;
1725     }
1726     case GST_QUERY_DURATION:
1727     {
1728       GstFormat format;
1729 
1730       gst_query_parse_duration (query, &format, NULL);
1731 
1732       res = TRUE;
1733       if (format == GST_FORMAT_TIME) {
1734         GST_OBJECT_LOCK (demux);
1735         gst_query_set_duration (query, GST_FORMAT_TIME,
1736             demux->common.segment.duration);
1737         GST_OBJECT_UNLOCK (demux);
1738       } else if (format == GST_FORMAT_DEFAULT && context
1739           && context->default_duration) {
1740         GST_OBJECT_LOCK (demux);
1741         gst_query_set_duration (query, GST_FORMAT_DEFAULT,
1742             demux->common.segment.duration / context->default_duration);
1743         GST_OBJECT_UNLOCK (demux);
1744       } else {
1745         GST_DEBUG_OBJECT (demux,
1746             "only duration query in TIME and DEFAULT format is supported");
1747         res = FALSE;
1748       }
1749       break;
1750     }
1751 
1752     case GST_QUERY_SEEKING:
1753     {
1754       GstFormat fmt;
1755 
1756       gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
1757       GST_OBJECT_LOCK (demux);
1758       if (fmt == GST_FORMAT_TIME) {
1759         gboolean seekable;
1760 
1761         if (demux->streaming) {
1762           /* assuming we'll be able to get an index ... */
1763           seekable = demux->seekable;
1764         } else {
1765           seekable = TRUE;
1766         }
1767 
1768         gst_query_set_seeking (query, GST_FORMAT_TIME, seekable,
1769             0, demux->common.segment.duration);
1770         res = TRUE;
1771       }
1772       GST_OBJECT_UNLOCK (demux);
1773       break;
1774     }
1775     case GST_QUERY_SEGMENT:
1776     {
1777       GstFormat format;
1778       gint64 start, stop;
1779 
1780       format = demux->common.segment.format;
1781 
1782       start =
1783           gst_segment_to_stream_time (&demux->common.segment, format,
1784           demux->common.segment.start);
1785       if ((stop = demux->common.segment.stop) == -1)
1786         stop = demux->common.segment.duration;
1787       else
1788         stop =
1789             gst_segment_to_stream_time (&demux->common.segment, format, stop);
1790 
1791       gst_query_set_segment (query, demux->common.segment.rate, format, start,
1792           stop);
1793       res = TRUE;
1794       break;
1795     }
1796     default:
1797       if (pad)
1798         res = gst_pad_query_default (pad, (GstObject *) demux, query);
1799       else
1800         res =
1801             GST_ELEMENT_CLASS (parent_class)->query (GST_ELEMENT_CAST (demux),
1802             query);
1803       break;
1804   }
1805 
1806   return res;
1807 }
1808 
1809 static gboolean
gst_matroska_demux_element_query(GstElement * element,GstQuery * query)1810 gst_matroska_demux_element_query (GstElement * element, GstQuery * query)
1811 {
1812   return gst_matroska_demux_query (GST_MATROSKA_DEMUX (element), NULL, query);
1813 }
1814 
1815 static gboolean
gst_matroska_demux_handle_src_query(GstPad * pad,GstObject * parent,GstQuery * query)1816 gst_matroska_demux_handle_src_query (GstPad * pad, GstObject * parent,
1817     GstQuery * query)
1818 {
1819   GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
1820 
1821   return gst_matroska_demux_query (demux, pad, query);
1822 }
1823 
1824 /* returns FALSE if there are no pads to deliver event to,
1825  * otherwise TRUE (whatever the outcome of event sending),
1826  * takes ownership of the passed event! */
1827 static gboolean
gst_matroska_demux_send_event(GstMatroskaDemux * demux,GstEvent * event)1828 gst_matroska_demux_send_event (GstMatroskaDemux * demux, GstEvent * event)
1829 {
1830   gboolean ret = FALSE;
1831   gint i;
1832 
1833   g_return_val_if_fail (event != NULL, FALSE);
1834 
1835   GST_DEBUG_OBJECT (demux, "Sending event of type %s to all source pads",
1836       GST_EVENT_TYPE_NAME (event));
1837 
1838   g_assert (demux->common.src->len == demux->common.num_streams);
1839   for (i = 0; i < demux->common.src->len; i++) {
1840     GstMatroskaTrackContext *stream;
1841 
1842     stream = g_ptr_array_index (demux->common.src, i);
1843     gst_event_ref (event);
1844     gst_pad_push_event (stream->pad, event);
1845     ret = TRUE;
1846   }
1847 
1848   gst_event_unref (event);
1849   return ret;
1850 }
1851 
1852 static void
gst_matroska_demux_send_tags(GstMatroskaDemux * demux)1853 gst_matroska_demux_send_tags (GstMatroskaDemux * demux)
1854 {
1855   gint i;
1856 
1857   if (G_UNLIKELY (demux->common.global_tags_changed)) {
1858     GstEvent *tag_event;
1859     gst_tag_list_add (demux->common.global_tags, GST_TAG_MERGE_REPLACE,
1860         GST_TAG_CONTAINER_FORMAT, "Matroska", NULL);
1861     GST_DEBUG_OBJECT (demux, "Sending global_tags %p : %" GST_PTR_FORMAT,
1862         demux->common.global_tags, demux->common.global_tags);
1863 
1864     tag_event =
1865         gst_event_new_tag (gst_tag_list_copy (demux->common.global_tags));
1866 
1867     for (i = 0; i < demux->common.src->len; i++) {
1868       GstMatroskaTrackContext *stream;
1869 
1870       stream = g_ptr_array_index (demux->common.src, i);
1871       gst_pad_push_event (stream->pad, gst_event_ref (tag_event));
1872     }
1873 
1874     gst_event_unref (tag_event);
1875     demux->common.global_tags_changed = FALSE;
1876   }
1877 
1878   g_assert (demux->common.src->len == demux->common.num_streams);
1879   for (i = 0; i < demux->common.src->len; i++) {
1880     GstMatroskaTrackContext *stream;
1881 
1882     stream = g_ptr_array_index (demux->common.src, i);
1883 
1884     if (G_UNLIKELY (stream->tags_changed)) {
1885       GST_DEBUG_OBJECT (demux, "Sending tags %p for pad %s:%s : %"
1886           GST_PTR_FORMAT, stream->tags,
1887           GST_DEBUG_PAD_NAME (stream->pad), stream->tags);
1888       gst_pad_push_event (stream->pad,
1889           gst_event_new_tag (gst_tag_list_copy (stream->tags)));
1890       stream->tags_changed = FALSE;
1891     }
1892   }
1893 }
1894 
1895 static gboolean
gst_matroska_demux_element_send_event(GstElement * element,GstEvent * event)1896 gst_matroska_demux_element_send_event (GstElement * element, GstEvent * event)
1897 {
1898   GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
1899   gboolean res;
1900 
1901   g_return_val_if_fail (event != NULL, FALSE);
1902 
1903   if (GST_EVENT_TYPE (event) == GST_EVENT_SEEK) {
1904     /* no seeking until we are (safely) ready */
1905     if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
1906       GST_DEBUG_OBJECT (demux,
1907           "not ready for seeking yet, deferring seek: %" GST_PTR_FORMAT, event);
1908       if (demux->deferred_seek_event)
1909         gst_event_unref (demux->deferred_seek_event);
1910       demux->deferred_seek_event = event;
1911       demux->deferred_seek_pad = NULL;
1912       return TRUE;
1913     }
1914     res = gst_matroska_demux_handle_seek_event (demux, NULL, event);
1915   } else {
1916     GST_WARNING_OBJECT (demux, "Unhandled event of type %s",
1917         GST_EVENT_TYPE_NAME (event));
1918     res = FALSE;
1919   }
1920   gst_event_unref (event);
1921   return res;
1922 }
1923 
1924 static gboolean
gst_matroska_demux_move_to_entry(GstMatroskaDemux * demux,GstMatroskaIndex * entry,gboolean reset,gboolean update)1925 gst_matroska_demux_move_to_entry (GstMatroskaDemux * demux,
1926     GstMatroskaIndex * entry, gboolean reset, gboolean update)
1927 {
1928   gint i;
1929 
1930   GST_OBJECT_LOCK (demux);
1931 
1932   if (update) {
1933     /* seek (relative to matroska segment) */
1934     /* position might be invalid; will error when streaming resumes ... */
1935     demux->common.offset = entry->pos + demux->common.ebml_segment_start;
1936     demux->next_cluster_offset = 0;
1937 
1938     GST_DEBUG_OBJECT (demux,
1939         "Seeked to offset %" G_GUINT64_FORMAT ", block %d, " "time %"
1940         GST_TIME_FORMAT, entry->pos + demux->common.ebml_segment_start,
1941         entry->block, GST_TIME_ARGS (entry->time));
1942 
1943     /* update the time */
1944     gst_matroska_read_common_reset_streams (&demux->common, entry->time, TRUE);
1945     gst_flow_combiner_reset (demux->flowcombiner);
1946     demux->common.segment.position = entry->time;
1947     demux->seek_block = entry->block;
1948     demux->seek_first = TRUE;
1949     demux->last_stop_end = GST_CLOCK_TIME_NONE;
1950   }
1951 
1952   for (i = 0; i < demux->common.src->len; i++) {
1953     GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
1954 
1955     if (reset) {
1956       stream->to_offset = G_MAXINT64;
1957     } else {
1958       if (stream->from_offset != -1)
1959         stream->to_offset = stream->from_offset;
1960     }
1961     stream->from_offset = -1;
1962     stream->from_time = GST_CLOCK_TIME_NONE;
1963   }
1964 
1965   GST_OBJECT_UNLOCK (demux);
1966 
1967   return TRUE;
1968 }
1969 
1970 static gint
gst_matroska_cluster_compare(gint64 * i1,gint64 * i2)1971 gst_matroska_cluster_compare (gint64 * i1, gint64 * i2)
1972 {
1973   if (*i1 < *i2)
1974     return -1;
1975   else if (*i1 > *i2)
1976     return 1;
1977   else
1978     return 0;
1979 }
1980 
1981 /* searches for a cluster start from @pos,
1982  * return GST_FLOW_OK and cluster position in @pos if found */
1983 static GstFlowReturn
gst_matroska_demux_search_cluster(GstMatroskaDemux * demux,gint64 * pos,gboolean forward)1984 gst_matroska_demux_search_cluster (GstMatroskaDemux * demux, gint64 * pos,
1985     gboolean forward)
1986 {
1987   gint64 newpos = *pos;
1988   gint64 orig_offset;
1989   GstFlowReturn ret = GST_FLOW_OK;
1990   const guint chunk = 128 * 1024;
1991   GstBuffer *buf = NULL;
1992   GstMapInfo map;
1993   gpointer data = NULL;
1994   gsize size;
1995   guint64 length;
1996   guint32 id;
1997   guint needed;
1998   gint64 oldpos, oldlength;
1999 
2000   orig_offset = demux->common.offset;
2001 
2002   GST_LOG_OBJECT (demux, "searching cluster %s offset %" G_GINT64_FORMAT,
2003       forward ? "following" : "preceding", *pos);
2004 
2005   if (demux->clusters) {
2006     gint64 *cpos;
2007 
2008     cpos = gst_util_array_binary_search (demux->clusters->data,
2009         demux->clusters->len, sizeof (gint64),
2010         (GCompareDataFunc) gst_matroska_cluster_compare,
2011         forward ? GST_SEARCH_MODE_AFTER : GST_SEARCH_MODE_BEFORE, pos, NULL);
2012     /* sanity check */
2013     if (cpos) {
2014       GST_DEBUG_OBJECT (demux,
2015           "cluster reported at offset %" G_GINT64_FORMAT, *cpos);
2016       demux->common.offset = *cpos;
2017       ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
2018           GST_ELEMENT_CAST (demux), &id, &length, &needed);
2019       if (ret == GST_FLOW_OK && id == GST_MATROSKA_ID_CLUSTER) {
2020         newpos = *cpos;
2021         goto exit;
2022       }
2023     }
2024   }
2025 
2026   /* read in at newpos and scan for ebml cluster id */
2027   oldpos = oldlength = -1;
2028   while (1) {
2029     GstByteReader reader;
2030     gint cluster_pos;
2031     guint toread = chunk;
2032 
2033     if (!forward) {
2034       /* never read beyond the requested target */
2035       if (G_UNLIKELY (newpos < chunk)) {
2036         toread = newpos;
2037         newpos = 0;
2038       } else {
2039         newpos -= chunk;
2040       }
2041     }
2042     if (buf != NULL) {
2043       gst_buffer_unmap (buf, &map);
2044       gst_buffer_unref (buf);
2045       buf = NULL;
2046     }
2047     ret = gst_pad_pull_range (demux->common.sinkpad, newpos, toread, &buf);
2048     if (ret != GST_FLOW_OK)
2049       break;
2050     GST_DEBUG_OBJECT (demux,
2051         "read buffer size %" G_GSIZE_FORMAT " at offset %" G_GINT64_FORMAT,
2052         gst_buffer_get_size (buf), newpos);
2053     gst_buffer_map (buf, &map, GST_MAP_READ);
2054     data = map.data;
2055     size = map.size;
2056     if (oldpos == newpos && oldlength == map.size) {
2057       GST_ERROR_OBJECT (demux, "Stuck at same position");
2058       ret = GST_FLOW_ERROR;
2059       goto exit;
2060     } else {
2061       oldpos = newpos;
2062       oldlength = map.size;
2063     }
2064 
2065     gst_byte_reader_init (&reader, data, size);
2066     cluster_pos = -1;
2067     while (1) {
2068       gint found = gst_byte_reader_masked_scan_uint32 (&reader, 0xffffffff,
2069           GST_MATROSKA_ID_CLUSTER, 0, gst_byte_reader_get_remaining (&reader));
2070       if (forward) {
2071         cluster_pos = found;
2072         break;
2073       }
2074       /* need last occurrence when searching backwards */
2075       if (found >= 0) {
2076         cluster_pos = gst_byte_reader_get_pos (&reader) + found;
2077         gst_byte_reader_skip (&reader, found + 4);
2078       } else {
2079         break;
2080       }
2081     }
2082 
2083     if (cluster_pos >= 0) {
2084       newpos += cluster_pos;
2085       GST_DEBUG_OBJECT (demux,
2086           "found cluster ebml id at offset %" G_GINT64_FORMAT, newpos);
2087       /* extra checks whether we really sync'ed to a cluster:
2088        * - either it is the first and only cluster
2089        * - either there is a cluster after this one
2090        * - either cluster length is undefined
2091        */
2092       /* ok if first cluster (there may not a subsequent one) */
2093       if (newpos == demux->first_cluster_offset) {
2094         GST_DEBUG_OBJECT (demux, "cluster is first cluster -> OK");
2095         break;
2096       }
2097       demux->common.offset = newpos;
2098       ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
2099           GST_ELEMENT_CAST (demux), &id, &length, &needed);
2100       if (ret != GST_FLOW_OK) {
2101         GST_DEBUG_OBJECT (demux, "need more data -> continue");
2102         goto next;
2103       }
2104       g_assert (id == GST_MATROSKA_ID_CLUSTER);
2105       GST_DEBUG_OBJECT (demux, "cluster size %" G_GUINT64_FORMAT ", prefix %d",
2106           length, needed);
2107       /* ok if undefined length or first cluster */
2108       if (length == GST_EBML_SIZE_UNKNOWN || length == G_MAXUINT64) {
2109         GST_DEBUG_OBJECT (demux, "cluster has undefined length -> OK");
2110         break;
2111       }
2112       /* skip cluster */
2113       demux->common.offset += length + needed;
2114       ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
2115           GST_ELEMENT_CAST (demux), &id, &length, &needed);
2116       if (ret != GST_FLOW_OK)
2117         goto next;
2118       GST_DEBUG_OBJECT (demux, "next element is %scluster",
2119           id == GST_MATROSKA_ID_CLUSTER ? "" : "not ");
2120       if (id == GST_MATROSKA_ID_CLUSTER)
2121         break;
2122     next:
2123       if (forward)
2124         newpos += 1;
2125     } else {
2126       /* partial cluster id may have been in tail of buffer */
2127       newpos +=
2128           forward ? MAX (gst_byte_reader_get_remaining (&reader), 4) - 3 : 3;
2129     }
2130   }
2131 
2132   if (buf) {
2133     gst_buffer_unmap (buf, &map);
2134     gst_buffer_unref (buf);
2135     buf = NULL;
2136   }
2137 
2138 exit:
2139   demux->common.offset = orig_offset;
2140   *pos = newpos;
2141   return ret;
2142 }
2143 
2144 /* Three states to express: starts with I-frame, starts with delta, don't know */
2145 typedef enum
2146 {
2147   CLUSTER_STATUS_NONE = 0,
2148   CLUSTER_STATUS_STARTS_WITH_KEYFRAME,
2149   CLUSTER_STATUS_STARTS_WITH_DELTAUNIT,
2150 } ClusterStatus;
2151 
2152 typedef struct
2153 {
2154   guint64 offset;
2155   guint64 size;
2156   guint64 prev_size;
2157   GstClockTime time;
2158   ClusterStatus status;
2159 } ClusterInfo;
2160 
2161 static const gchar *
cluster_status_get_nick(ClusterStatus status)2162 cluster_status_get_nick (ClusterStatus status)
2163 {
2164   switch (status) {
2165     case CLUSTER_STATUS_NONE:
2166       return "none";
2167     case CLUSTER_STATUS_STARTS_WITH_KEYFRAME:
2168       return "key";
2169     case CLUSTER_STATUS_STARTS_WITH_DELTAUNIT:
2170       return "delta";
2171   }
2172   return "???";
2173 }
2174 
2175 /* Skip ebml-coded number:
2176  *  1xxx.. = 1 byte
2177  *  01xx.. = 2 bytes
2178  *  001x.. = 3 bytes, etc.
2179  */
2180 static gboolean
bit_reader_skip_ebml_num(GstBitReader * br)2181 bit_reader_skip_ebml_num (GstBitReader * br)
2182 {
2183   guint8 i, v = 0;
2184 
2185   if (!gst_bit_reader_peek_bits_uint8 (br, &v, 8))
2186     return FALSE;
2187 
2188   for (i = 0; i < 8; i++) {
2189     if ((v & (0x80 >> i)) != 0)
2190       break;
2191   }
2192   return gst_bit_reader_skip (br, (i + 1) * 8);
2193 }
2194 
2195 /* Don't probe more than that many bytes into the cluster for keyframe info
2196  * (random value, mostly for sanity checking) */
2197 #define MAX_CLUSTER_INFO_PROBE_LENGTH 256
2198 
2199 static gboolean
gst_matroska_demux_peek_cluster_info(GstMatroskaDemux * demux,ClusterInfo * cluster,guint64 offset)2200 gst_matroska_demux_peek_cluster_info (GstMatroskaDemux * demux,
2201     ClusterInfo * cluster, guint64 offset)
2202 {
2203   demux->common.offset = offset;
2204   demux->cluster_time = GST_CLOCK_TIME_NONE;
2205 
2206   cluster->offset = offset;
2207   cluster->size = 0;
2208   cluster->prev_size = 0;
2209   cluster->time = GST_CLOCK_TIME_NONE;
2210   cluster->status = CLUSTER_STATUS_NONE;
2211 
2212   /* parse first few elements in cluster */
2213   do {
2214     GstFlowReturn flow;
2215     guint64 length;
2216     guint32 id;
2217     guint needed;
2218 
2219     flow = gst_matroska_read_common_peek_id_length_pull (&demux->common,
2220         GST_ELEMENT_CAST (demux), &id, &length, &needed);
2221 
2222     if (flow != GST_FLOW_OK)
2223       break;
2224 
2225     GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
2226         "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
2227         length, needed);
2228 
2229     /* Reached start of next cluster without finding data, stop processing */
2230     if (id == GST_MATROSKA_ID_CLUSTER && cluster->offset != offset)
2231       break;
2232 
2233     /* Not going to parse into these for now, stop processing */
2234     if (id == GST_MATROSKA_ID_ENCRYPTEDBLOCK
2235         || id == GST_MATROSKA_ID_BLOCKGROUP || id == GST_MATROSKA_ID_BLOCK)
2236       break;
2237 
2238     /* SimpleBlock: peek at headers to check if it's a keyframe */
2239     if (id == GST_MATROSKA_ID_SIMPLEBLOCK) {
2240       GstBitReader br;
2241       guint8 *d, hdr_len, v = 0;
2242 
2243       GST_DEBUG_OBJECT (demux, "SimpleBlock found");
2244 
2245       /* SimpleBlock header is max. 21 bytes */
2246       hdr_len = MIN (21, length);
2247 
2248       flow = gst_matroska_read_common_peek_bytes (&demux->common,
2249           demux->common.offset, hdr_len, NULL, &d);
2250 
2251       if (flow != GST_FLOW_OK)
2252         break;
2253 
2254       gst_bit_reader_init (&br, d, hdr_len);
2255 
2256       /* skip prefix: ebml id (SimpleBlock) + element length */
2257       if (!gst_bit_reader_skip (&br, 8 * needed))
2258         break;
2259 
2260       /* skip track number (ebml coded) */
2261       if (!bit_reader_skip_ebml_num (&br))
2262         break;
2263 
2264       /* skip Timecode */
2265       if (!gst_bit_reader_skip (&br, 16))
2266         break;
2267 
2268       /* read flags */
2269       if (!gst_bit_reader_get_bits_uint8 (&br, &v, 8))
2270         break;
2271 
2272       if ((v & 0x80) != 0)
2273         cluster->status = CLUSTER_STATUS_STARTS_WITH_KEYFRAME;
2274       else
2275         cluster->status = CLUSTER_STATUS_STARTS_WITH_DELTAUNIT;
2276 
2277       break;
2278     }
2279 
2280     flow = gst_matroska_demux_parse_id (demux, id, length, needed);
2281 
2282     if (flow != GST_FLOW_OK)
2283       break;
2284 
2285     switch (id) {
2286       case GST_MATROSKA_ID_CLUSTER:
2287         if (length == G_MAXUINT64)
2288           cluster->size = 0;
2289         else
2290           cluster->size = length + needed;
2291         break;
2292       case GST_MATROSKA_ID_PREVSIZE:
2293         cluster->prev_size = demux->cluster_prevsize;
2294         break;
2295       case GST_MATROSKA_ID_CLUSTERTIMECODE:
2296         cluster->time = demux->cluster_time * demux->common.time_scale;
2297         break;
2298       case GST_MATROSKA_ID_SILENTTRACKS:
2299         /* ignore and continue */
2300         break;
2301       default:
2302         GST_WARNING_OBJECT (demux, "Unknown ebml id 0x%08x (possibly garbage), "
2303             "bailing out", id);
2304         goto out;
2305     }
2306   } while (demux->common.offset - offset < MAX_CLUSTER_INFO_PROBE_LENGTH);
2307 
2308 out:
2309 
2310   GST_INFO_OBJECT (demux, "Cluster @ %" G_GUINT64_FORMAT ": "
2311       "time %" GST_TIME_FORMAT ", size %" G_GUINT64_FORMAT ", "
2312       "prev_size %" G_GUINT64_FORMAT ", %s", cluster->offset,
2313       GST_TIME_ARGS (cluster->time), cluster->size, cluster->prev_size,
2314       cluster_status_get_nick (cluster->status));
2315 
2316   /* return success as long as we could extract the minimum useful information */
2317   return cluster->time != GST_CLOCK_TIME_NONE;
2318 }
2319 
2320 /* returns TRUE if the cluster offset was updated */
2321 static gboolean
gst_matroska_demux_scan_back_for_keyframe_cluster(GstMatroskaDemux * demux,gint64 * cluster_offset,GstClockTime * cluster_time)2322 gst_matroska_demux_scan_back_for_keyframe_cluster (GstMatroskaDemux * demux,
2323     gint64 * cluster_offset, GstClockTime * cluster_time)
2324 {
2325   GstClockTime stream_start_time = demux->stream_start_time;
2326   guint64 first_cluster_offset = demux->first_cluster_offset;
2327   gint64 off = *cluster_offset;
2328   ClusterInfo cluster = { 0, };
2329 
2330   GST_INFO_OBJECT (demux, "Checking if cluster starts with keyframe");
2331   while (off > first_cluster_offset) {
2332     if (!gst_matroska_demux_peek_cluster_info (demux, &cluster, off)) {
2333       GST_LOG_OBJECT (demux,
2334           "Couldn't get info on cluster @ %" G_GUINT64_FORMAT, off);
2335       break;
2336     }
2337 
2338     /* Keyframe? Then we're done */
2339     if (cluster.status == CLUSTER_STATUS_STARTS_WITH_KEYFRAME) {
2340       GST_LOG_OBJECT (demux,
2341           "Found keyframe at start of cluster @ %" G_GUINT64_FORMAT, off);
2342       break;
2343     }
2344 
2345     /* We only scan back if we *know* we landed on a cluster that
2346      * starts with a delta frame. */
2347     if (cluster.status != CLUSTER_STATUS_STARTS_WITH_DELTAUNIT) {
2348       GST_LOG_OBJECT (demux,
2349           "No delta frame at start of cluster @ %" G_GUINT64_FORMAT, off);
2350       break;
2351     }
2352 
2353     GST_DEBUG_OBJECT (demux, "Cluster starts with delta frame, backtracking");
2354 
2355     /* Don't scan back more than this much in time from the cluster we
2356      * originally landed on. This is mostly a sanity check in case a file
2357      * always has keyframes in the middle of clusters and never at the
2358      * beginning. Without this we would always scan back to the beginning
2359      * of the file in that case. */
2360     if (cluster.time != GST_CLOCK_TIME_NONE) {
2361       GstClockTimeDiff distance = GST_CLOCK_DIFF (cluster.time, *cluster_time);
2362 
2363       if (distance < 0 || distance > demux->max_backtrack_distance * GST_SECOND) {
2364         GST_DEBUG_OBJECT (demux, "Haven't found cluster with keyframe within "
2365             "%u secs of original seek target cluster, stopping",
2366             demux->max_backtrack_distance);
2367         break;
2368       }
2369     }
2370 
2371     /* If we have cluster prev_size we can skip back efficiently. If not,
2372      * we'll just do a brute force search for a cluster identifier */
2373     if (cluster.prev_size > 0 && off >= cluster.prev_size) {
2374       off -= cluster.prev_size;
2375     } else {
2376       GstFlowReturn flow;
2377 
2378       GST_LOG_OBJECT (demux, "Cluster has no or invalid prev size, searching "
2379           "for previous cluster instead then");
2380 
2381       flow = gst_matroska_demux_search_cluster (demux, &off, FALSE);
2382       if (flow != GST_FLOW_OK) {
2383         GST_DEBUG_OBJECT (demux, "cluster search yielded flow %s, stopping",
2384             gst_flow_get_name (flow));
2385         break;
2386       }
2387     }
2388 
2389     if (off <= first_cluster_offset) {
2390       GST_LOG_OBJECT (demux, "Reached first cluster, stopping");
2391       *cluster_offset = first_cluster_offset;
2392       *cluster_time = stream_start_time;
2393       return TRUE;
2394     }
2395     GST_LOG_OBJECT (demux, "Trying prev cluster @ %" G_GUINT64_FORMAT, off);
2396   }
2397 
2398   /* If we found a cluster starting with a keyframe jump to that instead,
2399    * otherwise leave everything as it was before */
2400   if (cluster.time != GST_CLOCK_TIME_NONE
2401       && (cluster.offset == first_cluster_offset
2402           || cluster.status == CLUSTER_STATUS_STARTS_WITH_KEYFRAME)) {
2403     *cluster_offset = cluster.offset;
2404     *cluster_time = cluster.time;
2405     return TRUE;
2406   }
2407 
2408   return FALSE;
2409 }
2410 
2411 /* bisect and scan through file for cluster starting before @time,
2412  * returns fake index entry with corresponding info on cluster */
2413 static GstMatroskaIndex *
gst_matroska_demux_search_pos(GstMatroskaDemux * demux,GstClockTime time)2414 gst_matroska_demux_search_pos (GstMatroskaDemux * demux, GstClockTime time)
2415 {
2416   GstMatroskaIndex *entry = NULL;
2417   GstMatroskaReadState current_state;
2418   GstClockTime otime, prev_cluster_time, current_cluster_time, cluster_time;
2419   GstClockTime atime;
2420   gint64 opos, newpos, current_offset;
2421   gint64 prev_cluster_offset = -1, current_cluster_offset, cluster_offset;
2422   gint64 apos, maxpos;
2423   guint64 cluster_size = 0;
2424   GstFlowReturn ret;
2425   guint64 length;
2426   guint32 id;
2427   guint needed;
2428 
2429   /* estimate new position, resync using cluster ebml id,
2430    * and bisect further or scan forward to appropriate cluster */
2431 
2432   /* save some current global state which will be touched by our scanning */
2433   current_state = demux->common.state;
2434   g_return_val_if_fail (current_state == GST_MATROSKA_READ_STATE_DATA, NULL);
2435 
2436   current_cluster_offset = demux->cluster_offset;
2437   current_cluster_time = demux->cluster_time;
2438   current_offset = demux->common.offset;
2439 
2440   demux->common.state = GST_MATROSKA_READ_STATE_SCANNING;
2441 
2442   /* estimate using start and last known cluster */
2443   GST_OBJECT_LOCK (demux);
2444   apos = demux->first_cluster_offset;
2445   atime = demux->stream_start_time;
2446   opos = demux->last_cluster_offset;
2447   otime = demux->stream_last_time;
2448   GST_OBJECT_UNLOCK (demux);
2449 
2450   /* sanitize */
2451   time = MAX (time, atime);
2452   otime = MAX (otime, atime);
2453   opos = MAX (opos, apos);
2454 
2455   maxpos = gst_matroska_read_common_get_length (&demux->common);
2456 
2457   /* invariants;
2458    * apos <= opos
2459    * atime <= otime
2460    * apos always refer to a cluster before target time;
2461    * opos may or may not be after target time, but if it is once so,
2462    * then also in next iteration
2463    * */
2464 
2465 retry:
2466   GST_LOG_OBJECT (demux,
2467       "apos: %" G_GUINT64_FORMAT ", atime: %" GST_TIME_FORMAT ", %"
2468       GST_TIME_FORMAT " in stream time, "
2469       "opos: %" G_GUINT64_FORMAT ", otime: %" GST_TIME_FORMAT ", %"
2470       GST_TIME_FORMAT " in stream time (start %" GST_TIME_FORMAT "), time %"
2471       GST_TIME_FORMAT, apos, GST_TIME_ARGS (atime),
2472       GST_TIME_ARGS (atime - demux->stream_start_time), opos,
2473       GST_TIME_ARGS (otime), GST_TIME_ARGS (otime - demux->stream_start_time),
2474       GST_TIME_ARGS (demux->stream_start_time), GST_TIME_ARGS (time));
2475 
2476   g_assert (atime <= otime);
2477   g_assert (apos <= opos);
2478   if (time == GST_CLOCK_TIME_NONE) {
2479     GST_DEBUG_OBJECT (demux, "searching last cluster");
2480     newpos = maxpos;
2481     if (newpos == -1) {
2482       GST_DEBUG_OBJECT (demux, "unknown file size; bailing out");
2483       goto exit;
2484     }
2485   } else if (otime <= atime) {
2486     newpos = apos;
2487   } else {
2488     newpos = apos +
2489         gst_util_uint64_scale (opos - apos, time - atime, otime - atime);
2490     if (maxpos != -1 && newpos > maxpos)
2491       newpos = maxpos;
2492   }
2493 
2494   GST_DEBUG_OBJECT (demux,
2495       "estimated offset for %" GST_TIME_FORMAT ": %" G_GINT64_FORMAT,
2496       GST_TIME_ARGS (time), newpos);
2497 
2498   /* search backwards */
2499   if (newpos > apos) {
2500     ret = gst_matroska_demux_search_cluster (demux, &newpos, FALSE);
2501     if (ret != GST_FLOW_OK)
2502       goto exit;
2503   }
2504 
2505   /* then start scanning and parsing for cluster time,
2506    * re-estimate if possible, otherwise next cluster and so on */
2507   /* note that each re-estimate is entered with a change in apos or opos,
2508    * avoiding infinite loop */
2509   demux->common.offset = newpos;
2510   demux->cluster_time = cluster_time = GST_CLOCK_TIME_NONE;
2511   cluster_size = 0;
2512   prev_cluster_time = GST_CLOCK_TIME_NONE;
2513   while (1) {
2514     /* peek and parse some elements */
2515     ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
2516         GST_ELEMENT_CAST (demux), &id, &length, &needed);
2517     if (ret != GST_FLOW_OK)
2518       goto error;
2519     GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
2520         "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
2521         length, needed);
2522     ret = gst_matroska_demux_parse_id (demux, id, length, needed);
2523     if (ret != GST_FLOW_OK)
2524       goto error;
2525 
2526     if (id == GST_MATROSKA_ID_CLUSTER) {
2527       cluster_time = GST_CLOCK_TIME_NONE;
2528       if (length == G_MAXUINT64)
2529         cluster_size = 0;
2530       else
2531         cluster_size = length + needed;
2532     }
2533     if (demux->cluster_time != GST_CLOCK_TIME_NONE &&
2534         cluster_time == GST_CLOCK_TIME_NONE) {
2535       cluster_time = demux->cluster_time * demux->common.time_scale;
2536       cluster_offset = demux->cluster_offset;
2537       GST_DEBUG_OBJECT (demux, "found cluster at offset %" G_GINT64_FORMAT
2538           " with time %" GST_TIME_FORMAT, cluster_offset,
2539           GST_TIME_ARGS (cluster_time));
2540       if (time == GST_CLOCK_TIME_NONE) {
2541         GST_DEBUG_OBJECT (demux, "found last cluster");
2542         prev_cluster_time = cluster_time;
2543         prev_cluster_offset = cluster_offset;
2544         break;
2545       }
2546       if (cluster_time > time) {
2547         GST_DEBUG_OBJECT (demux, "overshot target");
2548         /* cluster overshoots */
2549         if (cluster_offset == demux->first_cluster_offset) {
2550           /* but no prev one */
2551           GST_DEBUG_OBJECT (demux, "but using first cluster anyway");
2552           prev_cluster_time = cluster_time;
2553           prev_cluster_offset = cluster_offset;
2554           break;
2555         }
2556         if (prev_cluster_time != GST_CLOCK_TIME_NONE) {
2557           /* prev cluster did not overshoot, so prev cluster is target */
2558           break;
2559         } else {
2560           /* re-estimate using this new position info */
2561           opos = cluster_offset;
2562           otime = cluster_time;
2563           goto retry;
2564         }
2565       } else {
2566         /* cluster undershoots */
2567         GST_DEBUG_OBJECT (demux, "undershot target");
2568         /* ok if close enough */
2569         if (GST_CLOCK_DIFF (cluster_time, time) < 5 * GST_SECOND) {
2570           GST_DEBUG_OBJECT (demux, "target close enough");
2571           prev_cluster_time = cluster_time;
2572           prev_cluster_offset = cluster_offset;
2573           break;
2574         }
2575         if (otime > time) {
2576           /* we are in between atime and otime => can bisect if worthwhile */
2577           if (prev_cluster_time != GST_CLOCK_TIME_NONE &&
2578               cluster_time > prev_cluster_time &&
2579               (GST_CLOCK_DIFF (prev_cluster_time, cluster_time) * 10 <
2580                   GST_CLOCK_DIFF (cluster_time, time))) {
2581             /* we moved at least one cluster forward,
2582              * and it looks like target is still far away,
2583              * let's estimate again */
2584             GST_DEBUG_OBJECT (demux, "bisecting with new apos");
2585             apos = cluster_offset;
2586             atime = cluster_time;
2587             goto retry;
2588           }
2589         }
2590         /* cluster undershoots, goto next one */
2591         prev_cluster_time = cluster_time;
2592         prev_cluster_offset = cluster_offset;
2593         /* skip cluster if length is defined,
2594          * otherwise will be skippingly parsed into */
2595         if (cluster_size) {
2596           GST_DEBUG_OBJECT (demux, "skipping to next cluster");
2597           demux->common.offset = cluster_offset + cluster_size;
2598           demux->cluster_time = GST_CLOCK_TIME_NONE;
2599         } else {
2600           GST_DEBUG_OBJECT (demux, "parsing/skipping cluster elements");
2601         }
2602       }
2603     }
2604     continue;
2605 
2606   error:
2607     if (ret == GST_FLOW_EOS) {
2608       if (prev_cluster_time != GST_CLOCK_TIME_NONE)
2609         break;
2610     }
2611     goto exit;
2612   }
2613 
2614   /* In the bisect loop above we always undershoot and then jump forward
2615    * cluster-by-cluster until we overshoot, so if we get here we've gone
2616    * over and the previous cluster is where we need to go to. */
2617   cluster_offset = prev_cluster_offset;
2618   cluster_time = prev_cluster_time;
2619 
2620   /* If we have video and can easily backtrack, check if we landed on a cluster
2621    * that starts with a keyframe - and if not backtrack until we find one that
2622    * does. */
2623   if (demux->have_nonintraonly_v_streams && demux->max_backtrack_distance > 0) {
2624     if (gst_matroska_demux_scan_back_for_keyframe_cluster (demux,
2625             &cluster_offset, &cluster_time)) {
2626       GST_INFO_OBJECT (demux, "Adjusted cluster to %" GST_TIME_FORMAT " @ "
2627           "%" G_GUINT64_FORMAT, GST_TIME_ARGS (cluster_time), cluster_offset);
2628     }
2629   }
2630 
2631   entry = g_new0 (GstMatroskaIndex, 1);
2632   entry->time = cluster_time;
2633   entry->pos = cluster_offset - demux->common.ebml_segment_start;
2634   GST_DEBUG_OBJECT (demux, "simulated index entry; time %" GST_TIME_FORMAT
2635       ", pos %" G_GUINT64_FORMAT, GST_TIME_ARGS (entry->time), entry->pos);
2636 
2637 exit:
2638 
2639   /* restore some state */
2640   demux->cluster_offset = current_cluster_offset;
2641   demux->cluster_time = current_cluster_time;
2642   demux->common.offset = current_offset;
2643   demux->common.state = current_state;
2644 
2645   return entry;
2646 }
2647 
2648 static gboolean
gst_matroska_demux_handle_seek_event(GstMatroskaDemux * demux,GstPad * pad,GstEvent * event)2649 gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
2650     GstPad * pad, GstEvent * event)
2651 {
2652   GstMatroskaIndex *entry = NULL;
2653   GstMatroskaIndex scan_entry;
2654   GstSeekFlags flags;
2655   GstSeekType cur_type, stop_type;
2656   GstFormat format;
2657   gboolean flush, keyunit, before, after, snap_next;
2658   gdouble rate;
2659   gint64 cur, stop;
2660   GstMatroskaTrackContext *track = NULL;
2661   GstSegment seeksegment = { 0, };
2662   gboolean update = TRUE;
2663   gboolean pad_locked = FALSE;
2664   guint32 seqnum;
2665   GstSearchMode snap_dir;
2666 
2667   g_return_val_if_fail (event != NULL, FALSE);
2668 
2669   if (pad)
2670     track = gst_pad_get_element_private (pad);
2671 
2672   GST_DEBUG_OBJECT (demux, "Have seek %" GST_PTR_FORMAT, event);
2673 
2674   gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
2675       &stop_type, &stop);
2676   seqnum = gst_event_get_seqnum (event);
2677 
2678   /* we can only seek on time */
2679   if (format != GST_FORMAT_TIME) {
2680     GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
2681     return FALSE;
2682   }
2683 
2684   /* copy segment, we need this because we still need the old
2685    * segment when we close the current segment. */
2686   memcpy (&seeksegment, &demux->common.segment, sizeof (GstSegment));
2687 
2688   /* pull mode without index means that the actual duration is not known,
2689    * we might be playing a file that's still being recorded
2690    * so, invalidate our current duration, which is only a moving target,
2691    * and should not be used to clamp anything */
2692   if (!demux->streaming && !demux->common.index && demux->invalid_duration) {
2693     seeksegment.duration = GST_CLOCK_TIME_NONE;
2694   }
2695 
2696   GST_DEBUG_OBJECT (demux, "configuring seek");
2697   /* Subtract stream_start_time so we always seek on a segment
2698    * in stream time */
2699   if (GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
2700     seeksegment.start -= demux->stream_start_time;
2701     seeksegment.position -= demux->stream_start_time;
2702     if (GST_CLOCK_TIME_IS_VALID (seeksegment.stop))
2703       seeksegment.stop -= demux->stream_start_time;
2704     else
2705       seeksegment.stop = seeksegment.duration;
2706   }
2707 
2708   gst_segment_do_seek (&seeksegment, rate, format, flags,
2709       cur_type, cur, stop_type, stop, &update);
2710 
2711   /* Restore the clip timestamp offset */
2712   if (GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
2713     seeksegment.position += demux->stream_start_time;
2714     seeksegment.start += demux->stream_start_time;
2715     if (!GST_CLOCK_TIME_IS_VALID (seeksegment.stop))
2716       seeksegment.stop = seeksegment.duration;
2717     if (GST_CLOCK_TIME_IS_VALID (seeksegment.stop))
2718       seeksegment.stop += demux->stream_start_time;
2719   }
2720 
2721   /* restore segment duration (if any effect),
2722    * would be determined again when parsing, but anyway ... */
2723   seeksegment.duration = demux->common.segment.duration;
2724 
2725   flush = ! !(flags & GST_SEEK_FLAG_FLUSH);
2726   keyunit = ! !(flags & GST_SEEK_FLAG_KEY_UNIT);
2727   after = ! !(flags & GST_SEEK_FLAG_SNAP_AFTER);
2728   before = ! !(flags & GST_SEEK_FLAG_SNAP_BEFORE);
2729 
2730   /* always do full update if flushing,
2731    * otherwise problems might arise downstream with missing keyframes etc */
2732   update = update || flush;
2733 
2734   GST_DEBUG_OBJECT (demux, "New segment %" GST_SEGMENT_FORMAT, &seeksegment);
2735 
2736   /* check sanity before we start flushing and all that */
2737   snap_next = after && !before;
2738   if (seeksegment.rate < 0)
2739     snap_dir = snap_next ? GST_SEARCH_MODE_BEFORE : GST_SEARCH_MODE_AFTER;
2740   else
2741     snap_dir = snap_next ? GST_SEARCH_MODE_AFTER : GST_SEARCH_MODE_BEFORE;
2742 
2743   GST_OBJECT_LOCK (demux);
2744   track = gst_matroska_read_common_get_seek_track (&demux->common, track);
2745   if ((entry = gst_matroska_read_common_do_index_seek (&demux->common, track,
2746               seeksegment.position, &demux->seek_index, &demux->seek_entry,
2747               snap_dir)) == NULL) {
2748     /* pull mode without index can scan later on */
2749     if (demux->streaming) {
2750       GST_DEBUG_OBJECT (demux, "No matching seek entry in index");
2751       GST_OBJECT_UNLOCK (demux);
2752       return FALSE;
2753     } else if (rate < 0.0) {
2754       /* FIXME: We should build an index during playback or when scanning
2755        * that can be used here. The reverse playback code requires seek_index
2756        * and seek_entry to be set!
2757        */
2758       GST_DEBUG_OBJECT (demux,
2759           "No matching seek entry in index, needed for reverse playback");
2760       GST_OBJECT_UNLOCK (demux);
2761       return FALSE;
2762     }
2763   }
2764   GST_DEBUG_OBJECT (demux, "Seek position looks sane");
2765   GST_OBJECT_UNLOCK (demux);
2766 
2767   if (!update) {
2768     /* only have to update some segment,
2769      * but also still have to honour flush and so on */
2770     GST_DEBUG_OBJECT (demux, "... no update");
2771     /* bad goto, bad ... */
2772     goto next;
2773   }
2774 
2775   if (demux->streaming)
2776     goto finish;
2777 
2778 next:
2779   if (flush) {
2780     GstEvent *flush_event = gst_event_new_flush_start ();
2781     gst_event_set_seqnum (flush_event, seqnum);
2782     GST_DEBUG_OBJECT (demux, "Starting flush");
2783     gst_pad_push_event (demux->common.sinkpad, gst_event_ref (flush_event));
2784     gst_matroska_demux_send_event (demux, flush_event);
2785   } else {
2786     GST_DEBUG_OBJECT (demux, "Non-flushing seek, pausing task");
2787     gst_pad_pause_task (demux->common.sinkpad);
2788   }
2789   /* ouch */
2790   if (!update) {
2791     GST_PAD_STREAM_LOCK (demux->common.sinkpad);
2792     pad_locked = TRUE;
2793     goto exit;
2794   }
2795 
2796   /* now grab the stream lock so that streaming cannot continue, for
2797    * non flushing seeks when the element is in PAUSED this could block
2798    * forever. */
2799   GST_DEBUG_OBJECT (demux, "Waiting for streaming to stop");
2800   GST_PAD_STREAM_LOCK (demux->common.sinkpad);
2801   pad_locked = TRUE;
2802 
2803   /* pull mode without index can do some scanning */
2804   if (!demux->streaming && !entry) {
2805     GstEvent *flush_event;
2806 
2807     /* need to stop flushing upstream as we need it next */
2808     if (flush) {
2809       flush_event = gst_event_new_flush_stop (TRUE);
2810       gst_event_set_seqnum (flush_event, seqnum);
2811       gst_pad_push_event (demux->common.sinkpad, flush_event);
2812     }
2813     entry = gst_matroska_demux_search_pos (demux, seeksegment.position);
2814     /* keep local copy */
2815     if (entry) {
2816       scan_entry = *entry;
2817       g_free (entry);
2818       entry = &scan_entry;
2819     } else {
2820       GST_DEBUG_OBJECT (demux, "Scan failed to find matching position");
2821       if (flush) {
2822         flush_event = gst_event_new_flush_stop (TRUE);
2823         gst_event_set_seqnum (flush_event, seqnum);
2824         gst_matroska_demux_send_event (demux, flush_event);
2825       }
2826       goto seek_error;
2827     }
2828   }
2829 
2830 finish:
2831   if (keyunit && seeksegment.rate > 0) {
2832     GST_DEBUG_OBJECT (demux, "seek to key unit, adjusting segment start from %"
2833         GST_TIME_FORMAT " to %" GST_TIME_FORMAT,
2834         GST_TIME_ARGS (seeksegment.start), GST_TIME_ARGS (entry->time));
2835     seeksegment.start = MAX (entry->time, demux->stream_start_time);
2836     seeksegment.position = seeksegment.start;
2837     seeksegment.time = seeksegment.start - demux->stream_start_time;
2838   } else if (keyunit) {
2839     GST_DEBUG_OBJECT (demux, "seek to key unit, adjusting segment stop from %"
2840         GST_TIME_FORMAT " to %" GST_TIME_FORMAT,
2841         GST_TIME_ARGS (seeksegment.stop), GST_TIME_ARGS (entry->time));
2842     seeksegment.stop = MAX (entry->time, demux->stream_start_time);
2843     seeksegment.position = seeksegment.stop;
2844   }
2845 
2846   if (demux->streaming) {
2847     GST_OBJECT_LOCK (demux);
2848     /* track real position we should start at */
2849     GST_DEBUG_OBJECT (demux, "storing segment start");
2850     demux->requested_seek_time = seeksegment.position;
2851     demux->seek_offset = entry->pos + demux->common.ebml_segment_start;
2852     GST_OBJECT_UNLOCK (demux);
2853     /* need to seek to cluster start to pick up cluster time */
2854     /* upstream takes care of flushing and all that
2855      * ... and newsegment event handling takes care of the rest */
2856     return perform_seek_to_offset (demux, rate,
2857         entry->pos + demux->common.ebml_segment_start, seqnum, flags);
2858   }
2859 
2860 exit:
2861   if (flush) {
2862     GstEvent *flush_event = gst_event_new_flush_stop (TRUE);
2863     gst_event_set_seqnum (flush_event, seqnum);
2864     GST_DEBUG_OBJECT (demux, "Stopping flush");
2865     gst_pad_push_event (demux->common.sinkpad, gst_event_ref (flush_event));
2866     gst_matroska_demux_send_event (demux, flush_event);
2867   }
2868 
2869   GST_OBJECT_LOCK (demux);
2870   /* now update the real segment info */
2871   GST_DEBUG_OBJECT (demux, "Committing new seek segment");
2872   memcpy (&demux->common.segment, &seeksegment, sizeof (GstSegment));
2873   GST_OBJECT_UNLOCK (demux);
2874 
2875   /* update some (segment) state */
2876   if (!gst_matroska_demux_move_to_entry (demux, entry, TRUE, update))
2877     goto seek_error;
2878 
2879   /* notify start of new segment */
2880   if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
2881     GstMessage *msg;
2882 
2883     msg = gst_message_new_segment_start (GST_OBJECT (demux),
2884         GST_FORMAT_TIME, demux->common.segment.start);
2885     gst_message_set_seqnum (msg, seqnum);
2886     gst_element_post_message (GST_ELEMENT (demux), msg);
2887   }
2888 
2889   GST_OBJECT_LOCK (demux);
2890   if (demux->new_segment)
2891     gst_event_unref (demux->new_segment);
2892 
2893   /* On port from 0.10, discarded !update (for segment.update) here, FIXME? */
2894   demux->new_segment = gst_event_new_segment (&demux->common.segment);
2895   gst_event_set_seqnum (demux->new_segment, seqnum);
2896   if (demux->common.segment.rate < 0 && demux->common.segment.stop == -1)
2897     demux->to_time = demux->common.segment.position;
2898   else
2899     demux->to_time = GST_CLOCK_TIME_NONE;
2900   demux->segment_seqnum = seqnum;
2901   GST_OBJECT_UNLOCK (demux);
2902 
2903   /* restart our task since it might have been stopped when we did the
2904    * flush. */
2905   gst_pad_start_task (demux->common.sinkpad,
2906       (GstTaskFunction) gst_matroska_demux_loop, demux->common.sinkpad, NULL);
2907 
2908   /* streaming can continue now */
2909   if (pad_locked) {
2910     GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
2911   }
2912 
2913   return TRUE;
2914 
2915 seek_error:
2916   {
2917     if (pad_locked) {
2918       GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
2919     }
2920     GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Got a seek error"));
2921     return FALSE;
2922   }
2923 }
2924 
2925 /*
2926  * Handle whether we can perform the seek event or if we have to let the chain
2927  * function handle seeks to build the seek indexes first.
2928  */
2929 static gboolean
gst_matroska_demux_handle_seek_push(GstMatroskaDemux * demux,GstPad * pad,GstEvent * event)2930 gst_matroska_demux_handle_seek_push (GstMatroskaDemux * demux, GstPad * pad,
2931     GstEvent * event)
2932 {
2933   GstSeekFlags flags;
2934   GstSeekType cur_type, stop_type;
2935   GstFormat format;
2936   gdouble rate;
2937   gint64 cur, stop;
2938 
2939   gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
2940       &stop_type, &stop);
2941 
2942   /* sanity checks */
2943 
2944   /* we can only seek on time */
2945   if (format != GST_FORMAT_TIME) {
2946     GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
2947     return FALSE;
2948   }
2949 
2950   if (stop_type != GST_SEEK_TYPE_NONE && stop != GST_CLOCK_TIME_NONE) {
2951     GST_DEBUG_OBJECT (demux, "Seek end-time not supported in streaming mode");
2952     return FALSE;
2953   }
2954 
2955   if (!(flags & GST_SEEK_FLAG_FLUSH)) {
2956     GST_DEBUG_OBJECT (demux,
2957         "Non-flushing seek not supported in streaming mode");
2958     return FALSE;
2959   }
2960 
2961   if (flags & GST_SEEK_FLAG_SEGMENT) {
2962     GST_DEBUG_OBJECT (demux, "Segment seek not supported in streaming mode");
2963     return FALSE;
2964   }
2965 
2966   /* check for having parsed index already */
2967   if (!demux->common.index_parsed) {
2968     gboolean building_index;
2969     guint64 offset = 0;
2970 
2971     if (!demux->index_offset) {
2972       GST_DEBUG_OBJECT (demux, "no index (location); no seek in push mode");
2973       return FALSE;
2974     }
2975 
2976     GST_OBJECT_LOCK (demux);
2977     /* handle the seek event in the chain function */
2978     demux->common.state = GST_MATROSKA_READ_STATE_SEEK;
2979     /* no more seek can be issued until state reset to _DATA */
2980 
2981     /* copy the event */
2982     if (demux->seek_event)
2983       gst_event_unref (demux->seek_event);
2984     demux->seek_event = gst_event_ref (event);
2985 
2986     /* set the building_index flag so that only one thread can setup the
2987      * structures for index seeking. */
2988     building_index = demux->building_index;
2989     if (!building_index) {
2990       demux->building_index = TRUE;
2991       offset = demux->index_offset;
2992     }
2993     GST_OBJECT_UNLOCK (demux);
2994 
2995     if (!building_index) {
2996       /* seek to the first subindex or legacy index */
2997       GST_INFO_OBJECT (demux, "Seeking to Cues at %" G_GUINT64_FORMAT, offset);
2998       return perform_seek_to_offset (demux, rate, offset,
2999           gst_event_get_seqnum (event), GST_SEEK_FLAG_NONE);
3000     }
3001 
3002     /* well, we are handling it already */
3003     return TRUE;
3004   }
3005 
3006   /* delegate to tweaked regular seek */
3007   return gst_matroska_demux_handle_seek_event (demux, pad, event);
3008 }
3009 
3010 static gboolean
gst_matroska_demux_handle_src_event(GstPad * pad,GstObject * parent,GstEvent * event)3011 gst_matroska_demux_handle_src_event (GstPad * pad, GstObject * parent,
3012     GstEvent * event)
3013 {
3014   GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
3015   gboolean res = TRUE;
3016 
3017   switch (GST_EVENT_TYPE (event)) {
3018     case GST_EVENT_SEEK:
3019       /* no seeking until we are (safely) ready */
3020       if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
3021         GST_DEBUG_OBJECT (demux,
3022             "not ready for seeking yet, deferring seek event: %" GST_PTR_FORMAT,
3023             event);
3024         if (demux->deferred_seek_event)
3025           gst_event_unref (demux->deferred_seek_event);
3026         demux->deferred_seek_event = event;
3027         demux->deferred_seek_pad = pad;
3028         return TRUE;
3029       }
3030 
3031       {
3032         guint32 seqnum = gst_event_get_seqnum (event);
3033         if (seqnum == demux->segment_seqnum) {
3034           GST_LOG_OBJECT (pad,
3035               "Drop duplicated SEEK event seqnum %" G_GUINT32_FORMAT, seqnum);
3036           gst_event_unref (event);
3037           return TRUE;
3038         }
3039       }
3040 
3041       if (!demux->streaming)
3042         res = gst_matroska_demux_handle_seek_event (demux, pad, event);
3043       else
3044         res = gst_matroska_demux_handle_seek_push (demux, pad, event);
3045       gst_event_unref (event);
3046       break;
3047 
3048     case GST_EVENT_QOS:
3049     {
3050       GstMatroskaTrackContext *context = gst_pad_get_element_private (pad);
3051       if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
3052         GstMatroskaTrackVideoContext *videocontext =
3053             (GstMatroskaTrackVideoContext *) context;
3054         gdouble proportion;
3055         GstClockTimeDiff diff;
3056         GstClockTime timestamp;
3057 
3058         gst_event_parse_qos (event, NULL, &proportion, &diff, &timestamp);
3059 
3060         GST_OBJECT_LOCK (demux);
3061         videocontext->earliest_time = timestamp + diff;
3062         GST_OBJECT_UNLOCK (demux);
3063       }
3064       res = TRUE;
3065       gst_event_unref (event);
3066       break;
3067     }
3068 
3069     case GST_EVENT_TOC_SELECT:
3070     {
3071       char *uid = NULL;
3072       GstTocEntry *entry = NULL;
3073       GstEvent *seek_event;
3074       gint64 start_pos;
3075 
3076       if (!demux->common.toc) {
3077         GST_DEBUG_OBJECT (demux, "no TOC to select");
3078         return FALSE;
3079       } else {
3080         gst_event_parse_toc_select (event, &uid);
3081         if (uid != NULL) {
3082           GST_OBJECT_LOCK (demux);
3083           entry = gst_toc_find_entry (demux->common.toc, uid);
3084           if (entry == NULL) {
3085             GST_OBJECT_UNLOCK (demux);
3086             GST_WARNING_OBJECT (demux, "no TOC entry with given UID: %s", uid);
3087             res = FALSE;
3088           } else {
3089             gst_toc_entry_get_start_stop_times (entry, &start_pos, NULL);
3090             GST_OBJECT_UNLOCK (demux);
3091             seek_event = gst_event_new_seek (1.0,
3092                 GST_FORMAT_TIME,
3093                 GST_SEEK_FLAG_FLUSH,
3094                 GST_SEEK_TYPE_SET, start_pos, GST_SEEK_TYPE_SET, -1);
3095             res = gst_matroska_demux_handle_seek_event (demux, pad, seek_event);
3096             gst_event_unref (seek_event);
3097           }
3098           g_free (uid);
3099         } else {
3100           GST_WARNING_OBJECT (demux, "received empty TOC select event");
3101           res = FALSE;
3102         }
3103       }
3104       gst_event_unref (event);
3105       break;
3106     }
3107 
3108       /* events we don't need to handle */
3109     case GST_EVENT_NAVIGATION:
3110       gst_event_unref (event);
3111       res = FALSE;
3112       break;
3113 
3114     case GST_EVENT_LATENCY:
3115     default:
3116       res = gst_pad_push_event (demux->common.sinkpad, event);
3117       break;
3118   }
3119 
3120   return res;
3121 }
3122 
3123 static gboolean
gst_matroska_demux_handle_sink_query(GstPad * pad,GstObject * parent,GstQuery * query)3124 gst_matroska_demux_handle_sink_query (GstPad * pad, GstObject * parent,
3125     GstQuery * query)
3126 {
3127   GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
3128   gboolean res = FALSE;
3129 
3130   switch (GST_QUERY_TYPE (query)) {
3131     case GST_QUERY_BITRATE:
3132     {
3133       if (G_UNLIKELY (demux->cached_length == G_MAXUINT64 ||
3134               demux->common.offset >= demux->cached_length)) {
3135         demux->cached_length =
3136             gst_matroska_read_common_get_length (&demux->common);
3137       }
3138 
3139       if (demux->cached_length < G_MAXUINT64
3140           && demux->common.segment.duration > 0) {
3141         /* TODO: better results based on ranges/index tables */
3142         guint bitrate =
3143             gst_util_uint64_scale (8 * demux->cached_length, GST_SECOND,
3144             demux->common.segment.duration);
3145 
3146         GST_LOG_OBJECT (demux, "bitrate query byte length: %" G_GUINT64_FORMAT
3147             " duration %" GST_TIME_FORMAT " resulting in a bitrate of %u",
3148             demux->cached_length,
3149             GST_TIME_ARGS (demux->common.segment.duration), bitrate);
3150 
3151         gst_query_set_bitrate (query, bitrate);
3152         res = TRUE;
3153       }
3154       break;
3155     }
3156     default:
3157       res = gst_pad_query_default (pad, (GstObject *) demux, query);
3158       break;
3159   }
3160 
3161   return res;
3162 }
3163 
3164 static GstFlowReturn
gst_matroska_demux_seek_to_previous_keyframe(GstMatroskaDemux * demux)3165 gst_matroska_demux_seek_to_previous_keyframe (GstMatroskaDemux * demux)
3166 {
3167   GstFlowReturn ret = GST_FLOW_EOS;
3168   gboolean done = TRUE;
3169   gint i;
3170 
3171   g_return_val_if_fail (demux->seek_index, GST_FLOW_EOS);
3172   g_return_val_if_fail (demux->seek_entry < demux->seek_index->len,
3173       GST_FLOW_EOS);
3174 
3175   GST_DEBUG_OBJECT (demux, "locating previous keyframe");
3176 
3177   if (!demux->seek_entry) {
3178     GST_DEBUG_OBJECT (demux, "no earlier index entry");
3179     goto exit;
3180   }
3181 
3182   for (i = 0; i < demux->common.src->len; i++) {
3183     GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
3184 
3185     GST_DEBUG_OBJECT (demux, "segment start %" GST_TIME_FORMAT
3186         ", stream %d at %" GST_TIME_FORMAT,
3187         GST_TIME_ARGS (demux->common.segment.start), stream->index,
3188         GST_TIME_ARGS (stream->from_time));
3189     if (GST_CLOCK_TIME_IS_VALID (stream->from_time)) {
3190       if (stream->from_time > demux->common.segment.start) {
3191         GST_DEBUG_OBJECT (demux, "stream %d not finished yet", stream->index);
3192         done = FALSE;
3193       }
3194     } else {
3195       /* nothing pushed for this stream;
3196        * likely seek entry did not start at keyframe, so all was skipped.
3197        * So we need an earlier entry */
3198       done = FALSE;
3199     }
3200   }
3201 
3202   if (!done) {
3203     GstMatroskaIndex *entry;
3204 
3205     entry = &g_array_index (demux->seek_index, GstMatroskaIndex,
3206         --demux->seek_entry);
3207     if (!gst_matroska_demux_move_to_entry (demux, entry, FALSE, TRUE))
3208       goto exit;
3209 
3210     ret = GST_FLOW_OK;
3211   }
3212 
3213 exit:
3214   return ret;
3215 }
3216 
3217 static GstFlowReturn
gst_matroska_demux_parse_tracks(GstMatroskaDemux * demux,GstEbmlRead * ebml)3218 gst_matroska_demux_parse_tracks (GstMatroskaDemux * demux, GstEbmlRead * ebml)
3219 {
3220   GstFlowReturn ret = GST_FLOW_OK;
3221   guint32 id;
3222 
3223   DEBUG_ELEMENT_START (demux, ebml, "Tracks");
3224 
3225   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3226     DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
3227     return ret;
3228   }
3229 
3230   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3231     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3232       break;
3233 
3234     switch (id) {
3235         /* one track within the "all-tracks" header */
3236       case GST_MATROSKA_ID_TRACKENTRY:{
3237         GstMatroskaTrackContext *track;
3238         ret = gst_matroska_demux_parse_stream (demux, ebml, &track);
3239         if (track != NULL) {
3240           if (gst_matroska_read_common_tracknumber_unique (&demux->common,
3241                   track->num)) {
3242             gst_matroska_demux_add_stream (demux, track);
3243           } else {
3244             GST_ERROR_OBJECT (demux,
3245                 "TrackNumber %" G_GUINT64_FORMAT " is not unique", track->num);
3246             ret = GST_FLOW_ERROR;
3247             gst_matroska_track_free (track);
3248             track = NULL;
3249           }
3250         }
3251         break;
3252       }
3253 
3254       default:
3255         ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3256             "Track", id);
3257         break;
3258     }
3259   }
3260   DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
3261 
3262   demux->tracks_parsed = TRUE;
3263   GST_DEBUG_OBJECT (demux, "signaling no more pads");
3264   gst_element_no_more_pads (GST_ELEMENT (demux));
3265 
3266   return ret;
3267 }
3268 
3269 static GstFlowReturn
gst_matroska_demux_update_tracks(GstMatroskaDemux * demux,GstEbmlRead * ebml)3270 gst_matroska_demux_update_tracks (GstMatroskaDemux * demux, GstEbmlRead * ebml)
3271 {
3272   GstFlowReturn ret = GST_FLOW_OK;
3273   guint num_tracks_found = 0;
3274   guint32 id;
3275 
3276   GST_INFO_OBJECT (demux, "Reparsing Tracks element");
3277 
3278   DEBUG_ELEMENT_START (demux, ebml, "Tracks");
3279 
3280   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3281     DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
3282     return ret;
3283   }
3284 
3285   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3286     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3287       break;
3288 
3289     switch (id) {
3290         /* one track within the "all-tracks" header */
3291       case GST_MATROSKA_ID_TRACKENTRY:{
3292         GstMatroskaTrackContext *new_track;
3293         gint old_track_index;
3294         GstMatroskaTrackContext *old_track;
3295         ret = gst_matroska_demux_parse_stream (demux, ebml, &new_track);
3296         if (new_track == NULL)
3297           break;
3298         num_tracks_found++;
3299 
3300         if (gst_matroska_read_common_tracknumber_unique (&demux->common,
3301                 new_track->num)) {
3302           GST_ERROR_OBJECT (demux,
3303               "Unexpected new TrackNumber: %" G_GUINT64_FORMAT, new_track->num);
3304           goto track_mismatch_error;
3305         }
3306 
3307         old_track_index =
3308             gst_matroska_read_common_stream_from_num (&demux->common,
3309             new_track->num);
3310         g_assert (old_track_index != -1);
3311         old_track = g_ptr_array_index (demux->common.src, old_track_index);
3312 
3313         if (old_track->type != new_track->type) {
3314           GST_ERROR_OBJECT (demux,
3315               "Mismatch reparsing track %" G_GUINT64_FORMAT
3316               " on track type. Expected %d, found %d", new_track->num,
3317               old_track->type, new_track->type);
3318           goto track_mismatch_error;
3319         }
3320 
3321         if (g_strcmp0 (old_track->codec_id, new_track->codec_id) != 0) {
3322           GST_ERROR_OBJECT (demux,
3323               "Mismatch reparsing track %" G_GUINT64_FORMAT
3324               " on codec id. Expected '%s', found '%s'", new_track->num,
3325               old_track->codec_id, new_track->codec_id);
3326           goto track_mismatch_error;
3327         }
3328 
3329         /* The new track matches the old track. No problems on our side.
3330          * Let's make it replace the old track. */
3331         new_track->pad = old_track->pad;
3332         new_track->index = old_track->index;
3333         new_track->pos = old_track->pos;
3334         g_ptr_array_index (demux->common.src, old_track_index) = new_track;
3335         gst_pad_set_element_private (new_track->pad, new_track);
3336 
3337         if (!gst_caps_is_equal (old_track->caps, new_track->caps)) {
3338           gst_pad_set_caps (new_track->pad, new_track->caps);
3339         }
3340         gst_caps_replace (&old_track->caps, NULL);
3341 
3342         if (!gst_tag_list_is_equal (old_track->tags, new_track->tags)) {
3343           GST_DEBUG_OBJECT (old_track->pad, "Sending tags %p: %"
3344               GST_PTR_FORMAT, new_track->tags, new_track->tags);
3345           gst_pad_push_event (new_track->pad,
3346               gst_event_new_tag (gst_tag_list_copy (new_track->tags)));
3347         }
3348 
3349         gst_matroska_track_free (old_track);
3350         break;
3351 
3352       track_mismatch_error:
3353         gst_matroska_track_free (new_track);
3354         new_track = NULL;
3355         ret = GST_FLOW_ERROR;
3356         break;
3357       }
3358 
3359       default:
3360         ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3361             "Track", id);
3362         break;
3363     }
3364   }
3365   DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
3366 
3367   if (ret != GST_FLOW_ERROR && demux->common.num_streams != num_tracks_found) {
3368     GST_ERROR_OBJECT (demux,
3369         "Mismatch on the number of tracks. Expected %du tracks, found %du",
3370         demux->common.num_streams, num_tracks_found);
3371     ret = GST_FLOW_ERROR;
3372   }
3373 
3374   return ret;
3375 }
3376 
3377 /*
3378  * Read signed/unsigned "EBML" numbers.
3379  * Return: number of bytes processed.
3380  */
3381 
3382 static gint
gst_matroska_ebmlnum_uint(guint8 * data,guint size,guint64 * num)3383 gst_matroska_ebmlnum_uint (guint8 * data, guint size, guint64 * num)
3384 {
3385   gint len_mask = 0x80, read = 1, n = 1, num_ffs = 0;
3386   guint64 total;
3387 
3388   if (size <= 0) {
3389     return -1;
3390   }
3391 
3392   total = data[0];
3393   while (read <= 8 && !(total & len_mask)) {
3394     read++;
3395     len_mask >>= 1;
3396   }
3397   if (read > 8)
3398     return -1;
3399 
3400   if ((total &= (len_mask - 1)) == len_mask - 1)
3401     num_ffs++;
3402   if (size < read)
3403     return -1;
3404   while (n < read) {
3405     if (data[n] == 0xff)
3406       num_ffs++;
3407     total = (total << 8) | data[n];
3408     n++;
3409   }
3410 
3411   if (read == num_ffs && total != 0)
3412     *num = G_MAXUINT64;
3413   else
3414     *num = total;
3415 
3416   return read;
3417 }
3418 
3419 static gint
gst_matroska_ebmlnum_sint(guint8 * data,guint size,gint64 * num)3420 gst_matroska_ebmlnum_sint (guint8 * data, guint size, gint64 * num)
3421 {
3422   guint64 unum;
3423   gint res;
3424 
3425   /* read as unsigned number first */
3426   if ((res = gst_matroska_ebmlnum_uint (data, size, &unum)) < 0)
3427     return -1;
3428 
3429   /* make signed */
3430   if (unum == G_MAXUINT64)
3431     *num = G_MAXINT64;
3432   else
3433     *num = unum - ((1 << ((7 * res) - 1)) - 1);
3434 
3435   return res;
3436 }
3437 
3438 /*
3439  * Mostly used for subtitles. We add void filler data for each
3440  * lagging stream to make sure we don't deadlock.
3441  */
3442 
3443 static void
gst_matroska_demux_sync_streams(GstMatroskaDemux * demux)3444 gst_matroska_demux_sync_streams (GstMatroskaDemux * demux)
3445 {
3446   GstClockTime gap_threshold;
3447   gint stream_nr;
3448 
3449   GST_OBJECT_LOCK (demux);
3450 
3451   GST_LOG_OBJECT (demux, "Sync to %" GST_TIME_FORMAT,
3452       GST_TIME_ARGS (demux->common.segment.position));
3453 
3454   g_assert (demux->common.num_streams == demux->common.src->len);
3455   for (stream_nr = 0; stream_nr < demux->common.src->len; stream_nr++) {
3456     GstMatroskaTrackContext *context;
3457 
3458     context = g_ptr_array_index (demux->common.src, stream_nr);
3459 
3460     GST_LOG_OBJECT (demux,
3461         "Checking for resync on stream %d (%" GST_TIME_FORMAT ")", stream_nr,
3462         GST_TIME_ARGS (context->pos));
3463 
3464     /* Only send gap events on non-subtitle streams if lagging way behind.
3465      * The 0.5 second threshold for subtitle streams is also quite random. */
3466     if (context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)
3467       gap_threshold = GST_SECOND / 2;
3468     else
3469       gap_threshold = 3 * GST_SECOND;
3470 
3471     /* Lag need only be considered if we have advanced into requested segment */
3472     if (GST_CLOCK_TIME_IS_VALID (context->pos) &&
3473         GST_CLOCK_TIME_IS_VALID (demux->common.segment.position) &&
3474         demux->common.segment.position > demux->common.segment.start &&
3475         context->pos + gap_threshold < demux->common.segment.position) {
3476 
3477       GstEvent *event;
3478       guint64 start = context->pos;
3479       guint64 stop = demux->common.segment.position - gap_threshold;
3480 
3481       GST_DEBUG_OBJECT (demux,
3482           "Synchronizing stream %d with other by advancing time from %"
3483           GST_TIME_FORMAT " to %" GST_TIME_FORMAT, stream_nr,
3484           GST_TIME_ARGS (start), GST_TIME_ARGS (stop));
3485 
3486       context->pos = stop;
3487 
3488       event = gst_event_new_gap (start, stop - start);
3489       GST_OBJECT_UNLOCK (demux);
3490       gst_pad_push_event (context->pad, event);
3491       GST_OBJECT_LOCK (demux);
3492     }
3493   }
3494 
3495   GST_OBJECT_UNLOCK (demux);
3496 }
3497 
3498 static GstFlowReturn
gst_matroska_demux_push_stream_headers(GstMatroskaDemux * demux,GstMatroskaTrackContext * stream)3499 gst_matroska_demux_push_stream_headers (GstMatroskaDemux * demux,
3500     GstMatroskaTrackContext * stream)
3501 {
3502   GstFlowReturn ret = GST_FLOW_OK;
3503   gint i, num;
3504 
3505   num = gst_buffer_list_length (stream->stream_headers);
3506   for (i = 0; i < num; ++i) {
3507     GstBuffer *buf;
3508 
3509     buf = gst_buffer_list_get (stream->stream_headers, i);
3510     buf = gst_buffer_copy (buf);
3511 
3512     GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
3513 
3514     if (stream->set_discont) {
3515       GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
3516       stream->set_discont = FALSE;
3517     } else {
3518       GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DISCONT);
3519     }
3520 
3521     /* push out all headers in one go and use last flow return */
3522     ret = gst_pad_push (stream->pad, buf);
3523   }
3524 
3525   /* don't need these any  longer */
3526   gst_buffer_list_unref (stream->stream_headers);
3527   stream->stream_headers = NULL;
3528 
3529   /* combine flows */
3530   ret = gst_flow_combiner_update_flow (demux->flowcombiner, ret);
3531 
3532   return ret;
3533 }
3534 
3535 static void
gst_matroska_demux_push_dvd_clut_change_event(GstMatroskaDemux * demux,GstMatroskaTrackContext * stream)3536 gst_matroska_demux_push_dvd_clut_change_event (GstMatroskaDemux * demux,
3537     GstMatroskaTrackContext * stream)
3538 {
3539   gchar *buf, *start;
3540 
3541   g_assert (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB));
3542 
3543   if (!stream->codec_priv)
3544     return;
3545 
3546   /* ideally, VobSub private data should be parsed and stored more convenient
3547    * elsewhere, but for now, only interested in a small part */
3548 
3549   /* make sure we have terminating 0 */
3550   buf = g_strndup (stream->codec_priv, stream->codec_priv_size);
3551 
3552   /* just locate and parse palette part */
3553   start = strstr (buf, "palette:");
3554   if (start) {
3555     gint i;
3556     guint32 clut[16];
3557     guint32 col;
3558     guint8 r, g, b, y, u, v;
3559 
3560     start += 8;
3561     while (g_ascii_isspace (*start))
3562       start++;
3563     for (i = 0; i < 16; i++) {
3564       if (sscanf (start, "%06x", &col) != 1)
3565         break;
3566       start += 6;
3567       while ((*start == ',') || g_ascii_isspace (*start))
3568         start++;
3569       /* sigh, need to convert this from vobsub pseudo-RGB to YUV */
3570       r = (col >> 16) & 0xff;
3571       g = (col >> 8) & 0xff;
3572       b = col & 0xff;
3573       y = CLAMP ((0.1494 * r + 0.6061 * g + 0.2445 * b) * 219 / 255 + 16, 0,
3574           255);
3575       u = CLAMP (0.6066 * r - 0.4322 * g - 0.1744 * b + 128, 0, 255);
3576       v = CLAMP (-0.08435 * r - 0.3422 * g + 0.4266 * b + 128, 0, 255);
3577       clut[i] = (y << 16) | (u << 8) | v;
3578     }
3579 
3580     /* got them all without problems; build and send event */
3581     if (i == 16) {
3582       GstStructure *s;
3583 
3584       s = gst_structure_new ("application/x-gst-dvd", "event", G_TYPE_STRING,
3585           "dvd-spu-clut-change", "clut00", G_TYPE_INT, clut[0], "clut01",
3586           G_TYPE_INT, clut[1], "clut02", G_TYPE_INT, clut[2], "clut03",
3587           G_TYPE_INT, clut[3], "clut04", G_TYPE_INT, clut[4], "clut05",
3588           G_TYPE_INT, clut[5], "clut06", G_TYPE_INT, clut[6], "clut07",
3589           G_TYPE_INT, clut[7], "clut08", G_TYPE_INT, clut[8], "clut09",
3590           G_TYPE_INT, clut[9], "clut10", G_TYPE_INT, clut[10], "clut11",
3591           G_TYPE_INT, clut[11], "clut12", G_TYPE_INT, clut[12], "clut13",
3592           G_TYPE_INT, clut[13], "clut14", G_TYPE_INT, clut[14], "clut15",
3593           G_TYPE_INT, clut[15], NULL);
3594 
3595       gst_pad_push_event (stream->pad,
3596           gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM_STICKY, s));
3597     }
3598   }
3599   g_free (buf);
3600 }
3601 
3602 static void
gst_matroska_demux_push_codec_data_all(GstMatroskaDemux * demux)3603 gst_matroska_demux_push_codec_data_all (GstMatroskaDemux * demux)
3604 {
3605   gint stream_nr;
3606 
3607   g_assert (demux->common.num_streams == demux->common.src->len);
3608   for (stream_nr = 0; stream_nr < demux->common.src->len; stream_nr++) {
3609     GstMatroskaTrackContext *stream;
3610 
3611     stream = g_ptr_array_index (demux->common.src, stream_nr);
3612 
3613     if (stream->send_stream_headers) {
3614       if (stream->stream_headers != NULL) {
3615         gst_matroska_demux_push_stream_headers (demux, stream);
3616       } else {
3617         /* FIXME: perhaps we can just disable and skip this stream then */
3618         GST_ELEMENT_ERROR (demux, STREAM, DECODE, (NULL),
3619             ("Failed to extract stream headers from codec private data"));
3620       }
3621       stream->send_stream_headers = FALSE;
3622     }
3623 
3624     if (stream->send_dvd_event) {
3625       gst_matroska_demux_push_dvd_clut_change_event (demux, stream);
3626       /* FIXME: should we send this event again after (flushing) seek ? */
3627       stream->send_dvd_event = FALSE;
3628     }
3629   }
3630 
3631 }
3632 
3633 static GstFlowReturn
gst_matroska_demux_add_mpeg_seq_header(GstElement * element,GstMatroskaTrackContext * stream,GstBuffer ** buf)3634 gst_matroska_demux_add_mpeg_seq_header (GstElement * element,
3635     GstMatroskaTrackContext * stream, GstBuffer ** buf)
3636 {
3637   guint8 *seq_header;
3638   guint seq_header_len;
3639   guint32 header, tmp;
3640 
3641   if (stream->codec_state) {
3642     seq_header = stream->codec_state;
3643     seq_header_len = stream->codec_state_size;
3644   } else if (stream->codec_priv) {
3645     seq_header = stream->codec_priv;
3646     seq_header_len = stream->codec_priv_size;
3647   } else {
3648     return GST_FLOW_OK;
3649   }
3650 
3651   /* Sequence header only needed for keyframes */
3652   if (GST_BUFFER_FLAG_IS_SET (*buf, GST_BUFFER_FLAG_DELTA_UNIT))
3653     return GST_FLOW_OK;
3654 
3655   if (gst_buffer_get_size (*buf) < 4)
3656     return GST_FLOW_OK;
3657 
3658   gst_buffer_extract (*buf, 0, &tmp, sizeof (guint32));
3659   header = GUINT32_FROM_BE (tmp);
3660 
3661   /* Sequence start code, if not found prepend */
3662   if (header != 0x000001b3) {
3663     GstBuffer *newbuf;
3664 
3665     GST_DEBUG_OBJECT (element, "Prepending MPEG sequence header");
3666 
3667     newbuf = gst_buffer_new_wrapped (g_memdup (seq_header, seq_header_len),
3668         seq_header_len);
3669 
3670     gst_buffer_copy_into (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
3671         GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_MEMORY, 0,
3672         gst_buffer_get_size (*buf));
3673 
3674     gst_buffer_unref (*buf);
3675     *buf = newbuf;
3676   }
3677 
3678   return GST_FLOW_OK;
3679 }
3680 
3681 static GstFlowReturn
gst_matroska_demux_add_wvpk_header(GstElement * element,GstMatroskaTrackContext * stream,GstBuffer ** buf)3682 gst_matroska_demux_add_wvpk_header (GstElement * element,
3683     GstMatroskaTrackContext * stream, GstBuffer ** buf)
3684 {
3685   GstMatroskaTrackAudioContext *audiocontext =
3686       (GstMatroskaTrackAudioContext *) stream;
3687   GstBuffer *newbuf = NULL;
3688   GstMapInfo map, outmap;
3689   guint8 *buf_data, *data;
3690   Wavpack4Header wvh;
3691 
3692   wvh.ck_id[0] = 'w';
3693   wvh.ck_id[1] = 'v';
3694   wvh.ck_id[2] = 'p';
3695   wvh.ck_id[3] = 'k';
3696 
3697   wvh.version = GST_READ_UINT16_LE (stream->codec_priv);
3698   wvh.track_no = 0;
3699   wvh.index_no = 0;
3700   wvh.total_samples = -1;
3701   wvh.block_index = audiocontext->wvpk_block_index;
3702 
3703   if (audiocontext->channels <= 2) {
3704     guint32 block_samples, tmp;
3705     gsize size = gst_buffer_get_size (*buf);
3706 
3707     gst_buffer_extract (*buf, 0, &tmp, sizeof (guint32));
3708     block_samples = GUINT32_FROM_LE (tmp);
3709     /* we need to reconstruct the header of the wavpack block */
3710 
3711     /* -20 because ck_size is the size of the wavpack block -8
3712      * and lace_size is the size of the wavpack block + 12
3713      * (the three guint32 of the header that already are in the buffer) */
3714     wvh.ck_size = size + sizeof (Wavpack4Header) - 20;
3715 
3716     /* block_samples, flags and crc are already in the buffer */
3717     newbuf = gst_buffer_new_allocate (NULL, sizeof (Wavpack4Header) - 12, NULL);
3718 
3719     gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
3720     data = outmap.data;
3721     data[0] = 'w';
3722     data[1] = 'v';
3723     data[2] = 'p';
3724     data[3] = 'k';
3725     GST_WRITE_UINT32_LE (data + 4, wvh.ck_size);
3726     GST_WRITE_UINT16_LE (data + 8, wvh.version);
3727     GST_WRITE_UINT8 (data + 10, wvh.track_no);
3728     GST_WRITE_UINT8 (data + 11, wvh.index_no);
3729     GST_WRITE_UINT32_LE (data + 12, wvh.total_samples);
3730     GST_WRITE_UINT32_LE (data + 16, wvh.block_index);
3731     gst_buffer_unmap (newbuf, &outmap);
3732 
3733     /* Append data from buf: */
3734     gst_buffer_copy_into (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
3735         GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_MEMORY, 0, size);
3736 
3737     gst_buffer_unref (*buf);
3738     *buf = newbuf;
3739     audiocontext->wvpk_block_index += block_samples;
3740   } else {
3741     guint8 *outdata = NULL;
3742     guint outpos = 0;
3743     gsize buf_size, size, out_size = 0;
3744     guint32 block_samples, flags, crc, blocksize;
3745 
3746     gst_buffer_map (*buf, &map, GST_MAP_READ);
3747     buf_data = map.data;
3748     buf_size = map.size;
3749 
3750     if (buf_size < 4) {
3751       GST_ERROR_OBJECT (element, "Too small wavpack buffer");
3752       gst_buffer_unmap (*buf, &map);
3753       return GST_FLOW_ERROR;
3754     }
3755 
3756     data = buf_data;
3757     size = buf_size;
3758 
3759     block_samples = GST_READ_UINT32_LE (data);
3760     data += 4;
3761     size -= 4;
3762 
3763     while (size > 12) {
3764       flags = GST_READ_UINT32_LE (data);
3765       data += 4;
3766       size -= 4;
3767       crc = GST_READ_UINT32_LE (data);
3768       data += 4;
3769       size -= 4;
3770       blocksize = GST_READ_UINT32_LE (data);
3771       data += 4;
3772       size -= 4;
3773 
3774       if (blocksize == 0 || size < blocksize)
3775         break;
3776 
3777       g_assert ((newbuf == NULL) == (outdata == NULL));
3778 
3779       if (newbuf == NULL) {
3780         out_size = sizeof (Wavpack4Header) + blocksize;
3781         newbuf = gst_buffer_new_allocate (NULL, out_size, NULL);
3782 
3783         gst_buffer_copy_into (newbuf, *buf,
3784             GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS, 0, -1);
3785 
3786         outpos = 0;
3787         gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
3788         outdata = outmap.data;
3789       } else {
3790         gst_buffer_unmap (newbuf, &outmap);
3791         out_size += sizeof (Wavpack4Header) + blocksize;
3792         gst_buffer_set_size (newbuf, out_size);
3793         gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
3794         outdata = outmap.data;
3795       }
3796 
3797       outdata[outpos] = 'w';
3798       outdata[outpos + 1] = 'v';
3799       outdata[outpos + 2] = 'p';
3800       outdata[outpos + 3] = 'k';
3801       outpos += 4;
3802 
3803       GST_WRITE_UINT32_LE (outdata + outpos,
3804           blocksize + sizeof (Wavpack4Header) - 8);
3805       GST_WRITE_UINT16_LE (outdata + outpos + 4, wvh.version);
3806       GST_WRITE_UINT8 (outdata + outpos + 6, wvh.track_no);
3807       GST_WRITE_UINT8 (outdata + outpos + 7, wvh.index_no);
3808       GST_WRITE_UINT32_LE (outdata + outpos + 8, wvh.total_samples);
3809       GST_WRITE_UINT32_LE (outdata + outpos + 12, wvh.block_index);
3810       GST_WRITE_UINT32_LE (outdata + outpos + 16, block_samples);
3811       GST_WRITE_UINT32_LE (outdata + outpos + 20, flags);
3812       GST_WRITE_UINT32_LE (outdata + outpos + 24, crc);
3813       outpos += 28;
3814 
3815       memmove (outdata + outpos, data, blocksize);
3816       outpos += blocksize;
3817       data += blocksize;
3818       size -= blocksize;
3819     }
3820     gst_buffer_unmap (*buf, &map);
3821     gst_buffer_unref (*buf);
3822 
3823     if (newbuf)
3824       gst_buffer_unmap (newbuf, &outmap);
3825 
3826     *buf = newbuf;
3827     audiocontext->wvpk_block_index += block_samples;
3828   }
3829 
3830   return GST_FLOW_OK;
3831 }
3832 
3833 static GstFlowReturn
gst_matroska_demux_add_prores_header(GstElement * element,GstMatroskaTrackContext * stream,GstBuffer ** buf)3834 gst_matroska_demux_add_prores_header (GstElement * element,
3835     GstMatroskaTrackContext * stream, GstBuffer ** buf)
3836 {
3837   GstBuffer *newbuf = gst_buffer_new_allocate (NULL, 8, NULL);
3838   GstMapInfo map;
3839   guint32 frame_size;
3840 
3841   if (!gst_buffer_map (newbuf, &map, GST_MAP_WRITE)) {
3842     GST_ERROR ("Failed to map newly allocated buffer");
3843     return GST_FLOW_ERROR;
3844   }
3845 
3846   frame_size = gst_buffer_get_size (*buf);
3847 
3848   GST_WRITE_UINT32_BE (map.data, frame_size);
3849   map.data[4] = 'i';
3850   map.data[5] = 'c';
3851   map.data[6] = 'p';
3852   map.data[7] = 'f';
3853 
3854   gst_buffer_unmap (newbuf, &map);
3855   *buf = gst_buffer_append (newbuf, *buf);
3856 
3857   return GST_FLOW_OK;
3858 }
3859 
3860 /* @text must be null-terminated */
3861 static gboolean
gst_matroska_demux_subtitle_chunk_has_tag(GstElement * element,const gchar * text)3862 gst_matroska_demux_subtitle_chunk_has_tag (GstElement * element,
3863     const gchar * text)
3864 {
3865   gchar *tag;
3866 
3867   g_return_val_if_fail (text != NULL, FALSE);
3868 
3869   /* yes, this might all lead to false positives ... */
3870   tag = (gchar *) text;
3871   while ((tag = strchr (tag, '<'))) {
3872     tag++;
3873     if (*tag != '\0' && *(tag + 1) == '>') {
3874       /* some common convenience ones */
3875       /* maybe any character will do here ? */
3876       switch (*tag) {
3877         case 'b':
3878         case 'i':
3879         case 'u':
3880         case 's':
3881           return TRUE;
3882         default:
3883           return FALSE;
3884       }
3885     }
3886   }
3887 
3888   if (strstr (text, "<span"))
3889     return TRUE;
3890 
3891   return FALSE;
3892 }
3893 
3894 static GstFlowReturn
gst_matroska_demux_check_subtitle_buffer(GstElement * element,GstMatroskaTrackContext * stream,GstBuffer ** buf)3895 gst_matroska_demux_check_subtitle_buffer (GstElement * element,
3896     GstMatroskaTrackContext * stream, GstBuffer ** buf)
3897 {
3898   GstMatroskaTrackSubtitleContext *sub_stream;
3899   const gchar *encoding;
3900   GError *err = NULL;
3901   GstBuffer *newbuf;
3902   gchar *utf8;
3903   GstMapInfo map;
3904   gboolean needs_unmap = TRUE;
3905 
3906   sub_stream = (GstMatroskaTrackSubtitleContext *) stream;
3907 
3908   if (!gst_buffer_get_size (*buf) || !gst_buffer_map (*buf, &map, GST_MAP_READ))
3909     return GST_FLOW_OK;
3910 
3911   /* The subtitle buffer we push out should not include a NUL terminator as
3912    * part of the data. */
3913   if (map.data[map.size - 1] == '\0') {
3914     gst_buffer_set_size (*buf, map.size - 1);
3915     gst_buffer_unmap (*buf, &map);
3916     gst_buffer_map (*buf, &map, GST_MAP_READ);
3917   }
3918 
3919   if (!sub_stream->invalid_utf8) {
3920     if (g_utf8_validate ((gchar *) map.data, map.size, NULL)) {
3921       goto next;
3922     }
3923     GST_WARNING_OBJECT (element, "subtitle stream %" G_GUINT64_FORMAT
3924         " is not valid UTF-8, this is broken according to the matroska"
3925         " specification", stream->num);
3926     sub_stream->invalid_utf8 = TRUE;
3927   }
3928 
3929   /* file with broken non-UTF8 subtitle, do the best we can do to fix it */
3930   encoding = g_getenv ("GST_SUBTITLE_ENCODING");
3931   if (encoding == NULL || *encoding == '\0') {
3932     /* if local encoding is UTF-8 and no encoding specified
3933      * via the environment variable, assume ISO-8859-15 */
3934     if (g_get_charset (&encoding)) {
3935       encoding = "ISO-8859-15";
3936     }
3937   }
3938 
3939   utf8 =
3940       g_convert_with_fallback ((gchar *) map.data, map.size, "UTF-8", encoding,
3941       (char *) "*", NULL, NULL, &err);
3942 
3943   if (err) {
3944     GST_LOG_OBJECT (element, "could not convert string from '%s' to UTF-8: %s",
3945         encoding, err->message);
3946     g_error_free (err);
3947     g_free (utf8);
3948 
3949     /* invalid input encoding, fall back to ISO-8859-15 (always succeeds) */
3950     encoding = "ISO-8859-15";
3951     utf8 =
3952         g_convert_with_fallback ((gchar *) map.data, map.size, "UTF-8",
3953         encoding, (char *) "*", NULL, NULL, NULL);
3954   }
3955 
3956   GST_LOG_OBJECT (element, "converted subtitle text from %s to UTF-8 %s",
3957       encoding, (err) ? "(using ISO-8859-15 as fallback)" : "");
3958 
3959   if (utf8 == NULL)
3960     utf8 = g_strdup ("invalid subtitle");
3961 
3962   newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
3963   gst_buffer_unmap (*buf, &map);
3964   gst_buffer_copy_into (newbuf, *buf,
3965       GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_META,
3966       0, -1);
3967   gst_buffer_unref (*buf);
3968 
3969   *buf = newbuf;
3970   gst_buffer_map (*buf, &map, GST_MAP_READ);
3971 
3972 next:
3973 
3974   if (sub_stream->check_markup) {
3975     /* caps claim markup text, so we need to escape text,
3976      * except if text is already markup and then needs no further escaping */
3977     sub_stream->seen_markup_tag = sub_stream->seen_markup_tag ||
3978         gst_matroska_demux_subtitle_chunk_has_tag (element, (gchar *) map.data);
3979 
3980     if (!sub_stream->seen_markup_tag) {
3981       utf8 = g_markup_escape_text ((gchar *) map.data, map.size);
3982 
3983       newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
3984       gst_buffer_unmap (*buf, &map);
3985       gst_buffer_copy_into (newbuf, *buf,
3986           GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS |
3987           GST_BUFFER_COPY_META, 0, -1);
3988       gst_buffer_unref (*buf);
3989 
3990       *buf = newbuf;
3991       needs_unmap = FALSE;
3992     }
3993   }
3994 
3995   if (needs_unmap)
3996     gst_buffer_unmap (*buf, &map);
3997 
3998   return GST_FLOW_OK;
3999 }
4000 
4001 static GstFlowReturn
gst_matroska_demux_check_aac(GstElement * element,GstMatroskaTrackContext * stream,GstBuffer ** buf)4002 gst_matroska_demux_check_aac (GstElement * element,
4003     GstMatroskaTrackContext * stream, GstBuffer ** buf)
4004 {
4005   guint8 data[2];
4006   guint size;
4007 
4008   gst_buffer_extract (*buf, 0, data, 2);
4009   size = gst_buffer_get_size (*buf);
4010 
4011   if (size > 2 && data[0] == 0xff && (data[1] >> 4 == 0x0f)) {
4012     GstStructure *s;
4013 
4014     /* tss, ADTS data, remove codec_data
4015      * still assume it is at least parsed */
4016     stream->caps = gst_caps_make_writable (stream->caps);
4017     s = gst_caps_get_structure (stream->caps, 0);
4018     g_assert (s);
4019     gst_structure_remove_field (s, "codec_data");
4020     gst_pad_set_caps (stream->pad, stream->caps);
4021     GST_DEBUG_OBJECT (element, "ADTS AAC audio data; removing codec-data, "
4022         "new caps: %" GST_PTR_FORMAT, stream->caps);
4023   }
4024 
4025   /* disable subsequent checking */
4026   stream->postprocess_frame = NULL;
4027 
4028   return GST_FLOW_OK;
4029 }
4030 
4031 static GstBuffer *
gst_matroska_demux_align_buffer(GstMatroskaDemux * demux,GstBuffer * buffer,gsize alignment)4032 gst_matroska_demux_align_buffer (GstMatroskaDemux * demux,
4033     GstBuffer * buffer, gsize alignment)
4034 {
4035   GstMapInfo map;
4036 
4037   gst_buffer_map (buffer, &map, GST_MAP_READ);
4038 
4039   if (map.size < sizeof (guintptr)) {
4040     gst_buffer_unmap (buffer, &map);
4041     return buffer;
4042   }
4043 
4044   if (((guintptr) map.data) & (alignment - 1)) {
4045     GstBuffer *new_buffer;
4046     GstAllocationParams params = { 0, alignment - 1, 0, 0, };
4047 
4048     new_buffer = gst_buffer_new_allocate (NULL,
4049         gst_buffer_get_size (buffer), &params);
4050 
4051     /* Copy data "by hand", so ensure alignment is kept: */
4052     gst_buffer_fill (new_buffer, 0, map.data, map.size);
4053 
4054     gst_buffer_copy_into (new_buffer, buffer, GST_BUFFER_COPY_METADATA, 0, -1);
4055     GST_DEBUG_OBJECT (demux,
4056         "We want output aligned on %" G_GSIZE_FORMAT ", reallocated",
4057         alignment);
4058 
4059     gst_buffer_unmap (buffer, &map);
4060     gst_buffer_unref (buffer);
4061 
4062     return new_buffer;
4063   }
4064 
4065   gst_buffer_unmap (buffer, &map);
4066   return buffer;
4067 }
4068 
4069 static GstFlowReturn
gst_matroska_demux_parse_blockgroup_or_simpleblock(GstMatroskaDemux * demux,GstEbmlRead * ebml,guint64 cluster_time,guint64 cluster_offset,gboolean is_simpleblock)4070 gst_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux,
4071     GstEbmlRead * ebml, guint64 cluster_time, guint64 cluster_offset,
4072     gboolean is_simpleblock)
4073 {
4074   GstMatroskaTrackContext *stream = NULL;
4075   GstFlowReturn ret = GST_FLOW_OK;
4076   gboolean readblock = FALSE;
4077   guint32 id;
4078   guint64 block_duration = -1;
4079   gint64 block_discardpadding = 0;
4080   GstBuffer *buf = NULL;
4081   GstMapInfo map;
4082   gint stream_num = -1, n, laces = 0;
4083   guint size = 0;
4084   gint *lace_size = NULL;
4085   gint64 time = 0;
4086   gint flags = 0;
4087   gint64 referenceblock = 0;
4088   gint64 offset;
4089   GstClockTime buffer_timestamp;
4090 
4091   offset = gst_ebml_read_get_offset (ebml);
4092 
4093   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
4094     if (!is_simpleblock) {
4095       if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK) {
4096         goto data_error;
4097       }
4098     } else {
4099       id = GST_MATROSKA_ID_SIMPLEBLOCK;
4100     }
4101 
4102     switch (id) {
4103         /* one block inside the group. Note, block parsing is one
4104          * of the harder things, so this code is a bit complicated.
4105          * See http://www.matroska.org/ for documentation. */
4106       case GST_MATROSKA_ID_SIMPLEBLOCK:
4107       case GST_MATROSKA_ID_BLOCK:
4108       {
4109         guint64 num;
4110         guint8 *data;
4111 
4112         if (buf) {
4113           gst_buffer_unmap (buf, &map);
4114           gst_buffer_unref (buf);
4115           buf = NULL;
4116         }
4117         if ((ret = gst_ebml_read_buffer (ebml, &id, &buf)) != GST_FLOW_OK)
4118           break;
4119 
4120         gst_buffer_map (buf, &map, GST_MAP_READ);
4121         data = map.data;
4122         size = map.size;
4123 
4124         /* first byte(s): blocknum */
4125         if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
4126           goto data_error;
4127         data += n;
4128         size -= n;
4129 
4130         /* fetch stream from num */
4131         stream_num = gst_matroska_read_common_stream_from_num (&demux->common,
4132             num);
4133         if (G_UNLIKELY (size < 3)) {
4134           GST_WARNING_OBJECT (demux, "Invalid size %u", size);
4135           /* non-fatal, try next block(group) */
4136           ret = GST_FLOW_OK;
4137           goto done;
4138         } else if (G_UNLIKELY (stream_num < 0 ||
4139                 stream_num >= demux->common.num_streams)) {
4140           /* let's not give up on a stray invalid track number */
4141           GST_WARNING_OBJECT (demux,
4142               "Invalid stream %d for track number %" G_GUINT64_FORMAT
4143               "; ignoring block", stream_num, num);
4144           goto done;
4145         }
4146 
4147         stream = g_ptr_array_index (demux->common.src, stream_num);
4148 
4149         /* time (relative to cluster time) */
4150         time = ((gint16) GST_READ_UINT16_BE (data));
4151         data += 2;
4152         size -= 2;
4153         flags = GST_READ_UINT8 (data);
4154         data += 1;
4155         size -= 1;
4156 
4157         GST_LOG_OBJECT (demux, "time %" G_GUINT64_FORMAT ", flags %d", time,
4158             flags);
4159 
4160         switch ((flags & 0x06) >> 1) {
4161           case 0x0:            /* no lacing */
4162             laces = 1;
4163             lace_size = g_new (gint, 1);
4164             lace_size[0] = size;
4165             break;
4166 
4167           case 0x1:            /* xiph lacing */
4168           case 0x2:            /* fixed-size lacing */
4169           case 0x3:            /* EBML lacing */
4170             if (size == 0)
4171               goto invalid_lacing;
4172             laces = GST_READ_UINT8 (data) + 1;
4173             data += 1;
4174             size -= 1;
4175             lace_size = g_new0 (gint, laces);
4176 
4177             switch ((flags & 0x06) >> 1) {
4178               case 0x1:        /* xiph lacing */  {
4179                 guint temp, total = 0;
4180 
4181                 for (n = 0; ret == GST_FLOW_OK && n < laces - 1; n++) {
4182                   while (1) {
4183                     if (size == 0)
4184                       goto invalid_lacing;
4185                     temp = GST_READ_UINT8 (data);
4186                     lace_size[n] += temp;
4187                     data += 1;
4188                     size -= 1;
4189                     if (temp != 0xff)
4190                       break;
4191                   }
4192                   total += lace_size[n];
4193                 }
4194                 lace_size[n] = size - total;
4195                 break;
4196               }
4197 
4198               case 0x2:        /* fixed-size lacing */
4199                 for (n = 0; n < laces; n++)
4200                   lace_size[n] = size / laces;
4201                 break;
4202 
4203               case 0x3:        /* EBML lacing */  {
4204                 guint total;
4205 
4206                 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
4207                   goto data_error;
4208                 data += n;
4209                 size -= n;
4210                 total = lace_size[0] = num;
4211                 for (n = 1; ret == GST_FLOW_OK && n < laces - 1; n++) {
4212                   gint64 snum;
4213                   gint r;
4214 
4215                   if ((r = gst_matroska_ebmlnum_sint (data, size, &snum)) < 0)
4216                     goto data_error;
4217                   data += r;
4218                   size -= r;
4219                   lace_size[n] = lace_size[n - 1] + snum;
4220                   total += lace_size[n];
4221                 }
4222                 if (n < laces)
4223                   lace_size[n] = size - total;
4224                 break;
4225               }
4226             }
4227             break;
4228         }
4229 
4230         if (ret != GST_FLOW_OK)
4231           break;
4232 
4233         readblock = TRUE;
4234         break;
4235       }
4236 
4237       case GST_MATROSKA_ID_BLOCKDURATION:{
4238         ret = gst_ebml_read_uint (ebml, &id, &block_duration);
4239         GST_DEBUG_OBJECT (demux, "BlockDuration: %" G_GUINT64_FORMAT,
4240             block_duration);
4241         break;
4242       }
4243 
4244       case GST_MATROSKA_ID_DISCARDPADDING:{
4245         ret = gst_ebml_read_sint (ebml, &id, &block_discardpadding);
4246         GST_DEBUG_OBJECT (demux, "DiscardPadding: %" GST_STIME_FORMAT,
4247             GST_STIME_ARGS (block_discardpadding));
4248         break;
4249       }
4250 
4251       case GST_MATROSKA_ID_REFERENCEBLOCK:{
4252         ret = gst_ebml_read_sint (ebml, &id, &referenceblock);
4253         GST_DEBUG_OBJECT (demux, "ReferenceBlock: %" G_GINT64_FORMAT,
4254             referenceblock);
4255         break;
4256       }
4257 
4258       case GST_MATROSKA_ID_CODECSTATE:{
4259         guint8 *data;
4260         guint64 data_len = 0;
4261 
4262         if ((ret =
4263                 gst_ebml_read_binary (ebml, &id, &data,
4264                     &data_len)) != GST_FLOW_OK)
4265           break;
4266 
4267         if (G_UNLIKELY (stream == NULL)) {
4268           GST_WARNING_OBJECT (demux,
4269               "Unexpected CodecState subelement - ignoring");
4270           break;
4271         }
4272 
4273         g_free (stream->codec_state);
4274         stream->codec_state = data;
4275         stream->codec_state_size = data_len;
4276 
4277         /* Decode if necessary */
4278         if (stream->encodings && stream->encodings->len > 0
4279             && stream->codec_state && stream->codec_state_size > 0) {
4280           if (!gst_matroska_decode_data (stream->encodings,
4281                   &stream->codec_state, &stream->codec_state_size,
4282                   GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
4283             GST_WARNING_OBJECT (demux, "Decoding codec state failed");
4284           }
4285         }
4286 
4287         GST_DEBUG_OBJECT (demux, "CodecState of %" G_GSIZE_FORMAT " bytes",
4288             stream->codec_state_size);
4289         break;
4290       }
4291 
4292       default:
4293         ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
4294             "BlockGroup", id);
4295         break;
4296 
4297       case GST_MATROSKA_ID_BLOCKVIRTUAL:
4298       case GST_MATROSKA_ID_BLOCKADDITIONS:
4299       case GST_MATROSKA_ID_REFERENCEPRIORITY:
4300       case GST_MATROSKA_ID_REFERENCEVIRTUAL:
4301       case GST_MATROSKA_ID_SLICES:
4302         GST_DEBUG_OBJECT (demux,
4303             "Skipping BlockGroup subelement 0x%x - ignoring", id);
4304         ret = gst_ebml_read_skip (ebml);
4305         break;
4306     }
4307 
4308     if (is_simpleblock)
4309       break;
4310   }
4311 
4312   /* reading a number or so could have failed */
4313   if (ret != GST_FLOW_OK)
4314     goto data_error;
4315 
4316   if (ret == GST_FLOW_OK && readblock) {
4317     gboolean invisible_frame = FALSE;
4318     gboolean delta_unit = FALSE;
4319     guint64 duration = 0;
4320     gint64 lace_time = 0;
4321     GstEvent *protect_event;
4322 
4323     stream = g_ptr_array_index (demux->common.src, stream_num);
4324 
4325     if (cluster_time != GST_CLOCK_TIME_NONE) {
4326       /* FIXME: What to do with negative timestamps? Give timestamp 0 or -1?
4327        * Drop unless the lace contains timestamp 0? */
4328       if (time < 0 && (-time) > cluster_time) {
4329         lace_time = 0;
4330       } else {
4331         if (stream->timecodescale == 1.0)
4332           lace_time = (cluster_time + time) * demux->common.time_scale;
4333         else
4334           lace_time =
4335               gst_util_guint64_to_gdouble ((cluster_time + time) *
4336               demux->common.time_scale) * stream->timecodescale;
4337       }
4338     } else {
4339       lace_time = GST_CLOCK_TIME_NONE;
4340     }
4341     /* Send the GST_PROTECTION event */
4342     while ((protect_event = g_queue_pop_head (&stream->protection_event_queue))) {
4343       GST_TRACE_OBJECT (demux, "pushing protection event for stream %d:%s",
4344           stream->index, GST_STR_NULL (stream->name));
4345       gst_pad_push_event (stream->pad, protect_event);
4346     }
4347 
4348     /* need to refresh segment info ASAP */
4349     if (GST_CLOCK_TIME_IS_VALID (lace_time) && demux->need_segment) {
4350       GstSegment *segment = &demux->common.segment;
4351       guint64 clace_time;
4352       GstEvent *segment_event;
4353 
4354       if (!GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
4355         demux->stream_start_time = lace_time;
4356         GST_DEBUG_OBJECT (demux,
4357             "Setting stream start time to %" GST_TIME_FORMAT,
4358             GST_TIME_ARGS (lace_time));
4359       }
4360       clace_time = MAX (lace_time, demux->stream_start_time);
4361       if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.position) &&
4362           demux->common.segment.position != 0) {
4363         GST_DEBUG_OBJECT (demux,
4364             "using stored seek position %" GST_TIME_FORMAT,
4365             GST_TIME_ARGS (demux->common.segment.position));
4366         clace_time = demux->common.segment.position;
4367         segment->position = GST_CLOCK_TIME_NONE;
4368       }
4369       segment->start = clace_time;
4370       segment->stop = GST_CLOCK_TIME_NONE;
4371       segment->time = segment->start - demux->stream_start_time;
4372       segment->position = segment->start - demux->stream_start_time;
4373       GST_DEBUG_OBJECT (demux,
4374           "generated segment starting at %" GST_TIME_FORMAT ": %"
4375           GST_SEGMENT_FORMAT, GST_TIME_ARGS (lace_time), segment);
4376       /* now convey our segment notion downstream */
4377       segment_event = gst_event_new_segment (segment);
4378       if (demux->segment_seqnum)
4379         gst_event_set_seqnum (segment_event, demux->segment_seqnum);
4380       gst_matroska_demux_send_event (demux, segment_event);
4381       demux->need_segment = FALSE;
4382       demux->segment_seqnum = 0;
4383     }
4384 
4385     /* send pending codec data headers for all streams,
4386      * before we perform sync across all streams */
4387     gst_matroska_demux_push_codec_data_all (demux);
4388 
4389     if (block_duration != -1) {
4390       if (stream->timecodescale == 1.0)
4391         duration = gst_util_uint64_scale (block_duration,
4392             demux->common.time_scale, 1);
4393       else
4394         duration =
4395             gst_util_gdouble_to_guint64 (gst_util_guint64_to_gdouble
4396             (gst_util_uint64_scale (block_duration, demux->common.time_scale,
4397                     1)) * stream->timecodescale);
4398     } else if (stream->default_duration) {
4399       duration = stream->default_duration * laces;
4400     }
4401     /* else duration is diff between timecode of this and next block */
4402 
4403     if (stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
4404       /* For SimpleBlock, look at the keyframe bit in flags. Otherwise,
4405          a ReferenceBlock implies that this is not a keyframe. In either
4406          case, it only makes sense for video streams. */
4407       if ((is_simpleblock && !(flags & 0x80)) || referenceblock) {
4408         delta_unit = TRUE;
4409         invisible_frame = ((flags & 0x08)) &&
4410             (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8) ||
4411             !strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP9) ||
4412             !strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_VIDEO_AV1));
4413       }
4414 
4415       /* If we're doing a keyframe-only trickmode, only push keyframes on video
4416        * streams */
4417       if (delta_unit
4418           && demux->common.segment.
4419           flags & GST_SEGMENT_FLAG_TRICKMODE_KEY_UNITS) {
4420         GST_LOG_OBJECT (demux, "Skipping non-keyframe on stream %d",
4421             stream->index);
4422         ret = GST_FLOW_OK;
4423         goto done;
4424       }
4425     }
4426 
4427     for (n = 0; n < laces; n++) {
4428       GstBuffer *sub;
4429 
4430       if (G_UNLIKELY (lace_size[n] > size)) {
4431         GST_WARNING_OBJECT (demux, "Invalid lace size");
4432         break;
4433       }
4434 
4435       /* QoS for video track with an index. the assumption is that
4436          index entries point to keyframes, but if that is not true we
4437          will instad skip until the next keyframe. */
4438       if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
4439           stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
4440           stream->index_table && demux->common.segment.rate > 0.0) {
4441         GstMatroskaTrackVideoContext *videocontext =
4442             (GstMatroskaTrackVideoContext *) stream;
4443         GstClockTime earliest_time;
4444         GstClockTime earliest_stream_time;
4445 
4446         GST_OBJECT_LOCK (demux);
4447         earliest_time = videocontext->earliest_time;
4448         GST_OBJECT_UNLOCK (demux);
4449         earliest_stream_time =
4450             gst_segment_position_from_running_time (&demux->common.segment,
4451             GST_FORMAT_TIME, earliest_time);
4452 
4453         if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
4454             GST_CLOCK_TIME_IS_VALID (earliest_stream_time) &&
4455             lace_time <= earliest_stream_time) {
4456           /* find index entry (keyframe) <= earliest_stream_time */
4457           GstMatroskaIndex *entry =
4458               gst_util_array_binary_search (stream->index_table->data,
4459               stream->index_table->len, sizeof (GstMatroskaIndex),
4460               (GCompareDataFunc) gst_matroska_index_seek_find,
4461               GST_SEARCH_MODE_BEFORE, &earliest_stream_time, NULL);
4462 
4463           /* if that entry (keyframe) is after the current the current
4464              buffer, we can skip pushing (and thus decoding) all
4465              buffers until that keyframe. */
4466           if (entry && GST_CLOCK_TIME_IS_VALID (entry->time) &&
4467               entry->time > lace_time) {
4468             GST_LOG_OBJECT (demux, "Skipping lace before late keyframe");
4469             stream->set_discont = TRUE;
4470             goto next_lace;
4471           }
4472         }
4473       }
4474 
4475       sub = gst_buffer_copy_region (buf, GST_BUFFER_COPY_ALL,
4476           gst_buffer_get_size (buf) - size, lace_size[n]);
4477       GST_DEBUG_OBJECT (demux, "created subbuffer %p", sub);
4478 
4479       if (delta_unit)
4480         GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
4481       else
4482         GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
4483 
4484       if (invisible_frame)
4485         GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DECODE_ONLY);
4486 
4487       if (stream->encodings != NULL && stream->encodings->len > 0)
4488         sub = gst_matroska_decode_buffer (stream, sub);
4489 
4490       if (sub == NULL) {
4491         GST_WARNING_OBJECT (demux, "Decoding buffer failed");
4492         goto next_lace;
4493       }
4494 
4495       if (!stream->dts_only) {
4496         GST_BUFFER_PTS (sub) = lace_time;
4497       } else {
4498         GST_BUFFER_DTS (sub) = lace_time;
4499         if (stream->intra_only)
4500           GST_BUFFER_PTS (sub) = lace_time;
4501       }
4502 
4503       buffer_timestamp = gst_matroska_track_get_buffer_timestamp (stream, sub);
4504 
4505       if (GST_CLOCK_TIME_IS_VALID (lace_time)) {
4506         GstClockTime last_stop_end;
4507 
4508         /* Check if this stream is after segment stop */
4509         if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop) &&
4510             lace_time >= demux->common.segment.stop) {
4511           GST_DEBUG_OBJECT (demux,
4512               "Stream %d after segment stop %" GST_TIME_FORMAT, stream->index,
4513               GST_TIME_ARGS (demux->common.segment.stop));
4514           gst_buffer_unref (sub);
4515           goto eos;
4516         }
4517         if (offset >= stream->to_offset
4518             || (GST_CLOCK_TIME_IS_VALID (demux->to_time)
4519                 && lace_time > demux->to_time)) {
4520           GST_DEBUG_OBJECT (demux, "Stream %d after playback section",
4521               stream->index);
4522           gst_buffer_unref (sub);
4523           goto eos;
4524         }
4525 
4526         /* handle gaps, e.g. non-zero start-time, or an cue index entry
4527          * that landed us with timestamps not quite intended */
4528         GST_OBJECT_LOCK (demux);
4529         if (demux->max_gap_time &&
4530             GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) &&
4531             demux->common.segment.rate > 0.0) {
4532           GstClockTimeDiff diff;
4533 
4534           /* only send segments with increasing start times,
4535            * otherwise if these go back and forth downstream (sinks) increase
4536            * accumulated time and running_time */
4537           diff = GST_CLOCK_DIFF (demux->last_stop_end, lace_time);
4538           if (diff > 0 && diff > demux->max_gap_time
4539               && lace_time > demux->common.segment.start
4540               && (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop)
4541                   || lace_time < demux->common.segment.stop)) {
4542             GstEvent *event;
4543             GST_DEBUG_OBJECT (demux,
4544                 "Gap of %" G_GINT64_FORMAT " ns detected in"
4545                 "stream %d (%" GST_TIME_FORMAT " -> %" GST_TIME_FORMAT "). "
4546                 "Sending updated SEGMENT events", diff,
4547                 stream->index, GST_TIME_ARGS (stream->pos),
4548                 GST_TIME_ARGS (lace_time));
4549 
4550             event = gst_event_new_gap (demux->last_stop_end, diff);
4551             GST_OBJECT_UNLOCK (demux);
4552             gst_pad_push_event (stream->pad, event);
4553             GST_OBJECT_LOCK (demux);
4554           }
4555         }
4556 
4557         if (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.position)
4558             || demux->common.segment.position < lace_time) {
4559           demux->common.segment.position = lace_time;
4560         }
4561         GST_OBJECT_UNLOCK (demux);
4562 
4563         last_stop_end = lace_time;
4564         if (duration) {
4565           GST_BUFFER_DURATION (sub) = duration / laces;
4566           last_stop_end += GST_BUFFER_DURATION (sub);
4567         }
4568 
4569         if (!GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) ||
4570             demux->last_stop_end < last_stop_end)
4571           demux->last_stop_end = last_stop_end;
4572 
4573         GST_OBJECT_LOCK (demux);
4574         if (demux->common.segment.duration == -1 ||
4575             demux->stream_start_time + demux->common.segment.duration <
4576             last_stop_end) {
4577           demux->common.segment.duration =
4578               last_stop_end - demux->stream_start_time;
4579           GST_OBJECT_UNLOCK (demux);
4580           if (!demux->invalid_duration) {
4581             gst_element_post_message (GST_ELEMENT_CAST (demux),
4582                 gst_message_new_duration_changed (GST_OBJECT_CAST (demux)));
4583             demux->invalid_duration = TRUE;
4584           }
4585         } else {
4586           GST_OBJECT_UNLOCK (demux);
4587         }
4588       }
4589 
4590       stream->pos = lace_time;
4591 
4592       gst_matroska_demux_sync_streams (demux);
4593 
4594       if (stream->set_discont) {
4595         GST_DEBUG_OBJECT (demux, "marking DISCONT");
4596         GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DISCONT);
4597         stream->set_discont = FALSE;
4598       } else {
4599         GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DISCONT);
4600       }
4601 
4602       /* reverse playback book-keeping */
4603       if (!GST_CLOCK_TIME_IS_VALID (stream->from_time))
4604         stream->from_time = lace_time;
4605       if (stream->from_offset == -1)
4606         stream->from_offset = offset;
4607 
4608       GST_DEBUG_OBJECT (demux,
4609           "Pushing lace %d, data of size %" G_GSIZE_FORMAT
4610           " for stream %d, time=%" GST_TIME_FORMAT " and duration=%"
4611           GST_TIME_FORMAT, n, gst_buffer_get_size (sub), stream_num,
4612           GST_TIME_ARGS (buffer_timestamp),
4613           GST_TIME_ARGS (GST_BUFFER_DURATION (sub)));
4614 
4615 #if 0
4616       if (demux->common.element_index) {
4617         if (stream->index_writer_id == -1)
4618           gst_index_get_writer_id (demux->common.element_index,
4619               GST_OBJECT (stream->pad), &stream->index_writer_id);
4620 
4621         GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
4622             G_GUINT64_FORMAT " for writer id %d",
4623             GST_TIME_ARGS (buffer_timestamp), cluster_offset,
4624             stream->index_writer_id);
4625         gst_index_add_association (demux->common.element_index,
4626             stream->index_writer_id, GST_BUFFER_FLAG_IS_SET (sub,
4627                 GST_BUFFER_FLAG_DELTA_UNIT) ? 0 : GST_ASSOCIATION_FLAG_KEY_UNIT,
4628             GST_FORMAT_TIME, buffer_timestamp, GST_FORMAT_BYTES, cluster_offset,
4629             NULL);
4630       }
4631 #endif
4632 
4633       /* Postprocess the buffers depending on the codec used */
4634       if (stream->postprocess_frame) {
4635         GST_LOG_OBJECT (demux, "running post process");
4636         ret = stream->postprocess_frame (GST_ELEMENT (demux), stream, &sub);
4637       }
4638 
4639       /* At this point, we have a sub-buffer pointing at data within a larger
4640          buffer. This data might not be aligned with anything. If the data is
4641          raw samples though, we want it aligned to the raw type (eg, 4 bytes
4642          for 32 bit samples, etc), or bad things will happen downstream as
4643          elements typically assume minimal alignment.
4644          Therefore, create an aligned copy if necessary. */
4645       sub = gst_matroska_demux_align_buffer (demux, sub, stream->alignment);
4646 
4647       if (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_AUDIO_OPUS)) {
4648         guint64 start_clip = 0, end_clip = 0;
4649 
4650         /* Codec delay is part of the timestamps */
4651         if (GST_BUFFER_PTS_IS_VALID (sub) && stream->codec_delay) {
4652           if (GST_BUFFER_PTS (sub) > stream->codec_delay) {
4653             GST_BUFFER_PTS (sub) -= stream->codec_delay;
4654           } else {
4655             GST_BUFFER_PTS (sub) = 0;
4656 
4657             /* Opus GstAudioClippingMeta units are scaled by 48000/sample_rate.
4658                That is, if a Opus track has audio encoded at 24000 Hz and 132
4659                samples need to be clipped, GstAudioClippingMeta.start will be
4660                set to 264. (This is also the case for buffer offsets.)
4661                Opus sample rates are always divisors of 48000 Hz, which is the
4662                maximum allowed sample rate. */
4663             start_clip =
4664                 gst_util_uint64_scale_round (stream->codec_delay, 48000,
4665                 GST_SECOND);
4666 
4667             if (GST_BUFFER_DURATION_IS_VALID (sub)) {
4668               if (GST_BUFFER_DURATION (sub) > stream->codec_delay)
4669                 GST_BUFFER_DURATION (sub) -= stream->codec_delay;
4670               else
4671                 GST_BUFFER_DURATION (sub) = 0;
4672             }
4673           }
4674         }
4675 
4676         if (block_discardpadding) {
4677           end_clip =
4678               gst_util_uint64_scale_round (block_discardpadding, 48000,
4679               GST_SECOND);
4680         }
4681 
4682         if (start_clip || end_clip) {
4683           gst_buffer_add_audio_clipping_meta (sub, GST_FORMAT_DEFAULT,
4684               start_clip, end_clip);
4685         }
4686       }
4687 
4688       if (GST_BUFFER_PTS_IS_VALID (sub)) {
4689         stream->pos = GST_BUFFER_PTS (sub);
4690         if (GST_BUFFER_DURATION_IS_VALID (sub))
4691           stream->pos += GST_BUFFER_DURATION (sub);
4692       } else if (GST_BUFFER_DTS_IS_VALID (sub)) {
4693         stream->pos = GST_BUFFER_DTS (sub);
4694         if (GST_BUFFER_DURATION_IS_VALID (sub))
4695           stream->pos += GST_BUFFER_DURATION (sub);
4696       }
4697 
4698       ret = gst_pad_push (stream->pad, sub);
4699 
4700       if (demux->common.segment.rate < 0) {
4701         if (lace_time > demux->common.segment.stop && ret == GST_FLOW_EOS) {
4702           /* In reverse playback we can get a GST_FLOW_EOS when
4703            * we are at the end of the segment, so we just need to jump
4704            * back to the previous section. */
4705           GST_DEBUG_OBJECT (demux, "downstream has reached end of segment");
4706           ret = GST_FLOW_OK;
4707         }
4708       }
4709       /* combine flows */
4710       ret = gst_flow_combiner_update_pad_flow (demux->flowcombiner,
4711           stream->pad, ret);
4712 
4713     next_lace:
4714       size -= lace_size[n];
4715       if (lace_time != GST_CLOCK_TIME_NONE && duration)
4716         lace_time += duration / laces;
4717       else
4718         lace_time = GST_CLOCK_TIME_NONE;
4719     }
4720   }
4721 
4722 done:
4723   if (buf) {
4724     gst_buffer_unmap (buf, &map);
4725     gst_buffer_unref (buf);
4726   }
4727   g_free (lace_size);
4728 
4729   return ret;
4730 
4731   /* EXITS */
4732 eos:
4733   {
4734     stream->eos = TRUE;
4735     ret = GST_FLOW_OK;
4736     /* combine flows */
4737     ret = gst_flow_combiner_update_pad_flow (demux->flowcombiner, stream->pad,
4738         ret);
4739     goto done;
4740   }
4741 invalid_lacing:
4742   {
4743     GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Invalid lacing size"));
4744     /* non-fatal, try next block(group) */
4745     ret = GST_FLOW_OK;
4746     goto done;
4747   }
4748 data_error:
4749   {
4750     GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Data error"));
4751     /* non-fatal, try next block(group) */
4752     ret = GST_FLOW_OK;
4753     goto done;
4754   }
4755 }
4756 
4757 /* return FALSE if block(group) should be skipped (due to a seek) */
4758 static inline gboolean
gst_matroska_demux_seek_block(GstMatroskaDemux * demux)4759 gst_matroska_demux_seek_block (GstMatroskaDemux * demux)
4760 {
4761   if (G_UNLIKELY (demux->seek_block)) {
4762     if (!(--demux->seek_block)) {
4763       return TRUE;
4764     } else {
4765       GST_LOG_OBJECT (demux, "should skip block due to seek");
4766       return FALSE;
4767     }
4768   } else {
4769     return TRUE;
4770   }
4771 }
4772 
4773 static GstFlowReturn
gst_matroska_demux_parse_contents_seekentry(GstMatroskaDemux * demux,GstEbmlRead * ebml)4774 gst_matroska_demux_parse_contents_seekentry (GstMatroskaDemux * demux,
4775     GstEbmlRead * ebml)
4776 {
4777   GstFlowReturn ret;
4778   guint64 seek_pos = (guint64) - 1;
4779   guint32 seek_id = 0;
4780   guint32 id;
4781 
4782   DEBUG_ELEMENT_START (demux, ebml, "Seek");
4783 
4784   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
4785     DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
4786     return ret;
4787   }
4788 
4789   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
4790     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
4791       break;
4792 
4793     switch (id) {
4794       case GST_MATROSKA_ID_SEEKID:
4795       {
4796         guint64 t;
4797 
4798         if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
4799           break;
4800 
4801         GST_DEBUG_OBJECT (demux, "SeekID: %" G_GUINT64_FORMAT, t);
4802         seek_id = t;
4803         break;
4804       }
4805 
4806       case GST_MATROSKA_ID_SEEKPOSITION:
4807       {
4808         guint64 t;
4809 
4810         if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
4811           break;
4812 
4813         if (t > G_MAXINT64) {
4814           GST_WARNING_OBJECT (demux,
4815               "Too large SeekPosition %" G_GUINT64_FORMAT, t);
4816           break;
4817         }
4818 
4819         GST_DEBUG_OBJECT (demux, "SeekPosition: %" G_GUINT64_FORMAT, t);
4820         seek_pos = t;
4821         break;
4822       }
4823 
4824       default:
4825         ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
4826             "SeekHead", id);
4827         break;
4828     }
4829   }
4830 
4831   if (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)
4832     return ret;
4833 
4834   if (!seek_id || seek_pos == (guint64) - 1) {
4835     GST_WARNING_OBJECT (demux, "Incomplete seekhead entry (0x%x/%"
4836         G_GUINT64_FORMAT ")", seek_id, seek_pos);
4837     return GST_FLOW_OK;
4838   }
4839 
4840   switch (seek_id) {
4841     case GST_MATROSKA_ID_SEEKHEAD:
4842     {
4843     }
4844     case GST_MATROSKA_ID_CUES:
4845     case GST_MATROSKA_ID_TAGS:
4846     case GST_MATROSKA_ID_TRACKS:
4847     case GST_MATROSKA_ID_SEGMENTINFO:
4848     case GST_MATROSKA_ID_ATTACHMENTS:
4849     case GST_MATROSKA_ID_CHAPTERS:
4850     {
4851       guint64 before_pos, length;
4852       guint needed;
4853 
4854       /* remember */
4855       length = gst_matroska_read_common_get_length (&demux->common);
4856       before_pos = demux->common.offset;
4857 
4858       if (length == (guint64) - 1) {
4859         GST_DEBUG_OBJECT (demux, "no upstream length, skipping SeakHead entry");
4860         break;
4861       }
4862 
4863       /* check for validity */
4864       if (seek_pos + demux->common.ebml_segment_start + 12 >= length) {
4865         GST_WARNING_OBJECT (demux,
4866             "SeekHead reference lies outside file!" " (%"
4867             G_GUINT64_FORMAT "+%" G_GUINT64_FORMAT "+12 >= %"
4868             G_GUINT64_FORMAT ")", seek_pos, demux->common.ebml_segment_start,
4869             length);
4870         break;
4871       }
4872 
4873       /* only pick up index location when streaming */
4874       if (demux->streaming) {
4875         if (seek_id == GST_MATROSKA_ID_CUES) {
4876           demux->index_offset = seek_pos + demux->common.ebml_segment_start;
4877           GST_DEBUG_OBJECT (demux, "Cues located at offset %" G_GUINT64_FORMAT,
4878               demux->index_offset);
4879         }
4880         break;
4881       }
4882 
4883       /* seek */
4884       demux->common.offset = seek_pos + demux->common.ebml_segment_start;
4885 
4886       /* check ID */
4887       if ((ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4888                   GST_ELEMENT_CAST (demux), &id, &length, &needed)) !=
4889           GST_FLOW_OK)
4890         goto finish;
4891 
4892       if (id != seek_id) {
4893         GST_WARNING_OBJECT (demux,
4894             "We looked for ID=0x%x but got ID=0x%x (pos=%" G_GUINT64_FORMAT ")",
4895             seek_id, id, seek_pos + demux->common.ebml_segment_start);
4896       } else {
4897         /* now parse */
4898         ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4899       }
4900 
4901     finish:
4902       /* seek back */
4903       demux->common.offset = before_pos;
4904       break;
4905     }
4906 
4907     case GST_MATROSKA_ID_CLUSTER:
4908     {
4909       guint64 pos = seek_pos + demux->common.ebml_segment_start;
4910 
4911       GST_LOG_OBJECT (demux, "Cluster position");
4912       if (G_UNLIKELY (!demux->clusters))
4913         demux->clusters = g_array_sized_new (TRUE, TRUE, sizeof (guint64), 100);
4914       g_array_append_val (demux->clusters, pos);
4915       break;
4916     }
4917 
4918     default:
4919       GST_DEBUG_OBJECT (demux, "Ignoring Seek entry for ID=0x%x", seek_id);
4920       break;
4921   }
4922   DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
4923 
4924   return ret;
4925 }
4926 
4927 static GstFlowReturn
gst_matroska_demux_parse_contents(GstMatroskaDemux * demux,GstEbmlRead * ebml)4928 gst_matroska_demux_parse_contents (GstMatroskaDemux * demux, GstEbmlRead * ebml)
4929 {
4930   GstFlowReturn ret = GST_FLOW_OK;
4931   guint32 id;
4932 
4933   DEBUG_ELEMENT_START (demux, ebml, "SeekHead");
4934 
4935   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
4936     DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
4937     return ret;
4938   }
4939 
4940   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
4941     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
4942       break;
4943 
4944     switch (id) {
4945       case GST_MATROSKA_ID_SEEKENTRY:
4946       {
4947         ret = gst_matroska_demux_parse_contents_seekentry (demux, ebml);
4948         /* Ignore EOS and errors here */
4949         if (ret != GST_FLOW_OK) {
4950           GST_DEBUG_OBJECT (demux, "Ignoring %s", gst_flow_get_name (ret));
4951           ret = GST_FLOW_OK;
4952         }
4953         break;
4954       }
4955 
4956       default:
4957         ret = gst_matroska_read_common_parse_skip (&demux->common,
4958             ebml, "SeekHead", id);
4959         break;
4960     }
4961   }
4962 
4963   DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
4964 
4965   /* Sort clusters by position for easier searching */
4966   if (demux->clusters)
4967     g_array_sort (demux->clusters, (GCompareFunc) gst_matroska_cluster_compare);
4968 
4969   return ret;
4970 }
4971 
4972 #define GST_FLOW_OVERFLOW   GST_FLOW_CUSTOM_ERROR
4973 
4974 #define MAX_BLOCK_SIZE (15 * 1024 * 1024)
4975 
4976 static inline GstFlowReturn
gst_matroska_demux_check_read_size(GstMatroskaDemux * demux,guint64 bytes)4977 gst_matroska_demux_check_read_size (GstMatroskaDemux * demux, guint64 bytes)
4978 {
4979   if (G_UNLIKELY (bytes > MAX_BLOCK_SIZE)) {
4980     /* only a few blocks are expected/allowed to be large,
4981      * and will be recursed into, whereas others will be read and must fit */
4982     if (demux->streaming) {
4983       /* fatal in streaming case, as we can't step over easily */
4984       GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4985           ("reading large block of size %" G_GUINT64_FORMAT " not supported; "
4986               "file might be corrupt.", bytes));
4987       return GST_FLOW_ERROR;
4988     } else {
4989       /* indicate higher level to quietly give up */
4990       GST_DEBUG_OBJECT (demux,
4991           "too large block of size %" G_GUINT64_FORMAT, bytes);
4992       return GST_FLOW_ERROR;
4993     }
4994   } else {
4995     return GST_FLOW_OK;
4996   }
4997 }
4998 
4999 /* returns TRUE if we truely are in error state, and should give up */
5000 static inline GstFlowReturn
gst_matroska_demux_check_parse_error(GstMatroskaDemux * demux)5001 gst_matroska_demux_check_parse_error (GstMatroskaDemux * demux)
5002 {
5003   if (!demux->streaming && demux->next_cluster_offset > 0) {
5004     /* just repositioning to where next cluster should be and try from there */
5005     GST_WARNING_OBJECT (demux, "parse error, trying next cluster expected at %"
5006         G_GUINT64_FORMAT, demux->next_cluster_offset);
5007     demux->common.offset = demux->next_cluster_offset;
5008     demux->next_cluster_offset = 0;
5009     return GST_FLOW_OK;
5010   } else {
5011     gint64 pos;
5012     GstFlowReturn ret;
5013 
5014     /* sigh, one last attempt above and beyond call of duty ...;
5015      * search for cluster mark following current pos */
5016     pos = demux->common.offset;
5017     GST_WARNING_OBJECT (demux, "parse error, looking for next cluster");
5018     if ((ret = gst_matroska_demux_search_cluster (demux, &pos, TRUE)) !=
5019         GST_FLOW_OK) {
5020       /* did not work, give up */
5021       return ret;
5022     } else {
5023       GST_DEBUG_OBJECT (demux, "... found at  %" G_GUINT64_FORMAT, pos);
5024       /* try that position */
5025       demux->common.offset = pos;
5026       return GST_FLOW_OK;
5027     }
5028   }
5029 }
5030 
5031 static inline GstFlowReturn
gst_matroska_demux_flush(GstMatroskaDemux * demux,guint flush)5032 gst_matroska_demux_flush (GstMatroskaDemux * demux, guint flush)
5033 {
5034   GST_LOG_OBJECT (demux, "skipping %d bytes", flush);
5035   demux->common.offset += flush;
5036   if (demux->streaming) {
5037     GstFlowReturn ret;
5038 
5039     /* hard to skip large blocks when streaming */
5040     ret = gst_matroska_demux_check_read_size (demux, flush);
5041     if (ret != GST_FLOW_OK)
5042       return ret;
5043     if (flush <= gst_adapter_available (demux->common.adapter))
5044       gst_adapter_flush (demux->common.adapter, flush);
5045     else
5046       return GST_FLOW_EOS;
5047   }
5048   return GST_FLOW_OK;
5049 }
5050 
5051 /* initializes @ebml with @bytes from input stream at current offset.
5052  * Returns EOS if insufficient available,
5053  * ERROR if too much was attempted to read. */
5054 static inline GstFlowReturn
gst_matroska_demux_take(GstMatroskaDemux * demux,guint64 bytes,GstEbmlRead * ebml)5055 gst_matroska_demux_take (GstMatroskaDemux * demux, guint64 bytes,
5056     GstEbmlRead * ebml)
5057 {
5058   GstBuffer *buffer = NULL;
5059   GstFlowReturn ret = GST_FLOW_OK;
5060 
5061   GST_LOG_OBJECT (demux, "taking %" G_GUINT64_FORMAT " bytes for parsing",
5062       bytes);
5063   ret = gst_matroska_demux_check_read_size (demux, bytes);
5064   if (G_UNLIKELY (ret != GST_FLOW_OK)) {
5065     if (!demux->streaming) {
5066       /* in pull mode, we can skip */
5067       if ((ret = gst_matroska_demux_flush (demux, bytes)) == GST_FLOW_OK)
5068         ret = GST_FLOW_OVERFLOW;
5069     } else {
5070       /* otherwise fatal */
5071       ret = GST_FLOW_ERROR;
5072     }
5073     goto exit;
5074   }
5075   if (demux->streaming) {
5076     if (gst_adapter_available (demux->common.adapter) >= bytes)
5077       buffer = gst_adapter_take_buffer (demux->common.adapter, bytes);
5078     else
5079       ret = GST_FLOW_EOS;
5080   } else
5081     ret = gst_matroska_read_common_peek_bytes (&demux->common,
5082         demux->common.offset, bytes, &buffer, NULL);
5083   if (G_LIKELY (buffer)) {
5084     gst_ebml_read_init (ebml, GST_ELEMENT_CAST (demux), buffer,
5085         demux->common.offset);
5086     demux->common.offset += bytes;
5087   }
5088 exit:
5089   return ret;
5090 }
5091 
5092 static void
gst_matroska_demux_check_seekability(GstMatroskaDemux * demux)5093 gst_matroska_demux_check_seekability (GstMatroskaDemux * demux)
5094 {
5095   GstQuery *query;
5096   gboolean seekable = FALSE;
5097   gint64 start = -1, stop = -1;
5098 
5099   query = gst_query_new_seeking (GST_FORMAT_BYTES);
5100   if (!gst_pad_peer_query (demux->common.sinkpad, query)) {
5101     GST_DEBUG_OBJECT (demux, "seeking query failed");
5102     goto done;
5103   }
5104 
5105   gst_query_parse_seeking (query, NULL, &seekable, &start, &stop);
5106 
5107   /* try harder to query upstream size if we didn't get it the first time */
5108   if (seekable && stop == -1) {
5109     GST_DEBUG_OBJECT (demux, "doing duration query to fix up unset stop");
5110     gst_pad_peer_query_duration (demux->common.sinkpad, GST_FORMAT_BYTES,
5111         &stop);
5112   }
5113 
5114   /* if upstream doesn't know the size, it's likely that it's not seekable in
5115    * practice even if it technically may be seekable */
5116   if (seekable && (start != 0 || stop <= start)) {
5117     GST_DEBUG_OBJECT (demux, "seekable but unknown start/stop -> disable");
5118     seekable = FALSE;
5119   }
5120 
5121 done:
5122   GST_INFO_OBJECT (demux, "seekable: %d (%" G_GUINT64_FORMAT " - %"
5123       G_GUINT64_FORMAT ")", seekable, start, stop);
5124   demux->seekable = seekable;
5125 
5126   gst_query_unref (query);
5127 }
5128 
5129 static GstFlowReturn
gst_matroska_demux_find_tracks(GstMatroskaDemux * demux)5130 gst_matroska_demux_find_tracks (GstMatroskaDemux * demux)
5131 {
5132   guint32 id;
5133   guint64 before_pos;
5134   guint64 length;
5135   guint needed;
5136   GstFlowReturn ret = GST_FLOW_OK;
5137 
5138   GST_WARNING_OBJECT (demux,
5139       "Found Cluster element before Tracks, searching Tracks");
5140 
5141   /* remember */
5142   before_pos = demux->common.offset;
5143 
5144   /* Search Tracks element */
5145   while (TRUE) {
5146     ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
5147         GST_ELEMENT_CAST (demux), &id, &length, &needed);
5148     if (ret != GST_FLOW_OK)
5149       break;
5150 
5151     if (id != GST_MATROSKA_ID_TRACKS) {
5152       /* we may be skipping large cluster here, so forego size check etc */
5153       /* ... but we can't skip undefined size; force error */
5154       if (length == G_MAXUINT64) {
5155         ret = gst_matroska_demux_check_read_size (demux, length);
5156         break;
5157       } else {
5158         demux->common.offset += needed;
5159         demux->common.offset += length;
5160       }
5161       continue;
5162     }
5163 
5164     /* will lead to track parsing ... */
5165     ret = gst_matroska_demux_parse_id (demux, id, length, needed);
5166     break;
5167   }
5168 
5169   /* seek back */
5170   demux->common.offset = before_pos;
5171 
5172   return ret;
5173 }
5174 
5175 #define GST_READ_CHECK(stmt)  \
5176 G_STMT_START { \
5177   if (G_UNLIKELY ((ret = (stmt)) != GST_FLOW_OK)) { \
5178     if (ret == GST_FLOW_OVERFLOW) { \
5179       ret = GST_FLOW_OK; \
5180     } \
5181     goto read_error; \
5182   } \
5183 } G_STMT_END
5184 
5185 static GstFlowReturn
gst_matroska_demux_parse_id(GstMatroskaDemux * demux,guint32 id,guint64 length,guint needed)5186 gst_matroska_demux_parse_id (GstMatroskaDemux * demux, guint32 id,
5187     guint64 length, guint needed)
5188 {
5189   GstEbmlRead ebml = { 0, };
5190   GstFlowReturn ret = GST_FLOW_OK;
5191   guint64 read;
5192 
5193   GST_LOG_OBJECT (demux, "Parsing Element id 0x%x, "
5194       "size %" G_GUINT64_FORMAT ", prefix %d", id, length, needed);
5195 
5196   /* if we plan to read and parse this element, we need prefix (id + length)
5197    * and the contents */
5198   /* mind about overflow wrap-around when dealing with undefined size */
5199   read = length;
5200   if (G_LIKELY (length != G_MAXUINT64))
5201     read += needed;
5202 
5203   switch (demux->common.state) {
5204     case GST_MATROSKA_READ_STATE_START:
5205       switch (id) {
5206         case GST_EBML_ID_HEADER:
5207           GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5208           ret = gst_matroska_read_common_parse_header (&demux->common, &ebml);
5209           if (ret != GST_FLOW_OK)
5210             goto parse_failed;
5211           demux->common.state = GST_MATROSKA_READ_STATE_SEGMENT;
5212           gst_matroska_demux_check_seekability (demux);
5213           break;
5214         default:
5215           goto invalid_header;
5216           break;
5217       }
5218       break;
5219     case GST_MATROSKA_READ_STATE_SEGMENT:
5220       switch (id) {
5221         case GST_MATROSKA_ID_SEGMENT:
5222           /* eat segment prefix */
5223           GST_READ_CHECK (gst_matroska_demux_flush (demux, needed));
5224           GST_DEBUG_OBJECT (demux,
5225               "Found Segment start at offset %" G_GUINT64_FORMAT " with size %"
5226               G_GUINT64_FORMAT, demux->common.offset, length);
5227           /* seeks are from the beginning of the segment,
5228            * after the segment ID/length */
5229           demux->common.ebml_segment_start = demux->common.offset;
5230           if (length == 0)
5231             length = G_MAXUINT64;
5232           demux->common.ebml_segment_length = length;
5233           demux->common.state = GST_MATROSKA_READ_STATE_HEADER;
5234           break;
5235         default:
5236           GST_WARNING_OBJECT (demux,
5237               "Expected a Segment ID (0x%x), but received 0x%x!",
5238               GST_MATROSKA_ID_SEGMENT, id);
5239           GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
5240           break;
5241       }
5242       break;
5243     case GST_MATROSKA_READ_STATE_SCANNING:
5244       if (id != GST_MATROSKA_ID_CLUSTER &&
5245           id != GST_MATROSKA_ID_PREVSIZE &&
5246           id != GST_MATROSKA_ID_CLUSTERTIMECODE) {
5247         if (demux->common.start_resync_offset != -1) {
5248           /* we need to skip byte per byte if we are scanning for a new cluster
5249            * after invalid data is found
5250            */
5251           read = 1;
5252         }
5253         goto skip;
5254       } else {
5255         if (demux->common.start_resync_offset != -1) {
5256           GST_LOG_OBJECT (demux, "Resync done, new cluster found!");
5257           demux->common.start_resync_offset = -1;
5258           demux->common.state = demux->common.state_to_restore;
5259         }
5260       }
5261       /* fall-through */
5262     case GST_MATROSKA_READ_STATE_HEADER:
5263     case GST_MATROSKA_READ_STATE_DATA:
5264     case GST_MATROSKA_READ_STATE_SEEK:
5265       switch (id) {
5266         case GST_EBML_ID_HEADER:
5267           GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
5268           demux->common.state = GST_MATROSKA_READ_STATE_SEGMENT;
5269           gst_matroska_demux_check_seekability (demux);
5270           break;
5271         case GST_MATROSKA_ID_SEGMENTINFO:
5272           if (!demux->common.segmentinfo_parsed) {
5273             GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5274             ret = gst_matroska_read_common_parse_info (&demux->common,
5275                 GST_ELEMENT_CAST (demux), &ebml);
5276             if (ret == GST_FLOW_OK)
5277               gst_matroska_demux_send_tags (demux);
5278           } else {
5279             GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
5280           }
5281           break;
5282         case GST_MATROSKA_ID_TRACKS:
5283           GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5284           if (!demux->tracks_parsed) {
5285             ret = gst_matroska_demux_parse_tracks (demux, &ebml);
5286           } else {
5287             ret = gst_matroska_demux_update_tracks (demux, &ebml);
5288           }
5289           break;
5290         case GST_MATROSKA_ID_CLUSTER:
5291           if (G_UNLIKELY (!demux->tracks_parsed)) {
5292             if (demux->streaming) {
5293               GST_DEBUG_OBJECT (demux, "Cluster before Track");
5294               goto not_streamable;
5295             } else {
5296               ret = gst_matroska_demux_find_tracks (demux);
5297               if (!demux->tracks_parsed)
5298                 goto no_tracks;
5299             }
5300           }
5301           if (demux->common.state == GST_MATROSKA_READ_STATE_HEADER) {
5302             demux->common.state = GST_MATROSKA_READ_STATE_DATA;
5303             demux->first_cluster_offset = demux->common.offset;
5304 
5305             if (!demux->streaming &&
5306                 !GST_CLOCK_TIME_IS_VALID (demux->common.segment.duration)) {
5307               GstMatroskaIndex *last = NULL;
5308 
5309               GST_DEBUG_OBJECT (demux,
5310                   "estimating duration using last cluster");
5311               if ((last = gst_matroska_demux_search_pos (demux,
5312                           GST_CLOCK_TIME_NONE)) != NULL) {
5313                 demux->last_cluster_offset =
5314                     last->pos + demux->common.ebml_segment_start;
5315                 demux->stream_last_time = last->time;
5316                 demux->common.segment.duration =
5317                     demux->stream_last_time - demux->stream_start_time;
5318                 /* above estimate should not be taken all too strongly */
5319                 demux->invalid_duration = TRUE;
5320                 GST_DEBUG_OBJECT (demux,
5321                     "estimated duration as %" GST_TIME_FORMAT,
5322                     GST_TIME_ARGS (demux->common.segment.duration));
5323 
5324                 g_free (last);
5325               }
5326             }
5327 
5328             /* Peek at second cluster in order to figure out if we have cluster
5329              * prev_size or not (which is never set on the first cluster for
5330              * obvious reasons). This is useful in case someone initiates a
5331              * seek or direction change before we reach the second cluster. */
5332             if (!demux->streaming) {
5333               ClusterInfo cluster = { 0, };
5334 
5335               if (gst_matroska_demux_peek_cluster_info (demux, &cluster,
5336                       demux->first_cluster_offset) && cluster.size > 0) {
5337                 gst_matroska_demux_peek_cluster_info (demux, &cluster,
5338                     demux->first_cluster_offset + cluster.size);
5339               }
5340               demux->common.offset = demux->first_cluster_offset;
5341             }
5342 
5343             if (demux->deferred_seek_event) {
5344               GstEvent *seek_event;
5345               GstPad *seek_pad;
5346               seek_event = demux->deferred_seek_event;
5347               seek_pad = demux->deferred_seek_pad;
5348               demux->deferred_seek_event = NULL;
5349               demux->deferred_seek_pad = NULL;
5350               GST_DEBUG_OBJECT (demux,
5351                   "Handling deferred seek event: %" GST_PTR_FORMAT, seek_event);
5352               gst_matroska_demux_handle_seek_event (demux, seek_pad,
5353                   seek_event);
5354               gst_event_unref (seek_event);
5355             }
5356 
5357             /* send initial segment - we wait till we know the first
5358                incoming timestamp, so we can properly set the start of
5359                the segment. */
5360             demux->need_segment = TRUE;
5361           }
5362           demux->cluster_time = GST_CLOCK_TIME_NONE;
5363           demux->cluster_offset = demux->common.offset;
5364           demux->cluster_prevsize = 0;
5365           if (G_UNLIKELY (!demux->seek_first && demux->seek_block)) {
5366             GST_DEBUG_OBJECT (demux, "seek target block %" G_GUINT64_FORMAT
5367                 " not found in Cluster, trying next Cluster's first block instead",
5368                 demux->seek_block);
5369             demux->seek_block = 0;
5370           }
5371           demux->seek_first = FALSE;
5372           /* record next cluster for recovery */
5373           if (read != G_MAXUINT64)
5374             demux->next_cluster_offset = demux->cluster_offset + read;
5375           /* eat cluster prefix */
5376           gst_matroska_demux_flush (demux, needed);
5377           break;
5378         case GST_MATROSKA_ID_CLUSTERTIMECODE:
5379         {
5380           guint64 num;
5381 
5382           GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5383           if ((ret = gst_ebml_read_uint (&ebml, &id, &num)) != GST_FLOW_OK)
5384             goto parse_failed;
5385           GST_DEBUG_OBJECT (demux, "ClusterTimeCode: %" G_GUINT64_FORMAT, num);
5386           demux->cluster_time = num;
5387           /* track last cluster */
5388           if (demux->cluster_offset > demux->last_cluster_offset) {
5389             demux->last_cluster_offset = demux->cluster_offset;
5390             demux->stream_last_time =
5391                 demux->cluster_time * demux->common.time_scale;
5392           }
5393 #if 0
5394           if (demux->common.element_index) {
5395             if (demux->common.element_index_writer_id == -1)
5396               gst_index_get_writer_id (demux->common.element_index,
5397                   GST_OBJECT (demux), &demux->common.element_index_writer_id);
5398             GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
5399                 G_GUINT64_FORMAT " for writer id %d",
5400                 GST_TIME_ARGS (demux->cluster_time), demux->cluster_offset,
5401                 demux->common.element_index_writer_id);
5402             gst_index_add_association (demux->common.element_index,
5403                 demux->common.element_index_writer_id,
5404                 GST_ASSOCIATION_FLAG_KEY_UNIT,
5405                 GST_FORMAT_TIME, demux->cluster_time,
5406                 GST_FORMAT_BYTES, demux->cluster_offset, NULL);
5407           }
5408 #endif
5409           break;
5410         }
5411         case GST_MATROSKA_ID_BLOCKGROUP:
5412           if (!gst_matroska_demux_seek_block (demux))
5413             goto skip;
5414           GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5415           DEBUG_ELEMENT_START (demux, &ebml, "BlockGroup");
5416           if ((ret = gst_ebml_read_master (&ebml, &id)) == GST_FLOW_OK) {
5417             ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
5418                 &ebml, demux->cluster_time, demux->cluster_offset, FALSE);
5419           }
5420           DEBUG_ELEMENT_STOP (demux, &ebml, "BlockGroup", ret);
5421           break;
5422         case GST_MATROSKA_ID_SIMPLEBLOCK:
5423           if (!gst_matroska_demux_seek_block (demux))
5424             goto skip;
5425           GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5426           DEBUG_ELEMENT_START (demux, &ebml, "SimpleBlock");
5427           ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
5428               &ebml, demux->cluster_time, demux->cluster_offset, TRUE);
5429           DEBUG_ELEMENT_STOP (demux, &ebml, "SimpleBlock", ret);
5430           break;
5431         case GST_MATROSKA_ID_ATTACHMENTS:
5432           if (!demux->common.attachments_parsed) {
5433             GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5434             ret = gst_matroska_read_common_parse_attachments (&demux->common,
5435                 GST_ELEMENT_CAST (demux), &ebml);
5436             if (ret == GST_FLOW_OK)
5437               gst_matroska_demux_send_tags (demux);
5438           } else {
5439             GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
5440           }
5441           break;
5442         case GST_MATROSKA_ID_TAGS:
5443           GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5444           ret = gst_matroska_read_common_parse_metadata (&demux->common,
5445               GST_ELEMENT_CAST (demux), &ebml);
5446           if (ret == GST_FLOW_OK)
5447             gst_matroska_demux_send_tags (demux);
5448           break;
5449         case GST_MATROSKA_ID_CHAPTERS:
5450           if (!demux->common.chapters_parsed) {
5451             GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5452             ret =
5453                 gst_matroska_read_common_parse_chapters (&demux->common, &ebml);
5454 
5455             if (demux->common.toc) {
5456               gst_matroska_demux_send_event (demux,
5457                   gst_event_new_toc (demux->common.toc, FALSE));
5458             }
5459           } else
5460             GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
5461           break;
5462         case GST_MATROSKA_ID_SEEKHEAD:
5463           GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5464           ret = gst_matroska_demux_parse_contents (demux, &ebml);
5465           break;
5466         case GST_MATROSKA_ID_CUES:
5467           if (demux->common.index_parsed) {
5468             GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
5469             break;
5470           }
5471           GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5472           ret = gst_matroska_read_common_parse_index (&demux->common, &ebml);
5473           /* only push based; delayed index building */
5474           if (ret == GST_FLOW_OK
5475               && demux->common.state == GST_MATROSKA_READ_STATE_SEEK) {
5476             GstEvent *event;
5477 
5478             GST_OBJECT_LOCK (demux);
5479             event = demux->seek_event;
5480             demux->seek_event = NULL;
5481             GST_OBJECT_UNLOCK (demux);
5482 
5483             g_assert (event);
5484             /* unlikely to fail, since we managed to seek to this point */
5485             if (!gst_matroska_demux_handle_seek_event (demux, NULL, event)) {
5486               gst_event_unref (event);
5487               goto seek_failed;
5488             }
5489             gst_event_unref (event);
5490             /* resume data handling, main thread clear to seek again */
5491             GST_OBJECT_LOCK (demux);
5492             demux->common.state = GST_MATROSKA_READ_STATE_DATA;
5493             GST_OBJECT_UNLOCK (demux);
5494           }
5495           break;
5496         case GST_MATROSKA_ID_PREVSIZE:{
5497           guint64 num;
5498 
5499           GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5500           if ((ret = gst_ebml_read_uint (&ebml, &id, &num)) != GST_FLOW_OK)
5501             goto parse_failed;
5502           GST_LOG_OBJECT (demux, "ClusterPrevSize: %" G_GUINT64_FORMAT, num);
5503           demux->cluster_prevsize = num;
5504           demux->seen_cluster_prevsize = TRUE;
5505           break;
5506         }
5507         case GST_MATROSKA_ID_POSITION:
5508         case GST_MATROSKA_ID_ENCRYPTEDBLOCK:
5509           /* The WebM doesn't support the EncryptedBlock element.
5510            * The Matroska spec doesn't give us more detail, how to parse this element,
5511            * for example the field TransformID isn't specified yet.*/
5512         case GST_MATROSKA_ID_SILENTTRACKS:
5513           GST_DEBUG_OBJECT (demux,
5514               "Skipping Cluster subelement 0x%x - ignoring", id);
5515           /* fall-through */
5516         default:
5517         skip:
5518           GST_DEBUG_OBJECT (demux, "skipping Element 0x%x", id);
5519           GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
5520           break;
5521       }
5522       break;
5523   }
5524 
5525   if (ret == GST_FLOW_PARSE)
5526     goto parse_failed;
5527 
5528 exit:
5529   gst_ebml_read_clear (&ebml);
5530   return ret;
5531 
5532   /* ERRORS */
5533 read_error:
5534   {
5535     /* simply exit, maybe not enough data yet */
5536     /* no ebml to clear if read error */
5537     return ret;
5538   }
5539 parse_failed:
5540   {
5541     GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
5542         ("Failed to parse Element 0x%x", id));
5543     ret = GST_FLOW_ERROR;
5544     goto exit;
5545   }
5546 not_streamable:
5547   {
5548     GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
5549         ("File layout does not permit streaming"));
5550     ret = GST_FLOW_ERROR;
5551     goto exit;
5552   }
5553 no_tracks:
5554   {
5555     GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
5556         ("No Tracks element found"));
5557     ret = GST_FLOW_ERROR;
5558     goto exit;
5559   }
5560 invalid_header:
5561   {
5562     GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Invalid header"));
5563     ret = GST_FLOW_ERROR;
5564     goto exit;
5565   }
5566 seek_failed:
5567   {
5568     GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Failed to seek"));
5569     ret = GST_FLOW_ERROR;
5570     goto exit;
5571   }
5572 }
5573 
5574 static void
gst_matroska_demux_loop(GstPad * pad)5575 gst_matroska_demux_loop (GstPad * pad)
5576 {
5577   GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (pad));
5578   GstFlowReturn ret;
5579   guint32 id;
5580   guint64 length;
5581   guint needed;
5582 
5583   /* If we have to close a segment, send a new segment to do this now */
5584   if (G_LIKELY (demux->common.state == GST_MATROSKA_READ_STATE_DATA)) {
5585     if (G_UNLIKELY (demux->new_segment)) {
5586       gst_matroska_demux_send_event (demux, demux->new_segment);
5587       demux->new_segment = NULL;
5588     }
5589   }
5590 
5591   ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
5592       GST_ELEMENT_CAST (demux), &id, &length, &needed);
5593   if (ret == GST_FLOW_EOS) {
5594     goto eos;
5595   } else if (ret == GST_FLOW_FLUSHING) {
5596     goto pause;
5597   } else if (ret != GST_FLOW_OK) {
5598     ret = gst_matroska_demux_check_parse_error (demux);
5599 
5600     /* Only handle EOS as no error if we're outside the segment already */
5601     if (ret == GST_FLOW_EOS && (demux->common.ebml_segment_length != G_MAXUINT64
5602             && demux->common.offset >=
5603             demux->common.ebml_segment_start +
5604             demux->common.ebml_segment_length))
5605       goto eos;
5606     else if (ret != GST_FLOW_OK)
5607       goto pause;
5608     else
5609       return;
5610   }
5611 
5612   GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
5613       "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
5614       length, needed);
5615 
5616   ret = gst_matroska_demux_parse_id (demux, id, length, needed);
5617   if (ret == GST_FLOW_EOS)
5618     goto eos;
5619   if (ret != GST_FLOW_OK)
5620     goto pause;
5621 
5622   /* check if we're at the end of a configured segment */
5623   if (G_LIKELY (demux->common.src->len)) {
5624     guint i;
5625 
5626     g_assert (demux->common.num_streams == demux->common.src->len);
5627     for (i = 0; i < demux->common.src->len; i++) {
5628       GstMatroskaTrackContext *context = g_ptr_array_index (demux->common.src,
5629           i);
5630       GST_DEBUG_OBJECT (context->pad, "pos %" GST_TIME_FORMAT,
5631           GST_TIME_ARGS (context->pos));
5632       if (context->eos == FALSE)
5633         goto next;
5634     }
5635 
5636     GST_INFO_OBJECT (demux, "All streams are EOS");
5637     ret = GST_FLOW_EOS;
5638     goto eos;
5639   }
5640 
5641 next:
5642   if (G_UNLIKELY (demux->cached_length == G_MAXUINT64 ||
5643           demux->common.offset >= demux->cached_length)) {
5644     demux->cached_length = gst_matroska_read_common_get_length (&demux->common);
5645     if (demux->common.offset == demux->cached_length) {
5646       GST_LOG_OBJECT (demux, "Reached end of stream");
5647       ret = GST_FLOW_EOS;
5648       goto eos;
5649     }
5650   }
5651 
5652   return;
5653 
5654   /* ERRORS */
5655 eos:
5656   {
5657     if (demux->common.segment.rate < 0.0) {
5658       ret = gst_matroska_demux_seek_to_previous_keyframe (demux);
5659       if (ret == GST_FLOW_OK)
5660         return;
5661     }
5662     /* fall-through */
5663   }
5664 pause:
5665   {
5666     const gchar *reason = gst_flow_get_name (ret);
5667     gboolean push_eos = FALSE;
5668 
5669     GST_LOG_OBJECT (demux, "pausing task, reason %s", reason);
5670     gst_pad_pause_task (demux->common.sinkpad);
5671 
5672     if (ret == GST_FLOW_EOS) {
5673       /* perform EOS logic */
5674 
5675       /* If we were in the headers, make sure we send no-more-pads.
5676          This will ensure decodebin does not get stuck thinking
5677          the chain is not complete yet, and waiting indefinitely. */
5678       if (G_UNLIKELY (demux->common.state == GST_MATROSKA_READ_STATE_HEADER)) {
5679         if (demux->common.src->len == 0) {
5680           GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
5681               ("No pads created"));
5682         } else {
5683           GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL),
5684               ("Failed to finish reading headers"));
5685         }
5686         gst_element_no_more_pads (GST_ELEMENT (demux));
5687       }
5688 
5689       if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
5690         GstEvent *event;
5691         GstMessage *msg;
5692         gint64 stop;
5693 
5694         /* for segment playback we need to post when (in stream time)
5695          * we stopped, this is either stop (when set) or the duration. */
5696         if ((stop = demux->common.segment.stop) == -1)
5697           stop = demux->last_stop_end;
5698 
5699         GST_LOG_OBJECT (demux, "Sending segment done, at end of segment");
5700         msg = gst_message_new_segment_done (GST_OBJECT (demux), GST_FORMAT_TIME,
5701             stop);
5702         if (demux->segment_seqnum)
5703           gst_message_set_seqnum (msg, demux->segment_seqnum);
5704         gst_element_post_message (GST_ELEMENT (demux), msg);
5705 
5706         event = gst_event_new_segment_done (GST_FORMAT_TIME, stop);
5707         if (demux->segment_seqnum)
5708           gst_event_set_seqnum (event, demux->segment_seqnum);
5709         gst_matroska_demux_send_event (demux, event);
5710       } else {
5711         push_eos = TRUE;
5712       }
5713     } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS) {
5714       /* for fatal errors we post an error message */
5715       GST_ELEMENT_FLOW_ERROR (demux, ret);
5716       push_eos = TRUE;
5717     }
5718     if (push_eos) {
5719       GstEvent *event;
5720 
5721       /* send EOS, and prevent hanging if no streams yet */
5722       GST_LOG_OBJECT (demux, "Sending EOS, at end of stream");
5723       event = gst_event_new_eos ();
5724       if (demux->segment_seqnum)
5725         gst_event_set_seqnum (event, demux->segment_seqnum);
5726       if (!gst_matroska_demux_send_event (demux, event) &&
5727           (ret == GST_FLOW_EOS)) {
5728         GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
5729             (NULL), ("got eos but no streams (yet)"));
5730       }
5731     }
5732     return;
5733   }
5734 }
5735 
5736 /*
5737  * Create and push a flushing seek event upstream
5738  */
5739 static gboolean
perform_seek_to_offset(GstMatroskaDemux * demux,gdouble rate,guint64 offset,guint32 seqnum,GstSeekFlags flags)5740 perform_seek_to_offset (GstMatroskaDemux * demux, gdouble rate, guint64 offset,
5741     guint32 seqnum, GstSeekFlags flags)
5742 {
5743   GstEvent *event;
5744   gboolean res = 0;
5745 
5746   GST_DEBUG_OBJECT (demux, "Seeking to %" G_GUINT64_FORMAT, offset);
5747 
5748   event =
5749       gst_event_new_seek (rate, GST_FORMAT_BYTES,
5750       flags | GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE,
5751       GST_SEEK_TYPE_SET, offset, GST_SEEK_TYPE_NONE, -1);
5752   gst_event_set_seqnum (event, seqnum);
5753 
5754   res = gst_pad_push_event (demux->common.sinkpad, event);
5755 
5756   /* segment event will update offset */
5757   return res;
5758 }
5759 
5760 static GstFlowReturn
gst_matroska_demux_chain(GstPad * pad,GstObject * parent,GstBuffer * buffer)5761 gst_matroska_demux_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
5762 {
5763   GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
5764   guint available;
5765   GstFlowReturn ret = GST_FLOW_OK;
5766   guint needed = 0;
5767   guint32 id;
5768   guint64 length;
5769 
5770   if (G_UNLIKELY (GST_BUFFER_IS_DISCONT (buffer))) {
5771     GST_DEBUG_OBJECT (demux, "got DISCONT");
5772     gst_adapter_clear (demux->common.adapter);
5773     GST_OBJECT_LOCK (demux);
5774     gst_matroska_read_common_reset_streams (&demux->common,
5775         GST_CLOCK_TIME_NONE, FALSE);
5776     GST_OBJECT_UNLOCK (demux);
5777   }
5778 
5779   gst_adapter_push (demux->common.adapter, buffer);
5780   buffer = NULL;
5781 
5782 next:
5783   available = gst_adapter_available (demux->common.adapter);
5784 
5785   ret = gst_matroska_read_common_peek_id_length_push (&demux->common,
5786       GST_ELEMENT_CAST (demux), &id, &length, &needed);
5787   if (G_UNLIKELY (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)) {
5788     if (demux->common.ebml_segment_length != G_MAXUINT64
5789         && demux->common.offset >=
5790         demux->common.ebml_segment_start + demux->common.ebml_segment_length) {
5791       return GST_FLOW_OK;
5792     } else {
5793       gint64 bytes_scanned;
5794       if (demux->common.start_resync_offset == -1) {
5795         demux->common.start_resync_offset = demux->common.offset;
5796         demux->common.state_to_restore = demux->common.state;
5797       }
5798       bytes_scanned = demux->common.offset - demux->common.start_resync_offset;
5799       if (bytes_scanned <= INVALID_DATA_THRESHOLD) {
5800         GST_WARNING_OBJECT (demux,
5801             "parse error, looking for next cluster, actual offset %"
5802             G_GUINT64_FORMAT ", start resync offset %" G_GUINT64_FORMAT,
5803             demux->common.offset, demux->common.start_resync_offset);
5804         demux->common.state = GST_MATROSKA_READ_STATE_SCANNING;
5805         ret = GST_FLOW_OK;
5806       } else {
5807         GST_WARNING_OBJECT (demux,
5808             "unrecoverable parse error, next cluster not found and threshold "
5809             "exceeded, bytes scanned %" G_GINT64_FORMAT, bytes_scanned);
5810         return ret;
5811       }
5812     }
5813   }
5814 
5815   GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
5816       "size %" G_GUINT64_FORMAT ", needed %d, available %d",
5817       demux->common.offset, id, length, needed, available);
5818 
5819   if (needed > available)
5820     return GST_FLOW_OK;
5821 
5822   ret = gst_matroska_demux_parse_id (demux, id, length, needed);
5823   if (ret == GST_FLOW_EOS) {
5824     /* need more data */
5825     return GST_FLOW_OK;
5826   } else if (ret != GST_FLOW_OK) {
5827     return ret;
5828   } else
5829     goto next;
5830 }
5831 
5832 static gboolean
gst_matroska_demux_handle_sink_event(GstPad * pad,GstObject * parent,GstEvent * event)5833 gst_matroska_demux_handle_sink_event (GstPad * pad, GstObject * parent,
5834     GstEvent * event)
5835 {
5836   gboolean res = TRUE;
5837   GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
5838 
5839   GST_DEBUG_OBJECT (demux,
5840       "have event type %s: %p on sink pad", GST_EVENT_TYPE_NAME (event), event);
5841 
5842   switch (GST_EVENT_TYPE (event)) {
5843     case GST_EVENT_SEGMENT:
5844     {
5845       const GstSegment *segment;
5846 
5847       /* some debug output */
5848       gst_event_parse_segment (event, &segment);
5849       /* FIXME: do we need to update segment base here (like accum in 0.10)? */
5850       GST_DEBUG_OBJECT (demux,
5851           "received format %d segment %" GST_SEGMENT_FORMAT, segment->format,
5852           segment);
5853 
5854       if (demux->common.state < GST_MATROSKA_READ_STATE_DATA) {
5855         GST_DEBUG_OBJECT (demux, "still starting");
5856         goto exit;
5857       }
5858 
5859       /* we only expect a BYTE segment, e.g. following a seek */
5860       if (segment->format != GST_FORMAT_BYTES) {
5861         GST_DEBUG_OBJECT (demux, "unsupported segment format, ignoring");
5862         goto exit;
5863       }
5864 
5865       GST_DEBUG_OBJECT (demux, "clearing segment state");
5866       GST_OBJECT_LOCK (demux);
5867       /* clear current segment leftover */
5868       gst_adapter_clear (demux->common.adapter);
5869       /* and some streaming setup */
5870       demux->common.offset = segment->start;
5871       /* accumulate base based on current position */
5872       if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.position))
5873         demux->common.segment.base +=
5874             (MAX (demux->common.segment.position, demux->stream_start_time)
5875             - demux->stream_start_time) / fabs (demux->common.segment.rate);
5876       /* do not know where we are;
5877        * need to come across a cluster and generate segment */
5878       demux->common.segment.position = GST_CLOCK_TIME_NONE;
5879       demux->cluster_time = GST_CLOCK_TIME_NONE;
5880       demux->cluster_offset = 0;
5881       demux->cluster_prevsize = 0;
5882       demux->need_segment = TRUE;
5883       demux->segment_seqnum = gst_event_get_seqnum (event);
5884       /* but keep some of the upstream segment */
5885       demux->common.segment.rate = segment->rate;
5886       demux->common.segment.flags = segment->flags;
5887       /* also check if need to keep some of the requested seek position */
5888       if (demux->seek_offset == segment->start) {
5889         GST_DEBUG_OBJECT (demux, "position matches requested seek");
5890         demux->common.segment.position = demux->requested_seek_time;
5891       } else {
5892         GST_DEBUG_OBJECT (demux, "unexpected segment position");
5893       }
5894       demux->requested_seek_time = GST_CLOCK_TIME_NONE;
5895       demux->seek_offset = -1;
5896       GST_OBJECT_UNLOCK (demux);
5897     exit:
5898       /* chain will send initial segment after pads have been added,
5899        * or otherwise come up with one */
5900       GST_DEBUG_OBJECT (demux, "eating event");
5901       gst_event_unref (event);
5902       res = TRUE;
5903       break;
5904     }
5905     case GST_EVENT_EOS:
5906     {
5907       if (demux->common.state != GST_MATROSKA_READ_STATE_DATA
5908           && demux->common.state != GST_MATROSKA_READ_STATE_SCANNING) {
5909         gst_event_unref (event);
5910         GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
5911             (NULL), ("got eos and didn't receive a complete header object"));
5912       } else if (demux->common.num_streams == 0) {
5913         GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
5914             (NULL), ("got eos but no streams (yet)"));
5915       } else {
5916         gst_matroska_demux_send_event (demux, event);
5917       }
5918       break;
5919     }
5920     case GST_EVENT_FLUSH_STOP:
5921     {
5922       guint64 dur;
5923 
5924       gst_adapter_clear (demux->common.adapter);
5925       GST_OBJECT_LOCK (demux);
5926       gst_matroska_read_common_reset_streams (&demux->common,
5927           GST_CLOCK_TIME_NONE, TRUE);
5928       gst_flow_combiner_reset (demux->flowcombiner);
5929       dur = demux->common.segment.duration;
5930       gst_segment_init (&demux->common.segment, GST_FORMAT_TIME);
5931       demux->common.segment.duration = dur;
5932       demux->cluster_time = GST_CLOCK_TIME_NONE;
5933       demux->cluster_offset = 0;
5934       demux->cluster_prevsize = 0;
5935       GST_OBJECT_UNLOCK (demux);
5936       /* fall-through */
5937     }
5938     default:
5939       res = gst_pad_event_default (pad, parent, event);
5940       break;
5941   }
5942 
5943   return res;
5944 }
5945 
5946 static gboolean
gst_matroska_demux_sink_activate(GstPad * sinkpad,GstObject * parent)5947 gst_matroska_demux_sink_activate (GstPad * sinkpad, GstObject * parent)
5948 {
5949   GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
5950   GstQuery *query;
5951   gboolean pull_mode = FALSE;
5952 
5953   query = gst_query_new_scheduling ();
5954 
5955   if (gst_pad_peer_query (sinkpad, query))
5956     pull_mode = gst_query_has_scheduling_mode_with_flags (query,
5957         GST_PAD_MODE_PULL, GST_SCHEDULING_FLAG_SEEKABLE);
5958 
5959   gst_query_unref (query);
5960 
5961   if (pull_mode) {
5962     GST_DEBUG ("going to pull mode");
5963     demux->streaming = FALSE;
5964     return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PULL, TRUE);
5965   } else {
5966     GST_DEBUG ("going to push (streaming) mode");
5967     demux->streaming = TRUE;
5968     return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PUSH, TRUE);
5969   }
5970 }
5971 
5972 static gboolean
gst_matroska_demux_sink_activate_mode(GstPad * sinkpad,GstObject * parent,GstPadMode mode,gboolean active)5973 gst_matroska_demux_sink_activate_mode (GstPad * sinkpad, GstObject * parent,
5974     GstPadMode mode, gboolean active)
5975 {
5976   switch (mode) {
5977     case GST_PAD_MODE_PULL:
5978       if (active) {
5979         /* if we have a scheduler we can start the task */
5980         gst_pad_start_task (sinkpad, (GstTaskFunction) gst_matroska_demux_loop,
5981             sinkpad, NULL);
5982       } else {
5983         gst_pad_stop_task (sinkpad);
5984       }
5985       return TRUE;
5986     case GST_PAD_MODE_PUSH:
5987       return TRUE;
5988     default:
5989       return FALSE;
5990   }
5991 }
5992 
5993 static GstCaps *
gst_matroska_demux_video_caps(GstMatroskaTrackVideoContext * videocontext,const gchar * codec_id,guint8 * data,guint size,gchar ** codec_name,guint32 * riff_fourcc)5994 gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext *
5995     videocontext, const gchar * codec_id, guint8 * data, guint size,
5996     gchar ** codec_name, guint32 * riff_fourcc)
5997 {
5998   GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) videocontext;
5999   GstCaps *caps = NULL;
6000 
6001   g_assert (videocontext != NULL);
6002   g_assert (codec_name != NULL);
6003 
6004   if (riff_fourcc)
6005     *riff_fourcc = 0;
6006 
6007   /* TODO: check if we have all codec types from matroska-ids.h
6008    *       check if we have to do more special things with codec_private
6009    *
6010    * Add support for
6011    *  GST_MATROSKA_CODEC_ID_VIDEO_QUICKTIME
6012    *  GST_MATROSKA_CODEC_ID_VIDEO_SNOW
6013    */
6014 
6015   if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VFW_FOURCC)) {
6016     gst_riff_strf_vids *vids = NULL;
6017 
6018     if (data) {
6019       GstBuffer *buf = NULL;
6020 
6021       vids = (gst_riff_strf_vids *) data;
6022 
6023       /* assure size is big enough */
6024       if (size < 24) {
6025         GST_WARNING ("Too small BITMAPINFOHEADER (%d bytes)", size);
6026         return NULL;
6027       }
6028       if (size < sizeof (gst_riff_strf_vids)) {
6029         vids = g_new (gst_riff_strf_vids, 1);
6030         memcpy (vids, data, size);
6031       }
6032 
6033       context->dts_only = TRUE; /* VFW files only store DTS */
6034 
6035       /* little-endian -> byte-order */
6036       vids->size = GUINT32_FROM_LE (vids->size);
6037       vids->width = GUINT32_FROM_LE (vids->width);
6038       vids->height = GUINT32_FROM_LE (vids->height);
6039       vids->planes = GUINT16_FROM_LE (vids->planes);
6040       vids->bit_cnt = GUINT16_FROM_LE (vids->bit_cnt);
6041       vids->compression = GUINT32_FROM_LE (vids->compression);
6042       vids->image_size = GUINT32_FROM_LE (vids->image_size);
6043       vids->xpels_meter = GUINT32_FROM_LE (vids->xpels_meter);
6044       vids->ypels_meter = GUINT32_FROM_LE (vids->ypels_meter);
6045       vids->num_colors = GUINT32_FROM_LE (vids->num_colors);
6046       vids->imp_colors = GUINT32_FROM_LE (vids->imp_colors);
6047 
6048       if (size > sizeof (gst_riff_strf_vids)) { /* some extra_data */
6049         gsize offset = sizeof (gst_riff_strf_vids);
6050 
6051         buf =
6052             gst_buffer_new_wrapped (g_memdup ((guint8 *) vids + offset,
6053                 size - offset), size - offset);
6054       }
6055 
6056       if (riff_fourcc)
6057         *riff_fourcc = vids->compression;
6058 
6059       caps = gst_riff_create_video_caps (vids->compression, NULL, vids,
6060           buf, NULL, codec_name);
6061 
6062       if (caps == NULL) {
6063         GST_WARNING ("Unhandled RIFF fourcc %" GST_FOURCC_FORMAT,
6064             GST_FOURCC_ARGS (vids->compression));
6065       } else {
6066         static GstStaticCaps intra_caps = GST_STATIC_CAPS ("image/jpeg; "
6067             "video/x-raw; image/png; video/x-dv; video/x-huffyuv; video/x-ffv; "
6068             "video/x-compressed-yuv");
6069         context->intra_only =
6070             gst_caps_can_intersect (gst_static_caps_get (&intra_caps), caps);
6071       }
6072 
6073       if (buf)
6074         gst_buffer_unref (buf);
6075 
6076       if (vids != (gst_riff_strf_vids *) data)
6077         g_free (vids);
6078     }
6079   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_UNCOMPRESSED)) {
6080     GstVideoInfo info;
6081     GstVideoFormat format;
6082 
6083     gst_video_info_init (&info);
6084     switch (videocontext->fourcc) {
6085       case GST_MAKE_FOURCC ('I', '4', '2', '0'):
6086         format = GST_VIDEO_FORMAT_I420;
6087         break;
6088       case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
6089         format = GST_VIDEO_FORMAT_YUY2;
6090         break;
6091       case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
6092         format = GST_VIDEO_FORMAT_YV12;
6093         break;
6094       case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
6095         format = GST_VIDEO_FORMAT_UYVY;
6096         break;
6097       case GST_MAKE_FOURCC ('A', 'Y', 'U', 'V'):
6098         format = GST_VIDEO_FORMAT_AYUV;
6099         break;
6100       case GST_MAKE_FOURCC ('Y', '8', '0', '0'):
6101       case GST_MAKE_FOURCC ('Y', '8', ' ', ' '):
6102         format = GST_VIDEO_FORMAT_GRAY8;
6103         break;
6104       case GST_MAKE_FOURCC ('R', 'G', 'B', 24):
6105         format = GST_VIDEO_FORMAT_RGB;
6106         break;
6107       case GST_MAKE_FOURCC ('B', 'G', 'R', 24):
6108         format = GST_VIDEO_FORMAT_BGR;
6109         break;
6110       default:
6111         GST_DEBUG ("Unknown fourcc %" GST_FOURCC_FORMAT,
6112             GST_FOURCC_ARGS (videocontext->fourcc));
6113         return NULL;
6114     }
6115 
6116     context->intra_only = TRUE;
6117 
6118     gst_video_info_set_format (&info, format, videocontext->pixel_width,
6119         videocontext->pixel_height);
6120     caps = gst_video_info_to_caps (&info);
6121     *codec_name = gst_pb_utils_get_codec_description (caps);
6122     context->alignment = 32;
6123   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_SP)) {
6124     caps = gst_caps_new_simple ("video/x-divx",
6125         "divxversion", G_TYPE_INT, 4, NULL);
6126     *codec_name = g_strdup ("MPEG-4 simple profile");
6127   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP) ||
6128       !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AP)) {
6129     caps = gst_caps_new_simple ("video/mpeg",
6130         "mpegversion", G_TYPE_INT, 4,
6131         "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
6132     if (data) {
6133       GstBuffer *priv;
6134 
6135       priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
6136       gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
6137       gst_buffer_unref (priv);
6138 
6139       gst_codec_utils_mpeg4video_caps_set_level_and_profile (caps, data, size);
6140     }
6141     if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP))
6142       *codec_name = g_strdup ("MPEG-4 advanced simple profile");
6143     else
6144       *codec_name = g_strdup ("MPEG-4 advanced profile");
6145   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MSMPEG4V3)) {
6146 #if 0
6147     caps = gst_caps_new_full (gst_structure_new ("video/x-divx",
6148             "divxversion", G_TYPE_INT, 3, NULL),
6149         gst_structure_new ("video/x-msmpeg",
6150             "msmpegversion", G_TYPE_INT, 43, NULL), NULL);
6151 #endif
6152     caps = gst_caps_new_simple ("video/x-msmpeg",
6153         "msmpegversion", G_TYPE_INT, 43, NULL);
6154     *codec_name = g_strdup ("Microsoft MPEG-4 v.3");
6155   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1) ||
6156       !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG2)) {
6157     gint mpegversion;
6158 
6159     if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1))
6160       mpegversion = 1;
6161     else
6162       mpegversion = 2;
6163 
6164     caps = gst_caps_new_simple ("video/mpeg",
6165         "systemstream", G_TYPE_BOOLEAN, FALSE,
6166         "mpegversion", G_TYPE_INT, mpegversion, NULL);
6167     *codec_name = g_strdup_printf ("MPEG-%d video", mpegversion);
6168     context->postprocess_frame = gst_matroska_demux_add_mpeg_seq_header;
6169   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MJPEG)) {
6170     caps = gst_caps_new_empty_simple ("image/jpeg");
6171     *codec_name = g_strdup ("Motion-JPEG");
6172     context->intra_only = TRUE;
6173   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AVC)) {
6174     caps = gst_caps_new_empty_simple ("video/x-h264");
6175     if (data) {
6176       GstBuffer *priv;
6177 
6178       /* First byte is the version, second is the profile indication, and third
6179        * is the 5 contraint_set_flags and 3 reserved bits. Fourth byte is the
6180        * level indication. */
6181       gst_codec_utils_h264_caps_set_level_and_profile (caps, data + 1,
6182           size - 1);
6183 
6184       priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
6185       gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
6186       gst_buffer_unref (priv);
6187 
6188       gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "avc",
6189           "alignment", G_TYPE_STRING, "au", NULL);
6190     } else {
6191       GST_WARNING ("No codec data found, assuming output is byte-stream");
6192       gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
6193           NULL);
6194     }
6195     *codec_name = g_strdup ("H264");
6196   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEGH_HEVC)) {
6197     caps = gst_caps_new_empty_simple ("video/x-h265");
6198     if (data) {
6199       GstBuffer *priv;
6200 
6201       gst_codec_utils_h265_caps_set_level_tier_and_profile (caps, data + 1,
6202           size - 1);
6203 
6204       priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
6205       gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
6206       gst_buffer_unref (priv);
6207 
6208       gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "hvc1",
6209           "alignment", G_TYPE_STRING, "au", NULL);
6210     } else {
6211       GST_WARNING ("No codec data found, assuming output is byte-stream");
6212       gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
6213           NULL);
6214     }
6215     *codec_name = g_strdup ("HEVC");
6216   } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1)) ||
6217       (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2)) ||
6218       (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3)) ||
6219       (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))) {
6220     gint rmversion = -1;
6221 
6222     if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1))
6223       rmversion = 1;
6224     else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2))
6225       rmversion = 2;
6226     else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3))
6227       rmversion = 3;
6228     else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))
6229       rmversion = 4;
6230 
6231     caps = gst_caps_new_simple ("video/x-pn-realvideo",
6232         "rmversion", G_TYPE_INT, rmversion, NULL);
6233     GST_DEBUG ("data:%p, size:0x%x", data, size);
6234     /* We need to extract the extradata ! */
6235     if (data && (size >= 0x22)) {
6236       GstBuffer *priv;
6237       guint rformat;
6238       guint subformat;
6239 
6240       subformat = GST_READ_UINT32_BE (data + 0x1a);
6241       rformat = GST_READ_UINT32_BE (data + 0x1e);
6242 
6243       priv =
6244           gst_buffer_new_wrapped (g_memdup (data + 0x1a, size - 0x1a),
6245           size - 0x1a);
6246       gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, "format",
6247           G_TYPE_INT, rformat, "subformat", G_TYPE_INT, subformat, NULL);
6248       gst_buffer_unref (priv);
6249 
6250     }
6251     *codec_name = g_strdup_printf ("RealVideo %d.0", rmversion);
6252   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_THEORA)) {
6253     caps = gst_caps_new_empty_simple ("video/x-theora");
6254     context->stream_headers =
6255         gst_matroska_parse_xiph_stream_headers (context->codec_priv,
6256         context->codec_priv_size);
6257     /* FIXME: mark stream as broken and skip if there are no stream headers */
6258     context->send_stream_headers = TRUE;
6259   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_DIRAC)) {
6260     caps = gst_caps_new_empty_simple ("video/x-dirac");
6261     *codec_name = g_strdup_printf ("Dirac");
6262   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8)) {
6263     caps = gst_caps_new_empty_simple ("video/x-vp8");
6264     *codec_name = g_strdup_printf ("On2 VP8");
6265   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP9)) {
6266     caps = gst_caps_new_empty_simple ("video/x-vp9");
6267     *codec_name = g_strdup_printf ("On2 VP9");
6268   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_AV1)) {
6269     caps = gst_caps_new_empty_simple ("video/x-av1");
6270     if (data) {
6271       GstBuffer *priv;
6272 
6273       priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
6274       gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
6275       gst_buffer_unref (priv);
6276     } else {
6277       GST_WARNING ("No AV1 codec data found!");
6278     }
6279     *codec_name = g_strdup_printf ("AOM AV1");
6280   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_PRORES)) {
6281     guint32 fourcc;
6282     const gchar *variant, *variant_descr = "";
6283 
6284     /* Expect a fourcc in the codec private data */
6285     if (!data || size < 4) {
6286       GST_WARNING ("No or too small PRORESS fourcc (%d bytes)", size);
6287       return NULL;
6288     }
6289 
6290     fourcc = GST_STR_FOURCC (data);
6291     switch (fourcc) {
6292       case GST_MAKE_FOURCC ('a', 'p', 'c', 's'):
6293         variant_descr = " 4:2:2 LT";
6294         variant = "lt";
6295         break;
6296       case GST_MAKE_FOURCC ('a', 'p', 'c', 'h'):
6297         variant = "hq";
6298         variant_descr = " 4:2:2 HQ";
6299         break;
6300       case GST_MAKE_FOURCC ('a', 'p', '4', 'h'):
6301         variant = "4444";
6302         variant_descr = " 4:4:4:4";
6303         break;
6304       case GST_MAKE_FOURCC ('a', 'p', 'c', 'o'):
6305         variant = "proxy";
6306         variant_descr = " 4:2:2 Proxy";
6307         break;
6308       case GST_MAKE_FOURCC ('a', 'p', 'c', 'n'):
6309       default:
6310         variant = "standard";
6311         variant_descr = " 4:2:2 SD";
6312         break;
6313     }
6314 
6315     GST_LOG ("Prores video, codec fourcc %" GST_FOURCC_FORMAT,
6316         GST_FOURCC_ARGS (fourcc));
6317 
6318     caps = gst_caps_new_simple ("video/x-prores",
6319         "format", G_TYPE_STRING, variant, NULL);
6320     *codec_name = g_strdup_printf ("Apple ProRes%s", variant_descr);
6321     context->postprocess_frame = gst_matroska_demux_add_prores_header;
6322   } else {
6323     GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
6324     return NULL;
6325   }
6326 
6327   if (caps != NULL) {
6328     int i;
6329     GstStructure *structure;
6330 
6331     for (i = 0; i < gst_caps_get_size (caps); i++) {
6332       structure = gst_caps_get_structure (caps, i);
6333 
6334       /* FIXME: use the real unit here! */
6335       GST_DEBUG ("video size %dx%d, target display size %dx%d (any unit)",
6336           videocontext->pixel_width,
6337           videocontext->pixel_height,
6338           videocontext->display_width, videocontext->display_height);
6339 
6340       /* pixel width and height are the w and h of the video in pixels */
6341       if (videocontext->pixel_width > 0 && videocontext->pixel_height > 0) {
6342         gint w = videocontext->pixel_width;
6343         gint h = videocontext->pixel_height;
6344 
6345         gst_structure_set (structure,
6346             "width", G_TYPE_INT, w, "height", G_TYPE_INT, h, NULL);
6347       }
6348 
6349       if (videocontext->display_width > 0 || videocontext->display_height > 0) {
6350         int n, d;
6351 
6352         if (videocontext->display_width <= 0)
6353           videocontext->display_width = videocontext->pixel_width;
6354         if (videocontext->display_height <= 0)
6355           videocontext->display_height = videocontext->pixel_height;
6356 
6357         /* calculate the pixel aspect ratio using the display and pixel w/h */
6358         n = videocontext->display_width * videocontext->pixel_height;
6359         d = videocontext->display_height * videocontext->pixel_width;
6360         GST_DEBUG ("setting PAR to %d/%d", n, d);
6361         gst_structure_set (structure, "pixel-aspect-ratio",
6362             GST_TYPE_FRACTION,
6363             videocontext->display_width * videocontext->pixel_height,
6364             videocontext->display_height * videocontext->pixel_width, NULL);
6365       }
6366 
6367       if (videocontext->default_fps > 0.0) {
6368         gint fps_n, fps_d;
6369 
6370         gst_util_double_to_fraction (videocontext->default_fps, &fps_n, &fps_d);
6371 
6372         GST_DEBUG ("using default fps %d/%d", fps_n, fps_d);
6373 
6374         gst_structure_set (structure, "framerate", GST_TYPE_FRACTION, fps_n,
6375             fps_d, NULL);
6376       } else if (context->default_duration > 0) {
6377         int fps_n, fps_d;
6378 
6379         gst_video_guess_framerate (context->default_duration, &fps_n, &fps_d);
6380 
6381         GST_INFO ("using default duration %" G_GUINT64_FORMAT
6382             " framerate %d/%d", context->default_duration, fps_n, fps_d);
6383 
6384         gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
6385             fps_n, fps_d, NULL);
6386       } else {
6387         gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
6388             0, 1, NULL);
6389       }
6390 
6391       switch (videocontext->interlace_mode) {
6392         case GST_MATROSKA_INTERLACE_MODE_PROGRESSIVE:
6393           gst_structure_set (structure,
6394               "interlace-mode", G_TYPE_STRING, "progressive", NULL);
6395           break;
6396         case GST_MATROSKA_INTERLACE_MODE_INTERLACED:
6397           gst_structure_set (structure,
6398               "interlace-mode", G_TYPE_STRING, "mixed", NULL);
6399           break;
6400         default:
6401           break;
6402       }
6403     }
6404     if (videocontext->multiview_mode != GST_VIDEO_MULTIVIEW_MODE_NONE) {
6405       if (gst_video_multiview_guess_half_aspect (videocontext->multiview_mode,
6406               videocontext->pixel_width, videocontext->pixel_height,
6407               videocontext->display_width * videocontext->pixel_height,
6408               videocontext->display_height * videocontext->pixel_width)) {
6409         videocontext->multiview_flags |= GST_VIDEO_MULTIVIEW_FLAGS_HALF_ASPECT;
6410       }
6411       gst_caps_set_simple (caps,
6412           "multiview-mode", G_TYPE_STRING,
6413           gst_video_multiview_mode_to_caps_string
6414           (videocontext->multiview_mode), "multiview-flags",
6415           GST_TYPE_VIDEO_MULTIVIEW_FLAGSET, videocontext->multiview_flags,
6416           GST_FLAG_SET_MASK_EXACT, NULL);
6417     }
6418 
6419     if (videocontext->colorimetry.range != GST_VIDEO_COLOR_RANGE_UNKNOWN ||
6420         videocontext->colorimetry.matrix != GST_VIDEO_COLOR_MATRIX_UNKNOWN ||
6421         videocontext->colorimetry.transfer != GST_VIDEO_TRANSFER_UNKNOWN ||
6422         videocontext->colorimetry.primaries !=
6423         GST_VIDEO_COLOR_PRIMARIES_UNKNOWN) {
6424       gchar *colorimetry =
6425           gst_video_colorimetry_to_string (&videocontext->colorimetry);
6426       gst_caps_set_simple (caps, "colorimetry", G_TYPE_STRING, colorimetry,
6427           NULL);
6428       GST_DEBUG ("setting colorimetry to %s", colorimetry);
6429       g_free (colorimetry);
6430     }
6431 
6432     caps = gst_caps_simplify (caps);
6433   }
6434 
6435   return caps;
6436 }
6437 
6438 /*
6439  * Some AAC specific code... *sigh*
6440  * FIXME: maybe we should use '15' and code the sample rate explicitly
6441  * if the sample rate doesn't match the predefined rates exactly? (tpm)
6442  */
6443 
6444 static gint
aac_rate_idx(gint rate)6445 aac_rate_idx (gint rate)
6446 {
6447   if (92017 <= rate)
6448     return 0;
6449   else if (75132 <= rate)
6450     return 1;
6451   else if (55426 <= rate)
6452     return 2;
6453   else if (46009 <= rate)
6454     return 3;
6455   else if (37566 <= rate)
6456     return 4;
6457   else if (27713 <= rate)
6458     return 5;
6459   else if (23004 <= rate)
6460     return 6;
6461   else if (18783 <= rate)
6462     return 7;
6463   else if (13856 <= rate)
6464     return 8;
6465   else if (11502 <= rate)
6466     return 9;
6467   else if (9391 <= rate)
6468     return 10;
6469   else
6470     return 11;
6471 }
6472 
6473 static gint
aac_profile_idx(const gchar * codec_id)6474 aac_profile_idx (const gchar * codec_id)
6475 {
6476   gint profile;
6477 
6478   if (strlen (codec_id) <= 12)
6479     profile = 3;
6480   else if (!strncmp (&codec_id[12], "MAIN", 4))
6481     profile = 0;
6482   else if (!strncmp (&codec_id[12], "LC", 2))
6483     profile = 1;
6484   else if (!strncmp (&codec_id[12], "SSR", 3))
6485     profile = 2;
6486   else
6487     profile = 3;
6488 
6489   return profile;
6490 }
6491 
6492 static guint
round_up_pow2(guint n)6493 round_up_pow2 (guint n)
6494 {
6495   n = n - 1;
6496   n = n | (n >> 1);
6497   n = n | (n >> 2);
6498   n = n | (n >> 4);
6499   n = n | (n >> 8);
6500   n = n | (n >> 16);
6501   return n + 1;
6502 }
6503 
6504 #define AAC_SYNC_EXTENSION_TYPE 0x02b7
6505 
6506 static GstCaps *
gst_matroska_demux_audio_caps(GstMatroskaTrackAudioContext * audiocontext,const gchar * codec_id,guint8 * data,guint size,gchar ** codec_name,guint16 * riff_audio_fmt)6507 gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext *
6508     audiocontext, const gchar * codec_id, guint8 * data, guint size,
6509     gchar ** codec_name, guint16 * riff_audio_fmt)
6510 {
6511   GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) audiocontext;
6512   GstCaps *caps = NULL;
6513 
6514   g_assert (audiocontext != NULL);
6515   g_assert (codec_name != NULL);
6516 
6517   if (riff_audio_fmt)
6518     *riff_audio_fmt = 0;
6519 
6520   /* TODO: check if we have all codec types from matroska-ids.h
6521    *       check if we have to do more special things with codec_private
6522    *       check if we need bitdepth in different places too
6523    *       implement channel position magic
6524    * Add support for:
6525    *  GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID9
6526    *  GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID10
6527    *  GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDMC
6528    *  GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDM2
6529    */
6530 
6531   if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1) ||
6532       !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2) ||
6533       !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L3)) {
6534     gint layer;
6535 
6536     if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1))
6537       layer = 1;
6538     else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2))
6539       layer = 2;
6540     else
6541       layer = 3;
6542 
6543     caps = gst_caps_new_simple ("audio/mpeg",
6544         "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, layer, NULL);
6545     *codec_name = g_strdup_printf ("MPEG-1 layer %d", layer);
6546   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE) ||
6547       !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_LE)) {
6548     gboolean sign;
6549     gint endianness;
6550     GstAudioFormat format;
6551 
6552     sign = (audiocontext->bitdepth != 8);
6553     if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE))
6554       endianness = G_BIG_ENDIAN;
6555     else
6556       endianness = G_LITTLE_ENDIAN;
6557 
6558     format = gst_audio_format_build_integer (sign, endianness,
6559         audiocontext->bitdepth, audiocontext->bitdepth);
6560 
6561     /* FIXME: Channel mask and reordering */
6562     caps = gst_caps_new_simple ("audio/x-raw",
6563         "format", G_TYPE_STRING, gst_audio_format_to_string (format),
6564         "layout", G_TYPE_STRING, "interleaved",
6565         "channel-mask", GST_TYPE_BITMASK,
6566         gst_audio_channel_get_fallback_mask (audiocontext->channels), NULL);
6567 
6568     *codec_name = g_strdup_printf ("Raw %d-bit PCM audio",
6569         audiocontext->bitdepth);
6570     context->alignment = GST_ROUND_UP_8 (audiocontext->bitdepth) / 8;
6571     context->alignment = round_up_pow2 (context->alignment);
6572   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_FLOAT)) {
6573     const gchar *format;
6574     if (audiocontext->bitdepth == 32)
6575       format = "F32LE";
6576     else
6577       format = "F64LE";
6578     /* FIXME: Channel mask and reordering */
6579     caps = gst_caps_new_simple ("audio/x-raw",
6580         "format", G_TYPE_STRING, format,
6581         "layout", G_TYPE_STRING, "interleaved",
6582         "channel-mask", GST_TYPE_BITMASK,
6583         gst_audio_channel_get_fallback_mask (audiocontext->channels), NULL);
6584     *codec_name = g_strdup_printf ("Raw %d-bit floating-point audio",
6585         audiocontext->bitdepth);
6586     context->alignment = audiocontext->bitdepth / 8;
6587     context->alignment = round_up_pow2 (context->alignment);
6588   } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AC3,
6589           strlen (GST_MATROSKA_CODEC_ID_AUDIO_AC3))) {
6590     caps = gst_caps_new_simple ("audio/x-ac3",
6591         "framed", G_TYPE_BOOLEAN, TRUE, NULL);
6592     *codec_name = g_strdup ("AC-3 audio");
6593   } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_EAC3,
6594           strlen (GST_MATROSKA_CODEC_ID_AUDIO_EAC3))) {
6595     caps = gst_caps_new_simple ("audio/x-eac3",
6596         "framed", G_TYPE_BOOLEAN, TRUE, NULL);
6597     *codec_name = g_strdup ("E-AC-3 audio");
6598   } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TRUEHD,
6599           strlen (GST_MATROSKA_CODEC_ID_AUDIO_TRUEHD))) {
6600     caps = gst_caps_new_empty_simple ("audio/x-true-hd");
6601     *codec_name = g_strdup ("Dolby TrueHD");
6602   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_DTS)) {
6603     caps = gst_caps_new_empty_simple ("audio/x-dts");
6604     *codec_name = g_strdup ("DTS audio");
6605   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_VORBIS)) {
6606     caps = gst_caps_new_empty_simple ("audio/x-vorbis");
6607     context->stream_headers =
6608         gst_matroska_parse_xiph_stream_headers (context->codec_priv,
6609         context->codec_priv_size);
6610     /* FIXME: mark stream as broken and skip if there are no stream headers */
6611     context->send_stream_headers = TRUE;
6612   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_FLAC)) {
6613     caps = gst_caps_new_empty_simple ("audio/x-flac");
6614     context->stream_headers =
6615         gst_matroska_parse_flac_stream_headers (context->codec_priv,
6616         context->codec_priv_size);
6617     /* FIXME: mark stream as broken and skip if there are no stream headers */
6618     context->send_stream_headers = TRUE;
6619   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_SPEEX)) {
6620     caps = gst_caps_new_empty_simple ("audio/x-speex");
6621     context->stream_headers =
6622         gst_matroska_parse_speex_stream_headers (context->codec_priv,
6623         context->codec_priv_size);
6624     /* FIXME: mark stream as broken and skip if there are no stream headers */
6625     context->send_stream_headers = TRUE;
6626   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_OPUS)) {
6627     GstBuffer *tmp;
6628 
6629     if (context->codec_priv_size >= 19) {
6630       if (audiocontext->samplerate)
6631         GST_WRITE_UINT32_LE ((guint8 *) context->codec_priv + 12,
6632             audiocontext->samplerate);
6633       if (context->codec_delay) {
6634         guint64 delay =
6635             gst_util_uint64_scale_round (context->codec_delay, 48000,
6636             GST_SECOND);
6637         GST_WRITE_UINT16_LE ((guint8 *) context->codec_priv + 10, delay);
6638       }
6639 
6640       tmp =
6641           gst_buffer_new_wrapped (g_memdup (context->codec_priv,
6642               context->codec_priv_size), context->codec_priv_size);
6643       caps = gst_codec_utils_opus_create_caps_from_header (tmp, NULL);
6644       gst_buffer_unref (tmp);
6645       *codec_name = g_strdup ("Opus");
6646     } else if (context->codec_priv_size == 0) {
6647       GST_WARNING ("No Opus codec data found, trying to create one");
6648       if (audiocontext->channels <= 2) {
6649         guint8 streams, coupled, channels;
6650         guint32 samplerate;
6651 
6652         samplerate =
6653             audiocontext->samplerate == 0 ? 48000 : audiocontext->samplerate;
6654         channels = audiocontext->channels == 0 ? 2 : audiocontext->channels;
6655         if (channels == 1) {
6656           streams = 1;
6657           coupled = 0;
6658         } else {
6659           streams = 1;
6660           coupled = 1;
6661         }
6662 
6663         caps =
6664             gst_codec_utils_opus_create_caps (samplerate, channels, 0, streams,
6665             coupled, NULL);
6666         if (caps) {
6667           *codec_name = g_strdup ("Opus");
6668         } else {
6669           GST_WARNING ("Failed to create Opus caps from audio context");
6670         }
6671       } else {
6672         GST_WARNING ("No Opus codec data, and not enough info to create one");
6673       }
6674     } else {
6675       GST_WARNING ("Invalid Opus codec data size (got %" G_GSIZE_FORMAT
6676           ", expected 19)", context->codec_priv_size);
6677     }
6678   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_ACM)) {
6679     gst_riff_strf_auds auds;
6680 
6681     if (data && size >= 18) {
6682       GstBuffer *codec_data = NULL;
6683 
6684       /* little-endian -> byte-order */
6685       auds.format = GST_READ_UINT16_LE (data);
6686       auds.channels = GST_READ_UINT16_LE (data + 2);
6687       auds.rate = GST_READ_UINT32_LE (data + 4);
6688       auds.av_bps = GST_READ_UINT32_LE (data + 8);
6689       auds.blockalign = GST_READ_UINT16_LE (data + 12);
6690       auds.bits_per_sample = GST_READ_UINT16_LE (data + 16);
6691 
6692       /* 18 is the waveformatex size */
6693       if (size > 18) {
6694         codec_data = gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY,
6695             data + 18, size - 18, 0, size - 18, NULL, NULL);
6696       }
6697 
6698       if (riff_audio_fmt)
6699         *riff_audio_fmt = auds.format;
6700 
6701       /* FIXME: Handle reorder map */
6702       caps = gst_riff_create_audio_caps (auds.format, NULL, &auds, codec_data,
6703           NULL, codec_name, NULL);
6704       if (codec_data)
6705         gst_buffer_unref (codec_data);
6706 
6707       if (caps == NULL) {
6708         GST_WARNING ("Unhandled RIFF audio format 0x%02x", auds.format);
6709       }
6710     } else {
6711       GST_WARNING ("Invalid codec data size (%d expected, got %d)", 18, size);
6712     }
6713   } else if (g_str_has_prefix (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC)) {
6714     GstBuffer *priv = NULL;
6715     gint mpegversion;
6716     gint rate_idx, profile;
6717     guint8 *data = NULL;
6718 
6719     /* unspecified AAC profile with opaque private codec data */
6720     if (strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC) == 0) {
6721       if (context->codec_priv_size >= 2) {
6722         guint obj_type, freq_index, explicit_freq_bytes = 0;
6723 
6724         codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
6725         mpegversion = 4;
6726         freq_index = (GST_READ_UINT16_BE (context->codec_priv) & 0x780) >> 7;
6727         obj_type = (GST_READ_UINT16_BE (context->codec_priv) & 0xF800) >> 11;
6728         if (freq_index == 15)
6729           explicit_freq_bytes = 3;
6730         GST_DEBUG ("obj_type = %u, freq_index = %u", obj_type, freq_index);
6731         priv = gst_buffer_new_wrapped (g_memdup (context->codec_priv,
6732                 context->codec_priv_size), context->codec_priv_size);
6733         /* assume SBR if samplerate <= 24kHz */
6734         if (obj_type == 5 || (freq_index >= 6 && freq_index != 15) ||
6735             (context->codec_priv_size == (5 + explicit_freq_bytes))) {
6736           audiocontext->samplerate *= 2;
6737         }
6738       } else {
6739         GST_WARNING ("Opaque A_AAC codec ID, but no codec private data");
6740         /* this is pretty broken;
6741          * maybe we need to make up some default private,
6742          * or maybe ADTS data got dumped in.
6743          * Let's set up some private data now, and check actual data later */
6744         /* just try this and see what happens ... */
6745         codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
6746         context->postprocess_frame = gst_matroska_demux_check_aac;
6747       }
6748     }
6749 
6750     /* make up decoder-specific data if it is not supplied */
6751     if (priv == NULL) {
6752       GstMapInfo map;
6753 
6754       priv = gst_buffer_new_allocate (NULL, 5, NULL);
6755       gst_buffer_map (priv, &map, GST_MAP_WRITE);
6756       data = map.data;
6757       rate_idx = aac_rate_idx (audiocontext->samplerate);
6758       profile = aac_profile_idx (codec_id);
6759 
6760       data[0] = ((profile + 1) << 3) | ((rate_idx & 0xE) >> 1);
6761       data[1] = ((rate_idx & 0x1) << 7) | (audiocontext->channels << 3);
6762 
6763       if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2,
6764               strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2))) {
6765         mpegversion = 2;
6766         gst_buffer_unmap (priv, &map);
6767         gst_buffer_set_size (priv, 2);
6768       } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4,
6769               strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4))) {
6770         mpegversion = 4;
6771 
6772         if (g_strrstr (codec_id, "SBR")) {
6773           /* HE-AAC (aka SBR AAC) */
6774           audiocontext->samplerate *= 2;
6775           rate_idx = aac_rate_idx (audiocontext->samplerate);
6776           data[2] = AAC_SYNC_EXTENSION_TYPE >> 3;
6777           data[3] = ((AAC_SYNC_EXTENSION_TYPE & 0x07) << 5) | 5;
6778           data[4] = (1 << 7) | (rate_idx << 3);
6779           gst_buffer_unmap (priv, &map);
6780         } else {
6781           gst_buffer_unmap (priv, &map);
6782           gst_buffer_set_size (priv, 2);
6783         }
6784       } else {
6785         gst_buffer_unmap (priv, &map);
6786         gst_buffer_unref (priv);
6787         priv = NULL;
6788         GST_ERROR ("Unknown AAC profile and no codec private data");
6789       }
6790     }
6791 
6792     if (priv) {
6793       caps = gst_caps_new_simple ("audio/mpeg",
6794           "mpegversion", G_TYPE_INT, mpegversion,
6795           "framed", G_TYPE_BOOLEAN, TRUE,
6796           "stream-format", G_TYPE_STRING, "raw", NULL);
6797       gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
6798       if (context->codec_priv && context->codec_priv_size > 0)
6799         gst_codec_utils_aac_caps_set_level_and_profile (caps,
6800             context->codec_priv, context->codec_priv_size);
6801       *codec_name = g_strdup_printf ("MPEG-%d AAC audio", mpegversion);
6802       gst_buffer_unref (priv);
6803     }
6804   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TTA)) {
6805     caps = gst_caps_new_simple ("audio/x-tta",
6806         "width", G_TYPE_INT, audiocontext->bitdepth, NULL);
6807     *codec_name = g_strdup ("TTA audio");
6808   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_WAVPACK4)) {
6809     caps = gst_caps_new_simple ("audio/x-wavpack",
6810         "width", G_TYPE_INT, audiocontext->bitdepth,
6811         "framed", G_TYPE_BOOLEAN, TRUE, NULL);
6812     *codec_name = g_strdup ("Wavpack audio");
6813     context->postprocess_frame = gst_matroska_demux_add_wvpk_header;
6814     audiocontext->wvpk_block_index = 0;
6815   } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4)) ||
6816       (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_28_8)) ||
6817       (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))) {
6818     gint raversion = -1;
6819 
6820     if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4))
6821       raversion = 1;
6822     else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))
6823       raversion = 8;
6824     else
6825       raversion = 2;
6826 
6827     caps = gst_caps_new_simple ("audio/x-pn-realaudio",
6828         "raversion", G_TYPE_INT, raversion, NULL);
6829     /* Extract extra information from caps, mapping varies based on codec */
6830     if (data && (size >= 0x50)) {
6831       GstBuffer *priv;
6832       guint flavor;
6833       guint packet_size;
6834       guint height;
6835       guint leaf_size;
6836       guint sample_width;
6837       guint extra_data_size;
6838 
6839       GST_DEBUG ("real audio raversion:%d", raversion);
6840       if (raversion == 8) {
6841         /* COOK */
6842         flavor = GST_READ_UINT16_BE (data + 22);
6843         packet_size = GST_READ_UINT32_BE (data + 24);
6844         height = GST_READ_UINT16_BE (data + 40);
6845         leaf_size = GST_READ_UINT16_BE (data + 44);
6846         sample_width = GST_READ_UINT16_BE (data + 58);
6847         extra_data_size = GST_READ_UINT32_BE (data + 74);
6848 
6849         GST_DEBUG
6850             ("flavor:%d, packet_size:%d, height:%d, leaf_size:%d, sample_width:%d, extra_data_size:%d",
6851             flavor, packet_size, height, leaf_size, sample_width,
6852             extra_data_size);
6853         gst_caps_set_simple (caps, "flavor", G_TYPE_INT, flavor, "packet_size",
6854             G_TYPE_INT, packet_size, "height", G_TYPE_INT, height, "leaf_size",
6855             G_TYPE_INT, leaf_size, "width", G_TYPE_INT, sample_width, NULL);
6856 
6857         if ((size - 78) >= extra_data_size) {
6858           priv = gst_buffer_new_wrapped (g_memdup (data + 78, extra_data_size),
6859               extra_data_size);
6860           gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
6861           gst_buffer_unref (priv);
6862         }
6863       }
6864     }
6865 
6866     *codec_name = g_strdup_printf ("RealAudio %d.0", raversion);
6867   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_SIPR)) {
6868     caps = gst_caps_new_empty_simple ("audio/x-sipro");
6869     *codec_name = g_strdup ("Sipro/ACELP.NET Voice Codec");
6870   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_RALF)) {
6871     caps = gst_caps_new_empty_simple ("audio/x-ralf-mpeg4-generic");
6872     *codec_name = g_strdup ("Real Audio Lossless");
6873   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_ATRC)) {
6874     caps = gst_caps_new_empty_simple ("audio/x-vnd.sony.atrac3");
6875     *codec_name = g_strdup ("Sony ATRAC3");
6876   } else {
6877     GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
6878     return NULL;
6879   }
6880 
6881   if (caps != NULL) {
6882     if (audiocontext->samplerate > 0 && audiocontext->channels > 0) {
6883       gint i;
6884 
6885       for (i = 0; i < gst_caps_get_size (caps); i++) {
6886         gst_structure_set (gst_caps_get_structure (caps, i),
6887             "channels", G_TYPE_INT, audiocontext->channels,
6888             "rate", G_TYPE_INT, audiocontext->samplerate, NULL);
6889       }
6890     }
6891 
6892     caps = gst_caps_simplify (caps);
6893   }
6894 
6895   return caps;
6896 }
6897 
6898 static GstCaps *
gst_matroska_demux_subtitle_caps(GstMatroskaTrackSubtitleContext * subtitlecontext,const gchar * codec_id,gpointer data,guint size)6899 gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
6900     subtitlecontext, const gchar * codec_id, gpointer data, guint size)
6901 {
6902   GstCaps *caps = NULL;
6903   GstMatroskaTrackContext *context =
6904       (GstMatroskaTrackContext *) subtitlecontext;
6905 
6906   /* for backwards compatibility */
6907   if (!g_ascii_strcasecmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASCII))
6908     codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8;
6909   else if (!g_ascii_strcasecmp (codec_id, "S_SSA"))
6910     codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_SSA;
6911   else if (!g_ascii_strcasecmp (codec_id, "S_ASS"))
6912     codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_ASS;
6913   else if (!g_ascii_strcasecmp (codec_id, "S_USF"))
6914     codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_USF;
6915 
6916   /* TODO: Add GST_MATROSKA_CODEC_ID_SUBTITLE_BMP support
6917    * Check if we have to do something with codec_private */
6918   if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8)) {
6919     /* well, plain text simply does not have a lot of markup ... */
6920     caps = gst_caps_new_simple ("text/x-raw", "format", G_TYPE_STRING,
6921         "pango-markup", NULL);
6922     context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
6923     subtitlecontext->check_markup = TRUE;
6924   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_SSA)) {
6925     caps = gst_caps_new_empty_simple ("application/x-ssa");
6926     context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
6927     subtitlecontext->check_markup = FALSE;
6928   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASS)) {
6929     caps = gst_caps_new_empty_simple ("application/x-ass");
6930     context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
6931     subtitlecontext->check_markup = FALSE;
6932   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_USF)) {
6933     caps = gst_caps_new_empty_simple ("application/x-usf");
6934     context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
6935     subtitlecontext->check_markup = FALSE;
6936   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB)) {
6937     caps = gst_caps_new_empty_simple ("subpicture/x-dvd");
6938     ((GstMatroskaTrackContext *) subtitlecontext)->send_dvd_event = TRUE;
6939   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_HDMVPGS)) {
6940     caps = gst_caps_new_empty_simple ("subpicture/x-pgs");
6941   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_KATE)) {
6942     caps = gst_caps_new_empty_simple ("subtitle/x-kate");
6943     context->stream_headers =
6944         gst_matroska_parse_xiph_stream_headers (context->codec_priv,
6945         context->codec_priv_size);
6946     /* FIXME: mark stream as broken and skip if there are no stream headers */
6947     context->send_stream_headers = TRUE;
6948   } else {
6949     GST_DEBUG ("Unknown subtitle stream: codec_id='%s'", codec_id);
6950     caps = gst_caps_new_empty_simple ("application/x-subtitle-unknown");
6951   }
6952 
6953   if (data != NULL && size > 0) {
6954     GstBuffer *buf;
6955 
6956     buf = gst_buffer_new_wrapped (g_memdup (data, size), size);
6957     gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, buf, NULL);
6958     gst_buffer_unref (buf);
6959   }
6960 
6961   return caps;
6962 }
6963 
6964 #if 0
6965 static void
6966 gst_matroska_demux_set_index (GstElement * element, GstIndex * index)
6967 {
6968   GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
6969 
6970   GST_OBJECT_LOCK (demux);
6971   if (demux->common.element_index)
6972     gst_object_unref (demux->common.element_index);
6973   demux->common.element_index = index ? gst_object_ref (index) : NULL;
6974   GST_OBJECT_UNLOCK (demux);
6975   GST_DEBUG_OBJECT (demux, "Set index %" GST_PTR_FORMAT,
6976       demux->common.element_index);
6977 }
6978 
6979 static GstIndex *
6980 gst_matroska_demux_get_index (GstElement * element)
6981 {
6982   GstIndex *result = NULL;
6983   GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
6984 
6985   GST_OBJECT_LOCK (demux);
6986   if (demux->common.element_index)
6987     result = gst_object_ref (demux->common.element_index);
6988   GST_OBJECT_UNLOCK (demux);
6989 
6990   GST_DEBUG_OBJECT (demux, "Returning index %" GST_PTR_FORMAT, result);
6991 
6992   return result;
6993 }
6994 #endif
6995 
6996 static GstStateChangeReturn
gst_matroska_demux_change_state(GstElement * element,GstStateChange transition)6997 gst_matroska_demux_change_state (GstElement * element,
6998     GstStateChange transition)
6999 {
7000   GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
7001   GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
7002 
7003   /* handle upwards state changes here */
7004   switch (transition) {
7005     default:
7006       break;
7007   }
7008 
7009   ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
7010 
7011   /* handle downwards state changes */
7012   switch (transition) {
7013     case GST_STATE_CHANGE_PAUSED_TO_READY:
7014       gst_matroska_demux_reset (GST_ELEMENT (demux));
7015       break;
7016     default:
7017       break;
7018   }
7019 
7020   return ret;
7021 }
7022 
7023 static void
gst_matroska_demux_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)7024 gst_matroska_demux_set_property (GObject * object,
7025     guint prop_id, const GValue * value, GParamSpec * pspec)
7026 {
7027   GstMatroskaDemux *demux;
7028 
7029   g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
7030   demux = GST_MATROSKA_DEMUX (object);
7031 
7032   switch (prop_id) {
7033     case PROP_MAX_GAP_TIME:
7034       GST_OBJECT_LOCK (demux);
7035       demux->max_gap_time = g_value_get_uint64 (value);
7036       GST_OBJECT_UNLOCK (demux);
7037       break;
7038     case PROP_MAX_BACKTRACK_DISTANCE:
7039       GST_OBJECT_LOCK (demux);
7040       demux->max_backtrack_distance = g_value_get_uint (value);
7041       GST_OBJECT_UNLOCK (demux);
7042       break;
7043     default:
7044       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
7045       break;
7046   }
7047 }
7048 
7049 static void
gst_matroska_demux_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)7050 gst_matroska_demux_get_property (GObject * object,
7051     guint prop_id, GValue * value, GParamSpec * pspec)
7052 {
7053   GstMatroskaDemux *demux;
7054 
7055   g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
7056   demux = GST_MATROSKA_DEMUX (object);
7057 
7058   switch (prop_id) {
7059     case PROP_MAX_GAP_TIME:
7060       GST_OBJECT_LOCK (demux);
7061       g_value_set_uint64 (value, demux->max_gap_time);
7062       GST_OBJECT_UNLOCK (demux);
7063       break;
7064     case PROP_MAX_BACKTRACK_DISTANCE:
7065       GST_OBJECT_LOCK (demux);
7066       g_value_set_uint (value, demux->max_backtrack_distance);
7067       GST_OBJECT_UNLOCK (demux);
7068       break;
7069     default:
7070       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
7071       break;
7072   }
7073 }
7074 
7075 static const gchar *
gst_matroska_track_encryption_algorithm_name(gint val)7076 gst_matroska_track_encryption_algorithm_name (gint val)
7077 {
7078   GEnumValue *en;
7079   GEnumClass *enum_class =
7080       g_type_class_ref (MATROSKA_TRACK_ENCRYPTION_ALGORITHM_TYPE);
7081   en = g_enum_get_value (G_ENUM_CLASS (enum_class), val);
7082   return en ? en->value_nick : NULL;
7083 }
7084 
7085 static const gchar *
gst_matroska_track_encryption_cipher_mode_name(gint val)7086 gst_matroska_track_encryption_cipher_mode_name (gint val)
7087 {
7088   GEnumValue *en;
7089   GEnumClass *enum_class =
7090       g_type_class_ref (MATROSKA_TRACK_ENCRYPTION_CIPHER_MODE_TYPE);
7091   en = g_enum_get_value (G_ENUM_CLASS (enum_class), val);
7092   return en ? en->value_nick : NULL;
7093 }
7094 
7095 static const gchar *
gst_matroska_track_encoding_scope_name(gint val)7096 gst_matroska_track_encoding_scope_name (gint val)
7097 {
7098   GEnumValue *en;
7099   GEnumClass *enum_class =
7100       g_type_class_ref (MATROSKA_TRACK_ENCODING_SCOPE_TYPE);
7101 
7102   en = g_enum_get_value (G_ENUM_CLASS (enum_class), val);
7103   return en ? en->value_nick : NULL;
7104 }
7105 
7106 gboolean
gst_matroska_demux_plugin_init(GstPlugin * plugin)7107 gst_matroska_demux_plugin_init (GstPlugin * plugin)
7108 {
7109   gst_riff_init ();
7110 
7111   /* parser helper separate debug */
7112   GST_DEBUG_CATEGORY_INIT (ebmlread_debug, "ebmlread",
7113       0, "EBML stream helper class");
7114 
7115   /* create an elementfactory for the matroska_demux element */
7116   if (!gst_element_register (plugin, "matroskademux",
7117           GST_RANK_PRIMARY, GST_TYPE_MATROSKA_DEMUX))
7118     return FALSE;
7119 
7120   return TRUE;
7121 }
7122