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