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