matroskamux: add G722 audio support
[platform/upstream/gst-plugins-good.git] / gst / matroska / matroska-mux.c
1 /* GStreamer Matroska muxer/demuxer
2  * (c) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
3  * (c) 2005 Michal Benes <michal.benes@xeris.cz>
4  * (c) 2008 Sebastian Dröge <sebastian.droege@collabora.co.uk>
5  * (c) 2011 Mark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>
6  *
7  * matroska-mux.c: matroska file/stream muxer
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 everywhere that we don't write invalid values
26  *       - make sure timestamps are correctly scaled everywhere
27  */
28
29 /**
30  * SECTION:element-matroskamux
31  *
32  * matroskamux muxes different input streams into a Matroska file.
33  *
34  * <refsect2>
35  * <title>Example launch line</title>
36  * |[
37  * gst-launch-1.0 -v filesrc location=/path/to/mp3 ! mpegaudioparse ! matroskamux name=mux ! filesink location=test.mkv  filesrc location=/path/to/theora.ogg ! oggdemux ! theoraparse ! mux.
38  * ]| This pipeline muxes an MP3 file and a Ogg Theora video into a Matroska file.
39  * |[
40  * gst-launch-1.0 -v audiotestsrc num-buffers=100 ! audioconvert ! vorbisenc ! matroskamux ! filesink location=test.mka
41  * ]| This pipeline muxes a 440Hz sine wave encoded with the Vorbis codec into a Matroska file.
42  * </refsect2>
43  */
44
45 #ifdef HAVE_CONFIG_H
46 #include "config.h"
47 #endif
48
49 #include <math.h>
50 #include <stdio.h>
51 #include <string.h>
52
53 #include <gst/audio/audio.h>
54 #include <gst/riff/riff-media.h>
55 #include <gst/tag/tag.h>
56 #include <gst/pbutils/codec-utils.h>
57
58 #include "matroska-mux.h"
59 #include "matroska-ids.h"
60
61 #define GST_MATROSKA_MUX_CHAPLANG "und"
62
63 GST_DEBUG_CATEGORY_STATIC (matroskamux_debug);
64 #define GST_CAT_DEFAULT matroskamux_debug
65
66 enum
67 {
68   PROP_0,
69   PROP_WRITING_APP,
70   PROP_DOCTYPE_VERSION,
71   PROP_MIN_INDEX_INTERVAL,
72   PROP_STREAMABLE,
73   PROP_TIMECODESCALE
74 };
75
76 #define  DEFAULT_DOCTYPE_VERSION         2
77 #define  DEFAULT_WRITING_APP             "GStreamer Matroska muxer"
78 #define  DEFAULT_MIN_INDEX_INTERVAL      0
79 #define  DEFAULT_STREAMABLE              FALSE
80 #define  DEFAULT_TIMECODESCALE           GST_MSECOND
81
82 /* WAVEFORMATEX is gst_riff_strf_auds + an extra guint16 extension size */
83 #define WAVEFORMATEX_SIZE  (2 + sizeof (gst_riff_strf_auds))
84
85 static GstStaticPadTemplate src_templ = GST_STATIC_PAD_TEMPLATE ("src",
86     GST_PAD_SRC,
87     GST_PAD_ALWAYS,
88     GST_STATIC_CAPS ("video/x-matroska; video/x-matroska-3d; audio/x-matroska")
89     );
90
91 #define COMMON_VIDEO_CAPS \
92   "width = (int) [ 16, MAX ], " \
93   "height = (int) [ 16, MAX ] "
94
95 /* FIXME:
96  * * require codec data, etc as needed
97  */
98
99 static GstStaticPadTemplate videosink_templ =
100     GST_STATIC_PAD_TEMPLATE ("video_%u",
101     GST_PAD_SINK,
102     GST_PAD_REQUEST,
103     GST_STATIC_CAPS ("video/mpeg, "
104         "mpegversion = (int) { 1, 2, 4 }, "
105         "systemstream = (boolean) false, "
106         COMMON_VIDEO_CAPS "; "
107         "video/x-h264, stream-format=avc, alignment=au, "
108         COMMON_VIDEO_CAPS "; "
109         "video/x-h265, stream-format=hvc1, alignment=au, "
110         COMMON_VIDEO_CAPS "; "
111         "video/x-divx, "
112         COMMON_VIDEO_CAPS "; "
113         "video/x-huffyuv, "
114         COMMON_VIDEO_CAPS "; "
115         "video/x-dv, "
116         COMMON_VIDEO_CAPS "; "
117         "video/x-h263, "
118         COMMON_VIDEO_CAPS "; "
119         "video/x-msmpeg, "
120         COMMON_VIDEO_CAPS "; "
121         "image/jpeg, "
122         COMMON_VIDEO_CAPS "; "
123         "video/x-theora; "
124         "video/x-dirac, "
125         COMMON_VIDEO_CAPS "; "
126         "video/x-pn-realvideo, "
127         "rmversion = (int) [1, 4], "
128         COMMON_VIDEO_CAPS "; "
129         "video/x-vp8, "
130         COMMON_VIDEO_CAPS "; "
131         "video/x-vp9, "
132         COMMON_VIDEO_CAPS "; "
133         "video/x-raw, "
134         "format = (string) { YUY2, I420, YV12, UYVY, AYUV, GRAY8, BGR, RGB }, "
135         COMMON_VIDEO_CAPS "; "
136         "video/x-prores, "
137         COMMON_VIDEO_CAPS "; "
138         "video/x-wmv, " "wmvversion = (int) [ 1, 3 ], " COMMON_VIDEO_CAPS)
139     );
140
141 #define COMMON_AUDIO_CAPS \
142   "channels = (int) [ 1, MAX ], " \
143   "rate = (int) [ 1, MAX ]"
144
145 /* FIXME:
146  * * require codec data, etc as needed
147  */
148 static GstStaticPadTemplate audiosink_templ =
149     GST_STATIC_PAD_TEMPLATE ("audio_%u",
150     GST_PAD_SINK,
151     GST_PAD_REQUEST,
152     GST_STATIC_CAPS ("audio/mpeg, "
153         "mpegversion = (int) 1, "
154         "layer = (int) [ 1, 3 ], "
155         COMMON_AUDIO_CAPS "; "
156         "audio/mpeg, "
157         "mpegversion = (int) { 2, 4 }, "
158         "stream-format = (string) raw, "
159         COMMON_AUDIO_CAPS "; "
160         "audio/x-ac3, "
161         COMMON_AUDIO_CAPS "; "
162         "audio/x-eac3, "
163         COMMON_AUDIO_CAPS "; "
164         "audio/x-dts, "
165         COMMON_AUDIO_CAPS "; "
166         "audio/x-vorbis, "
167         COMMON_AUDIO_CAPS "; "
168         "audio/x-flac, "
169         COMMON_AUDIO_CAPS "; "
170         "audio/x-opus; "
171         "audio/x-speex, "
172         COMMON_AUDIO_CAPS "; "
173         "audio/x-raw, "
174         "format = (string) { U8, S16BE, S16LE, S24BE, S24LE, S32BE, S32LE, F32LE, F64LE }, "
175         "layout = (string) interleaved, "
176         COMMON_AUDIO_CAPS ";"
177         "audio/x-tta, "
178         "width = (int) { 8, 16, 24 }, "
179         "channels = (int) { 1, 2 }, " "rate = (int) [ 8000, 96000 ]; "
180         "audio/x-pn-realaudio, "
181         "raversion = (int) { 1, 2, 8 }, " COMMON_AUDIO_CAPS "; "
182         "audio/x-wma, " "wmaversion = (int) [ 1, 3 ], "
183         "block_align = (int) [ 0, 65535 ], bitrate = (int) [ 0, 524288 ], "
184         COMMON_AUDIO_CAPS ";"
185         "audio/x-alaw, "
186         "channels = (int) {1, 2}, " "rate = (int) [ 8000, 192000 ]; "
187         "audio/x-mulaw, "
188         "channels = (int) {1, 2}, " "rate = (int) [ 8000, 192000 ]; "
189         "audio/x-adpcm, "
190         "layout = (string)dvi, "
191         "block_align = (int)[64, 8192], "
192         "channels = (int) { 1, 2 }, " "rate = (int) [ 8000, 96000 ]; "
193         "audio/G722, "
194         "channels = (int)1," "rate = (int)16000; "
195         "audio/x-adpcm, "
196         "layout = (string)g726, " "channels = (int)1," "rate = (int)8000; ")
197     );
198
199 static GstStaticPadTemplate subtitlesink_templ =
200     GST_STATIC_PAD_TEMPLATE ("subtitle_%u",
201     GST_PAD_SINK,
202     GST_PAD_REQUEST,
203     GST_STATIC_CAPS ("subtitle/x-kate; "
204         "text/x-raw, format=utf8; application/x-ssa; application/x-ass; "
205         "application/x-usf; subpicture/x-dvd; "
206         "application/x-subtitle-unknown")
207     );
208
209 static gpointer parent_class;   /* NULL */
210
211 /* Matroska muxer destructor */
212 static void gst_matroska_mux_class_init (GstMatroskaMuxClass * klass);
213 static void gst_matroska_mux_init (GstMatroskaMux * mux, gpointer g_class);
214 static void gst_matroska_mux_finalize (GObject * object);
215
216 /* Pads collected callback */
217 static GstFlowReturn gst_matroska_mux_handle_buffer (GstCollectPads * pads,
218     GstCollectData * data, GstBuffer * buf, gpointer user_data);
219 static gboolean gst_matroska_mux_handle_sink_event (GstCollectPads * pads,
220     GstCollectData * data, GstEvent * event, gpointer user_data);
221
222 /* pad functions */
223 static gboolean gst_matroska_mux_handle_src_event (GstPad * pad,
224     GstObject * parent, GstEvent * event);
225 static GstPad *gst_matroska_mux_request_new_pad (GstElement * element,
226     GstPadTemplate * templ, const gchar * name, const GstCaps * caps);
227 static void gst_matroska_mux_release_pad (GstElement * element, GstPad * pad);
228
229 /* gst internal change state handler */
230 static GstStateChangeReturn
231 gst_matroska_mux_change_state (GstElement * element, GstStateChange transition);
232
233 /* gobject bla bla */
234 static void gst_matroska_mux_set_property (GObject * object,
235     guint prop_id, const GValue * value, GParamSpec * pspec);
236 static void gst_matroska_mux_get_property (GObject * object,
237     guint prop_id, GValue * value, GParamSpec * pspec);
238
239 /* reset muxer */
240 static void gst_matroska_mux_reset (GstElement * element);
241
242 /* uid generation */
243 static guint64 gst_matroska_mux_create_uid (GstMatroskaMux * mux);
244
245 static gboolean theora_streamheader_to_codecdata (const GValue * streamheader,
246     GstMatroskaTrackContext * context);
247 static gboolean vorbis_streamheader_to_codecdata (const GValue * streamheader,
248     GstMatroskaTrackContext * context);
249 static gboolean speex_streamheader_to_codecdata (const GValue * streamheader,
250     GstMatroskaTrackContext * context);
251 static gboolean kate_streamheader_to_codecdata (const GValue * streamheader,
252     GstMatroskaTrackContext * context);
253 static gboolean flac_streamheader_to_codecdata (const GValue * streamheader,
254     GstMatroskaTrackContext * context);
255 static void
256 gst_matroska_mux_write_simple_tag (const GstTagList * list, const gchar * tag,
257     gpointer data);
258 static gboolean gst_matroska_mux_tag_list_is_empty (const GstTagList * list);
259 static void gst_matroska_mux_write_streams_tags (GstMatroskaMux * mux);
260 static gboolean gst_matroska_mux_streams_have_tags (GstMatroskaMux * mux);
261
262 /* Cannot use boilerplate macros here because we need the full init function
263  * signature with the additional class argument, so we use the right template
264  * for the sink caps */
265 GType
266 gst_matroska_mux_get_type (void)
267 {
268   static GType object_type;     /* 0 */
269
270   if (object_type == 0) {
271     static const GTypeInfo object_info = {
272       sizeof (GstMatroskaMuxClass),
273       NULL,                     /* base_init */
274       NULL,                     /* base_finalize */
275       (GClassInitFunc) gst_matroska_mux_class_init,
276       NULL,                     /* class_finalize */
277       NULL,                     /* class_data */
278       sizeof (GstMatroskaMux),
279       0,                        /* n_preallocs */
280       (GInstanceInitFunc) gst_matroska_mux_init
281     };
282     const GInterfaceInfo iface_info = { NULL };
283
284     object_type = g_type_register_static (GST_TYPE_ELEMENT,
285         "GstMatroskaMux", &object_info, (GTypeFlags) 0);
286
287     g_type_add_interface_static (object_type, GST_TYPE_TAG_SETTER, &iface_info);
288     g_type_add_interface_static (object_type, GST_TYPE_TOC_SETTER, &iface_info);
289   }
290
291   return object_type;
292 }
293
294 static void
295 gst_matroska_mux_class_init (GstMatroskaMuxClass * klass)
296 {
297   GObjectClass *gobject_class;
298   GstElementClass *gstelement_class;
299
300   gobject_class = (GObjectClass *) klass;
301   gstelement_class = (GstElementClass *) klass;
302
303   gst_element_class_add_static_pad_template (gstelement_class,
304       &videosink_templ);
305   gst_element_class_add_static_pad_template (gstelement_class,
306       &audiosink_templ);
307   gst_element_class_add_static_pad_template (gstelement_class,
308       &subtitlesink_templ);
309   gst_element_class_add_static_pad_template (gstelement_class, &src_templ);
310   gst_element_class_set_static_metadata (gstelement_class, "Matroska muxer",
311       "Codec/Muxer",
312       "Muxes video/audio/subtitle streams into a matroska stream",
313       "GStreamer maintainers <gstreamer-devel@lists.freedesktop.org>");
314
315   GST_DEBUG_CATEGORY_INIT (matroskamux_debug, "matroskamux", 0,
316       "Matroska muxer");
317
318   gobject_class->finalize = gst_matroska_mux_finalize;
319
320   gobject_class->get_property = gst_matroska_mux_get_property;
321   gobject_class->set_property = gst_matroska_mux_set_property;
322
323   g_object_class_install_property (gobject_class, PROP_WRITING_APP,
324       g_param_spec_string ("writing-app", "Writing application.",
325           "The name the application that creates the matroska file.",
326           NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
327   g_object_class_install_property (gobject_class, PROP_DOCTYPE_VERSION,
328       g_param_spec_int ("version", "DocType version",
329           "This parameter determines what Matroska features can be used.",
330           1, 2, DEFAULT_DOCTYPE_VERSION,
331           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
332   g_object_class_install_property (gobject_class, PROP_MIN_INDEX_INTERVAL,
333       g_param_spec_int64 ("min-index-interval", "Minimum time between index "
334           "entries", "An index entry is created every so many nanoseconds.",
335           0, G_MAXINT64, DEFAULT_MIN_INDEX_INTERVAL,
336           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
337   g_object_class_install_property (gobject_class, PROP_STREAMABLE,
338       g_param_spec_boolean ("streamable", "Determines whether output should "
339           "be streamable", "If set to true, the output should be as if it is "
340           "to be streamed and hence no indexes written or duration written.",
341           DEFAULT_STREAMABLE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
342   g_object_class_install_property (gobject_class, PROP_TIMECODESCALE,
343       g_param_spec_int64 ("timecodescale", "Timecode Scale",
344           "TimecodeScale used to calculate the Raw Timecode of a Block", 1,
345           GST_SECOND, DEFAULT_TIMECODESCALE,
346           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
347
348   gstelement_class->change_state =
349       GST_DEBUG_FUNCPTR (gst_matroska_mux_change_state);
350   gstelement_class->request_new_pad =
351       GST_DEBUG_FUNCPTR (gst_matroska_mux_request_new_pad);
352   gstelement_class->release_pad =
353       GST_DEBUG_FUNCPTR (gst_matroska_mux_release_pad);
354
355   parent_class = g_type_class_peek_parent (klass);
356 }
357
358 /*
359  * Start of pad option handler code
360  */
361 #define DEFAULT_PAD_FRAME_DURATION TRUE
362
363 enum
364 {
365   PROP_PAD_0,
366   PROP_PAD_FRAME_DURATION
367 };
368
369 typedef struct
370 {
371   GstPad parent;
372   gboolean frame_duration;
373   gboolean frame_duration_user;
374 } GstMatroskamuxPad;
375
376 typedef GstPadClass GstMatroskamuxPadClass;
377
378 GType gst_matroskamux_pad_get_type (void);
379 G_DEFINE_TYPE (GstMatroskamuxPad, gst_matroskamux_pad, GST_TYPE_PAD);
380
381 #define GST_TYPE_MATROSKAMUX_PAD (gst_matroskamux_pad_get_type())
382 #define GST_MATROSKAMUX_PAD(pad) (G_TYPE_CHECK_INSTANCE_CAST((pad),GST_TYPE_MATROSKAMUX_PAD,GstMatroskamuxPad))
383 #define GST_MATROSKAMUX_PAD_CAST(pad) ((GstMatroskamuxPad *) pad)
384 #define GST_IS_MATROSKAMUX_PAD(pad) (G_TYPE_CHECK_INSTANCE_TYPE((pad),GST_TYPE_MATROSKAMUX_PAD))
385
386 static void
387 gst_matroskamux_pad_get_property (GObject * object, guint prop_id,
388     GValue * value, GParamSpec * pspec)
389 {
390   GstMatroskamuxPad *pad = GST_MATROSKAMUX_PAD (object);
391
392   switch (prop_id) {
393     case PROP_PAD_FRAME_DURATION:
394       g_value_set_boolean (value, pad->frame_duration);
395       break;
396     default:
397       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
398       break;
399   }
400 }
401
402 static void
403 gst_matroskamux_pad_set_property (GObject * object, guint prop_id,
404     const GValue * value, GParamSpec * pspec)
405 {
406   GstMatroskamuxPad *pad = GST_MATROSKAMUX_PAD (object);
407
408   switch (prop_id) {
409     case PROP_PAD_FRAME_DURATION:
410       pad->frame_duration = g_value_get_boolean (value);
411       pad->frame_duration_user = TRUE;
412       break;
413     default:
414       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
415       break;
416   }
417 }
418
419 static void
420 gst_matroskamux_pad_class_init (GstMatroskamuxPadClass * klass)
421 {
422   GObjectClass *gobject_class = (GObjectClass *) klass;
423
424   gobject_class->set_property = gst_matroskamux_pad_set_property;
425   gobject_class->get_property = gst_matroskamux_pad_get_property;
426
427   g_object_class_install_property (gobject_class, PROP_PAD_FRAME_DURATION,
428       g_param_spec_boolean ("frame-duration", "Frame duration",
429           "Default frame duration", DEFAULT_PAD_FRAME_DURATION,
430           G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
431 }
432
433 static void
434 gst_matroskamux_pad_init (GstMatroskamuxPad * pad)
435 {
436   pad->frame_duration = DEFAULT_PAD_FRAME_DURATION;
437   pad->frame_duration_user = FALSE;
438 }
439
440 /*
441  * End of pad option handler code
442  **/
443
444 static void
445 gst_matroska_mux_init (GstMatroskaMux * mux, gpointer g_class)
446 {
447   GstPadTemplate *templ;
448
449   templ =
450       gst_element_class_get_pad_template (GST_ELEMENT_CLASS (g_class), "src");
451   mux->srcpad = gst_pad_new_from_template (templ, "src");
452
453   gst_pad_set_event_function (mux->srcpad, gst_matroska_mux_handle_src_event);
454   gst_element_add_pad (GST_ELEMENT (mux), mux->srcpad);
455   gst_pad_use_fixed_caps (mux->srcpad);
456
457   mux->collect = gst_collect_pads_new ();
458   gst_collect_pads_set_clip_function (mux->collect,
459       GST_DEBUG_FUNCPTR (gst_collect_pads_clip_running_time), mux);
460   gst_collect_pads_set_buffer_function (mux->collect,
461       GST_DEBUG_FUNCPTR (gst_matroska_mux_handle_buffer), mux);
462   gst_collect_pads_set_event_function (mux->collect,
463       GST_DEBUG_FUNCPTR (gst_matroska_mux_handle_sink_event), mux);
464
465   mux->ebml_write = gst_ebml_write_new (mux->srcpad);
466   mux->doctype = GST_MATROSKA_DOCTYPE_MATROSKA;
467
468   /* property defaults */
469   mux->doctype_version = DEFAULT_DOCTYPE_VERSION;
470   mux->writing_app = g_strdup (DEFAULT_WRITING_APP);
471   mux->min_index_interval = DEFAULT_MIN_INDEX_INTERVAL;
472   mux->ebml_write->streamable = DEFAULT_STREAMABLE;
473   mux->time_scale = DEFAULT_TIMECODESCALE;
474
475   /* initialize internal variables */
476   mux->index = NULL;
477   mux->num_streams = 0;
478   mux->num_a_streams = 0;
479   mux->num_t_streams = 0;
480   mux->num_v_streams = 0;
481
482   /* create used uid list */
483   mux->used_uids = g_array_sized_new (FALSE, FALSE, sizeof (guint64), 10);
484
485   /* initialize remaining variables */
486   gst_matroska_mux_reset (GST_ELEMENT (mux));
487 }
488
489
490 /**
491  * gst_matroska_mux_finalize:
492  * @object: #GstMatroskaMux that should be finalized.
493  *
494  * Finalize matroska muxer.
495  */
496 static void
497 gst_matroska_mux_finalize (GObject * object)
498 {
499   GstMatroskaMux *mux = GST_MATROSKA_MUX (object);
500
501   gst_event_replace (&mux->force_key_unit_event, NULL);
502
503   gst_object_unref (mux->collect);
504   gst_object_unref (mux->ebml_write);
505   g_free (mux->writing_app);
506
507   g_array_free (mux->used_uids, TRUE);
508
509   G_OBJECT_CLASS (parent_class)->finalize (object);
510 }
511
512
513 /**
514  * gst_matroska_mux_create_uid:
515  * @mux: #GstMatroskaMux to generate UID for.
516  *
517  * Generate new unused track UID.
518  *
519  * Returns: New track UID.
520  */
521 static guint64
522 gst_matroska_mux_create_uid (GstMatroskaMux * mux)
523 {
524   guint64 uid = 0;
525
526   while (!uid) {
527     guint i;
528
529     uid = (((guint64) g_random_int ()) << 32) | g_random_int ();
530     for (i = 0; i < mux->used_uids->len; i++) {
531       if (g_array_index (mux->used_uids, guint64, i) == uid) {
532         uid = 0;
533         break;
534       }
535     }
536     g_array_append_val (mux->used_uids, uid);
537   }
538
539   return uid;
540 }
541
542
543 /**
544  * gst_matroska_pad_reset:
545  * @collect_pad: the #GstMatroskaPad
546  *
547  * Reset and/or release resources of a matroska collect pad.
548  */
549 static void
550 gst_matroska_pad_reset (GstMatroskaPad * collect_pad, gboolean full)
551 {
552   gchar *name = NULL;
553   GstMatroskaTrackType type = 0;
554
555   /* free track information */
556   if (collect_pad->track != NULL) {
557     /* retrieve for optional later use */
558     name = collect_pad->track->name;
559     type = collect_pad->track->type;
560     /* extra for video */
561     if (type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
562       GstMatroskaTrackVideoContext *ctx =
563           (GstMatroskaTrackVideoContext *) collect_pad->track;
564
565       if (ctx->dirac_unit) {
566         gst_buffer_unref (ctx->dirac_unit);
567         ctx->dirac_unit = NULL;
568       }
569     }
570     g_free (collect_pad->track->codec_id);
571     g_free (collect_pad->track->codec_name);
572     if (full)
573       g_free (collect_pad->track->name);
574     g_free (collect_pad->track->language);
575     g_free (collect_pad->track->codec_priv);
576     g_free (collect_pad->track);
577     collect_pad->track = NULL;
578     if (collect_pad->tags) {
579       gst_tag_list_unref (collect_pad->tags);
580       collect_pad->tags = NULL;
581     }
582   }
583
584   if (!full && type != 0) {
585     GstMatroskaTrackContext *context;
586
587     /* create a fresh context */
588     switch (type) {
589       case GST_MATROSKA_TRACK_TYPE_VIDEO:
590         context = (GstMatroskaTrackContext *)
591             g_new0 (GstMatroskaTrackVideoContext, 1);
592         break;
593       case GST_MATROSKA_TRACK_TYPE_AUDIO:
594         context = (GstMatroskaTrackContext *)
595             g_new0 (GstMatroskaTrackAudioContext, 1);
596         break;
597       case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
598         context = (GstMatroskaTrackContext *)
599             g_new0 (GstMatroskaTrackSubtitleContext, 1);
600         break;
601       default:
602         g_assert_not_reached ();
603         return;
604     }
605
606     context->type = type;
607     context->name = name;
608     context->uid = gst_matroska_mux_create_uid (collect_pad->mux);
609     /* TODO: check default values for the context */
610     context->flags = GST_MATROSKA_TRACK_ENABLED | GST_MATROSKA_TRACK_DEFAULT;
611     collect_pad->track = context;
612     collect_pad->start_ts = GST_CLOCK_TIME_NONE;
613     collect_pad->end_ts = GST_CLOCK_TIME_NONE;
614     collect_pad->tags = gst_tag_list_new_empty ();
615     gst_tag_list_set_scope (collect_pad->tags, GST_TAG_SCOPE_STREAM);
616   }
617 }
618
619 /**
620  * gst_matroska_pad_free:
621  * @collect_pad: the #GstMatroskaPad
622  *
623  * Release resources of a matroska collect pad.
624  */
625 static void
626 gst_matroska_pad_free (GstPad * collect_pad)
627 {
628   gst_matroska_pad_reset ((GstMatroskaPad *) collect_pad, TRUE);
629 }
630
631
632 /**
633  * gst_matroska_mux_reset:
634  * @element: #GstMatroskaMux that should be reseted.
635  *
636  * Reset matroska muxer back to initial state.
637  */
638 static void
639 gst_matroska_mux_reset (GstElement * element)
640 {
641   GstMatroskaMux *mux = GST_MATROSKA_MUX (element);
642   GSList *walk;
643
644   /* reset EBML write */
645   gst_ebml_write_reset (mux->ebml_write);
646
647   /* reset input */
648   mux->state = GST_MATROSKA_MUX_STATE_START;
649
650   /* clean up existing streams */
651
652   for (walk = mux->collect->data; walk; walk = g_slist_next (walk)) {
653     GstMatroskaPad *collect_pad;
654
655     collect_pad = (GstMatroskaPad *) walk->data;
656
657     /* reset collect pad to pristine state */
658     gst_matroska_pad_reset (collect_pad, FALSE);
659   }
660
661   /* reset indexes */
662   mux->num_indexes = 0;
663   g_free (mux->index);
664   mux->index = NULL;
665
666   /* reset timers */
667   mux->max_cluster_duration = G_MAXINT16 * mux->time_scale;
668   mux->duration = 0;
669
670   /* reset cluster */
671   mux->cluster = 0;
672   mux->cluster_time = 0;
673   mux->cluster_pos = 0;
674   mux->prev_cluster_size = 0;
675
676   /* reset tags */
677   gst_tag_setter_reset_tags (GST_TAG_SETTER (mux));
678
679   mux->tags_pos = 0;
680
681   /* reset chapters */
682   gst_toc_setter_reset (GST_TOC_SETTER (mux));
683
684   mux->chapters_pos = 0;
685
686   /* clear used uids */
687   if (mux->used_uids->len > 0) {
688     g_array_remove_range (mux->used_uids, 0, mux->used_uids->len);
689   }
690 }
691
692 /**
693  * gst_matroska_mux_handle_src_event:
694  * @pad: Pad which received the event.
695  * @event: Received event.
696  *
697  * handle events - copied from oggmux without understanding
698  *
699  * Returns: #TRUE on success.
700  */
701 static gboolean
702 gst_matroska_mux_handle_src_event (GstPad * pad, GstObject * parent,
703     GstEvent * event)
704 {
705   GstEventType type;
706
707   type = event ? GST_EVENT_TYPE (event) : GST_EVENT_UNKNOWN;
708
709   switch (type) {
710     case GST_EVENT_SEEK:
711       /* disable seeking for now */
712       return FALSE;
713     default:
714       break;
715   }
716
717   return gst_pad_event_default (pad, parent, event);
718 }
719
720
721 static void
722 gst_matroska_mux_free_codec_priv (GstMatroskaTrackContext * context)
723 {
724   if (context->codec_priv != NULL) {
725     g_free (context->codec_priv);
726     context->codec_priv = NULL;
727     context->codec_priv_size = 0;
728   }
729 }
730
731 static void
732 gst_matroska_mux_build_vobsub_private (GstMatroskaTrackContext * context,
733     const guint * clut)
734 {
735   gchar *clutv[17];
736   gchar *sclut;
737   gint i;
738   guint32 col;
739   gdouble y, u, v;
740   guint8 r, g, b;
741
742   /* produce comma-separated list in hex format */
743   for (i = 0; i < 16; ++i) {
744     col = clut[i];
745     /* replicate vobsub's slightly off RGB conversion calculation */
746     y = (((col >> 16) & 0xff) - 16) * 255 / 219;
747     u = ((col >> 8) & 0xff) - 128;
748     v = (col & 0xff) - 128;
749     r = CLAMP (1.0 * y + 1.4022 * u, 0, 255);
750     g = CLAMP (1.0 * y - 0.3456 * u - 0.7145 * v, 0, 255);
751     b = CLAMP (1.0 * y + 1.7710 * v, 0, 255);
752     clutv[i] = g_strdup_printf ("%02x%02x%02x", r, g, b);
753   }
754   clutv[i] = NULL;
755   sclut = g_strjoinv (",", clutv);
756
757   /* build codec private; only palette for now */
758   gst_matroska_mux_free_codec_priv (context);
759   context->codec_priv = (guint8 *) g_strdup_printf ("palette: %s", sclut);
760   /* include terminating 0 */
761   context->codec_priv_size = strlen ((gchar *) context->codec_priv) + 1;
762   g_free (sclut);
763   for (i = 0; i < 16; ++i) {
764     g_free (clutv[i]);
765   }
766 }
767
768
769 /**
770  * gst_matroska_mux_handle_sink_event:
771  * @pad: Pad which received the event.
772  * @event: Received event.
773  *
774  * handle events - informational ones like tags
775  *
776  * Returns: #TRUE on success.
777  */
778 static gboolean
779 gst_matroska_mux_handle_sink_event (GstCollectPads * pads,
780     GstCollectData * data, GstEvent * event, gpointer user_data)
781 {
782   GstMatroskaPad *collect_pad;
783   GstMatroskaTrackContext *context;
784   GstMatroskaMux *mux;
785   GstPad *pad;
786   GstTagList *list;
787   gboolean ret = TRUE;
788
789   mux = GST_MATROSKA_MUX (user_data);
790   collect_pad = (GstMatroskaPad *) data;
791   pad = data->pad;
792   context = collect_pad->track;
793   g_assert (context);
794
795   switch (GST_EVENT_TYPE (event)) {
796     case GST_EVENT_CAPS:{
797       GstCaps *caps;
798
799       collect_pad = (GstMatroskaPad *) gst_pad_get_element_private (pad);
800       gst_event_parse_caps (event, &caps);
801
802       ret = collect_pad->capsfunc (pad, caps);
803       gst_event_unref (event);
804       event = NULL;
805       break;
806     }
807     case GST_EVENT_TAG:{
808       gchar *lang = NULL;
809
810       GST_DEBUG_OBJECT (mux, "received tag event");
811       gst_event_parse_tag (event, &list);
812
813       /* Matroska wants ISO 639-2B code, taglist most likely contains 639-1 */
814       if (gst_tag_list_get_string (list, GST_TAG_LANGUAGE_CODE, &lang)) {
815         const gchar *lang_code;
816
817         lang_code = gst_tag_get_language_code_iso_639_2B (lang);
818         if (lang_code) {
819           GST_INFO_OBJECT (pad, "Setting language to '%s'", lang_code);
820           g_free (context->language);
821           context->language = g_strdup (lang_code);
822         } else {
823           GST_WARNING_OBJECT (pad, "Did not get language code for '%s'", lang);
824         }
825         g_free (lang);
826       }
827
828       /* FIXME: what about stream-specific tags? */
829       if (gst_tag_list_get_scope (list) == GST_TAG_SCOPE_GLOBAL) {
830         gst_tag_setter_merge_tags (GST_TAG_SETTER (mux), list,
831             gst_tag_setter_get_tag_merge_mode (GST_TAG_SETTER (mux)));
832       } else {
833         gst_tag_list_insert (collect_pad->tags, list, GST_TAG_MERGE_REPLACE);
834       }
835
836       gst_event_unref (event);
837       /* handled this, don't want collectpads to forward it downstream */
838       event = NULL;
839       ret = TRUE;
840       break;
841     }
842     case GST_EVENT_TOC:{
843       GstToc *toc, *old_toc;
844
845       if (mux->chapters_pos > 0)
846         break;
847
848       GST_DEBUG_OBJECT (mux, "received toc event");
849       gst_event_parse_toc (event, &toc, NULL);
850
851       if (toc != NULL) {
852         old_toc = gst_toc_setter_get_toc (GST_TOC_SETTER (mux));
853         if (old_toc != NULL) {
854           if (old_toc != toc)
855             GST_INFO_OBJECT (pad, "Replacing TOC with a new one");
856           gst_toc_unref (old_toc);
857         }
858
859         gst_toc_setter_set_toc (GST_TOC_SETTER (mux), toc);
860         gst_toc_unref (toc);
861       }
862
863       gst_event_unref (event);
864       /* handled this, don't want collectpads to forward it downstream */
865       event = NULL;
866       break;
867     }
868     case GST_EVENT_CUSTOM_DOWNSTREAM:
869     case GST_EVENT_CUSTOM_DOWNSTREAM_STICKY:{
870       const GstStructure *structure;
871
872       structure = gst_event_get_structure (event);
873       if (gst_structure_has_name (structure, "GstForceKeyUnit")) {
874         gst_event_replace (&mux->force_key_unit_event, NULL);
875         mux->force_key_unit_event = event;
876         event = NULL;
877       } else if (gst_structure_has_name (structure, "application/x-gst-dvd") &&
878           !strcmp ("dvd-spu-clut-change",
879               gst_structure_get_string (structure, "event"))) {
880         gchar name[16];
881         gint i, value;
882         guint clut[16];
883
884         GST_DEBUG_OBJECT (pad, "New DVD colour table received");
885         if (context->type != GST_MATROSKA_TRACK_TYPE_SUBTITLE) {
886           GST_DEBUG_OBJECT (pad, "... discarding");
887           break;
888         }
889         /* first transform event data into table form */
890         for (i = 0; i < 16; i++) {
891           g_snprintf (name, sizeof (name), "clut%02d", i);
892           if (!gst_structure_get_int (structure, name, &value)) {
893             GST_ERROR_OBJECT (mux, "dvd-spu-clut-change event did not "
894                 "contain %s field", name);
895             goto break_hard;
896           }
897           clut[i] = value;
898         }
899
900         /* transform into private data for stream; text form */
901         gst_matroska_mux_build_vobsub_private (context, clut);
902       }
903     }
904       /* fall through */
905     default:
906       break;
907   }
908
909 break_hard:
910   if (event != NULL)
911     return gst_collect_pads_event_default (pads, data, event, FALSE);
912
913   return ret;
914 }
915
916 static void
917 gst_matroska_mux_set_codec_id (GstMatroskaTrackContext * context,
918     const char *id)
919 {
920   g_assert (context && id);
921   g_free (context->codec_id);
922   context->codec_id = g_strdup (id);
923 }
924
925 /**
926  * gst_matroska_mux_video_pad_setcaps:
927  * @pad: Pad which got the caps.
928  * @caps: New caps.
929  *
930  * Setcaps function for video sink pad.
931  *
932  * Returns: #TRUE on success.
933  */
934 static gboolean
935 gst_matroska_mux_video_pad_setcaps (GstPad * pad, GstCaps * caps)
936 {
937   GstMatroskaTrackContext *context = NULL;
938   GstMatroskaTrackVideoContext *videocontext;
939   GstMatroskaMux *mux;
940   GstMatroskaPad *collect_pad;
941   GstStructure *structure;
942   const gchar *mimetype;
943   const gchar *interlace_mode, *s;
944   const GValue *value = NULL;
945   GstBuffer *codec_buf = NULL;
946   gint width, height, pixel_width, pixel_height;
947   gint fps_d, fps_n;
948   guint multiview_flags;
949
950   mux = GST_MATROSKA_MUX (GST_PAD_PARENT (pad));
951
952   /* find context */
953   collect_pad = (GstMatroskaPad *) gst_pad_get_element_private (pad);
954   g_assert (collect_pad);
955   context = collect_pad->track;
956   g_assert (context);
957   g_assert (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO);
958   videocontext = (GstMatroskaTrackVideoContext *) context;
959
960   /* gst -> matroska ID'ing */
961   structure = gst_caps_get_structure (caps, 0);
962
963   mimetype = gst_structure_get_name (structure);
964
965   interlace_mode = gst_structure_get_string (structure, "interlace-mode");
966   if (interlace_mode != NULL && strcmp (interlace_mode, "progressive") != 0)
967     context->flags |= GST_MATROSKA_VIDEOTRACK_INTERLACED;
968
969   if (!strcmp (mimetype, "video/x-theora")) {
970     /* we'll extract the details later from the theora identification header */
971     goto skip_details;
972   }
973
974   /* get general properties */
975   /* spec says it is mandatory */
976   if (!gst_structure_get_int (structure, "width", &width) ||
977       !gst_structure_get_int (structure, "height", &height))
978     goto refuse_caps;
979
980   videocontext->pixel_width = width;
981   videocontext->pixel_height = height;
982
983   if (GST_MATROSKAMUX_PAD_CAST (pad)->frame_duration
984       && gst_structure_get_fraction (structure, "framerate", &fps_n, &fps_d)
985       && fps_n > 0) {
986     context->default_duration =
987         gst_util_uint64_scale_int (GST_SECOND, fps_d, fps_n);
988     GST_LOG_OBJECT (pad, "default duration = %" GST_TIME_FORMAT,
989         GST_TIME_ARGS (context->default_duration));
990   } else {
991     context->default_duration = 0;
992   }
993   if (gst_structure_get_fraction (structure, "pixel-aspect-ratio",
994           &pixel_width, &pixel_height)) {
995     if (pixel_width > pixel_height) {
996       videocontext->display_width = width * pixel_width / pixel_height;
997       videocontext->display_height = height;
998     } else if (pixel_width < pixel_height) {
999       videocontext->display_width = width;
1000       videocontext->display_height = height * pixel_height / pixel_width;
1001     } else {
1002       videocontext->display_width = 0;
1003       videocontext->display_height = 0;
1004     }
1005   } else {
1006     videocontext->display_width = 0;
1007     videocontext->display_height = 0;
1008   }
1009
1010   /* Collect stereoscopic info, if any */
1011   if ((s = gst_structure_get_string (structure, "multiview-mode")))
1012     videocontext->multiview_mode =
1013         gst_video_multiview_mode_from_caps_string (s);
1014   gst_structure_get_flagset (structure, "multiview-flags", &multiview_flags,
1015       NULL);
1016   videocontext->multiview_flags = multiview_flags;
1017
1018
1019 skip_details:
1020
1021   videocontext->asr_mode = GST_MATROSKA_ASPECT_RATIO_MODE_FREE;
1022   videocontext->fourcc = 0;
1023
1024   /* TODO: - check if we handle all codecs by the spec, i.e. codec private
1025    *         data and other settings
1026    *       - add new formats
1027    */
1028
1029   /* extract codec_data, may turn out needed */
1030   value = gst_structure_get_value (structure, "codec_data");
1031   if (value)
1032     codec_buf = (GstBuffer *) gst_value_get_buffer (value);
1033
1034   /* find type */
1035   if (!strcmp (mimetype, "video/x-raw")) {
1036     const gchar *fstr;
1037     gst_matroska_mux_set_codec_id (context,
1038         GST_MATROSKA_CODEC_ID_VIDEO_UNCOMPRESSED);
1039     fstr = gst_structure_get_string (structure, "format");
1040     if (fstr) {
1041       if (strlen (fstr) == 4)
1042         videocontext->fourcc = GST_STR_FOURCC (fstr);
1043       else if (!strcmp (fstr, "GRAY8"))
1044         videocontext->fourcc = GST_MAKE_FOURCC ('Y', '8', '0', '0');
1045       else if (!strcmp (fstr, "BGR"))
1046         videocontext->fourcc = GST_MAKE_FOURCC ('B', 'G', 'R', 24);
1047       else if (!strcmp (fstr, "RGB"))
1048         videocontext->fourcc = GST_MAKE_FOURCC ('R', 'G', 'B', 24);
1049     }
1050   } else if (!strcmp (mimetype, "video/x-huffyuv")      /* MS/VfW compatibility cases */
1051       ||!strcmp (mimetype, "video/x-divx")
1052       || !strcmp (mimetype, "video/x-dv")
1053       || !strcmp (mimetype, "video/x-h263")
1054       || !strcmp (mimetype, "video/x-msmpeg")
1055       || !strcmp (mimetype, "video/x-wmv")
1056       || !strcmp (mimetype, "image/jpeg")) {
1057     gst_riff_strf_vids *bih;
1058     gint size = sizeof (gst_riff_strf_vids);
1059     guint32 fourcc = 0;
1060
1061     if (!strcmp (mimetype, "video/x-huffyuv"))
1062       fourcc = GST_MAKE_FOURCC ('H', 'F', 'Y', 'U');
1063     else if (!strcmp (mimetype, "video/x-dv"))
1064       fourcc = GST_MAKE_FOURCC ('D', 'V', 'S', 'D');
1065     else if (!strcmp (mimetype, "video/x-h263"))
1066       fourcc = GST_MAKE_FOURCC ('H', '2', '6', '3');
1067     else if (!strcmp (mimetype, "video/x-divx")) {
1068       gint divxversion;
1069
1070       gst_structure_get_int (structure, "divxversion", &divxversion);
1071       switch (divxversion) {
1072         case 3:
1073           fourcc = GST_MAKE_FOURCC ('D', 'I', 'V', '3');
1074           break;
1075         case 4:
1076           fourcc = GST_MAKE_FOURCC ('D', 'I', 'V', 'X');
1077           break;
1078         case 5:
1079           fourcc = GST_MAKE_FOURCC ('D', 'X', '5', '0');
1080           break;
1081       }
1082     } else if (!strcmp (mimetype, "video/x-msmpeg")) {
1083       gint msmpegversion;
1084
1085       gst_structure_get_int (structure, "msmpegversion", &msmpegversion);
1086       switch (msmpegversion) {
1087         case 41:
1088           fourcc = GST_MAKE_FOURCC ('M', 'P', 'G', '4');
1089           break;
1090         case 42:
1091           fourcc = GST_MAKE_FOURCC ('M', 'P', '4', '2');
1092           break;
1093         case 43:
1094           goto msmpeg43;
1095           break;
1096       }
1097     } else if (!strcmp (mimetype, "video/x-wmv")) {
1098       gint wmvversion;
1099       const gchar *fstr;
1100
1101       fstr = gst_structure_get_string (structure, "format");
1102       if (fstr && strlen (fstr) == 4) {
1103         fourcc = GST_STR_FOURCC (fstr);
1104       } else if (gst_structure_get_int (structure, "wmvversion", &wmvversion)) {
1105         if (wmvversion == 2) {
1106           fourcc = GST_MAKE_FOURCC ('W', 'M', 'V', '2');
1107         } else if (wmvversion == 1) {
1108           fourcc = GST_MAKE_FOURCC ('W', 'M', 'V', '1');
1109         } else if (wmvversion == 3) {
1110           fourcc = GST_MAKE_FOURCC ('W', 'M', 'V', '3');
1111         }
1112       }
1113     } else if (!strcmp (mimetype, "image/jpeg")) {
1114       fourcc = GST_MAKE_FOURCC ('M', 'J', 'P', 'G');
1115     }
1116
1117     if (!fourcc)
1118       goto refuse_caps;
1119
1120     bih = g_new0 (gst_riff_strf_vids, 1);
1121     GST_WRITE_UINT32_LE (&bih->size, size);
1122     GST_WRITE_UINT32_LE (&bih->width, videocontext->pixel_width);
1123     GST_WRITE_UINT32_LE (&bih->height, videocontext->pixel_height);
1124     GST_WRITE_UINT32_LE (&bih->compression, fourcc);
1125     GST_WRITE_UINT16_LE (&bih->planes, (guint16) 1);
1126     GST_WRITE_UINT16_LE (&bih->bit_cnt, (guint16) 24);
1127     GST_WRITE_UINT32_LE (&bih->image_size, videocontext->pixel_width *
1128         videocontext->pixel_height * 3);
1129
1130     /* process codec private/initialization data, if any */
1131     if (codec_buf) {
1132       size += gst_buffer_get_size (codec_buf);
1133       bih = g_realloc (bih, size);
1134       GST_WRITE_UINT32_LE (&bih->size, size);
1135       gst_buffer_extract (codec_buf, 0,
1136           (guint8 *) bih + sizeof (gst_riff_strf_vids), -1);
1137     }
1138
1139     gst_matroska_mux_set_codec_id (context,
1140         GST_MATROSKA_CODEC_ID_VIDEO_VFW_FOURCC);
1141     gst_matroska_mux_free_codec_priv (context);
1142     context->codec_priv = (gpointer) bih;
1143     context->codec_priv_size = size;
1144     context->dts_only = TRUE;
1145   } else if (!strcmp (mimetype, "video/x-h264")) {
1146     gst_matroska_mux_set_codec_id (context,
1147         GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AVC);
1148     gst_matroska_mux_free_codec_priv (context);
1149     /* Create avcC header */
1150     if (codec_buf != NULL) {
1151       context->codec_priv_size = gst_buffer_get_size (codec_buf);
1152       context->codec_priv = g_malloc0 (context->codec_priv_size);
1153       gst_buffer_extract (codec_buf, 0, context->codec_priv, -1);
1154     }
1155   } else if (!strcmp (mimetype, "video/x-h265")) {
1156     gst_matroska_mux_set_codec_id (context,
1157         GST_MATROSKA_CODEC_ID_VIDEO_MPEGH_HEVC);
1158     gst_matroska_mux_free_codec_priv (context);
1159     /* Create hvcC header */
1160     if (codec_buf != NULL) {
1161       context->codec_priv_size = gst_buffer_get_size (codec_buf);
1162       context->codec_priv = g_malloc0 (context->codec_priv_size);
1163       gst_buffer_extract (codec_buf, 0, context->codec_priv, -1);
1164     }
1165   } else if (!strcmp (mimetype, "video/x-theora")) {
1166     const GValue *streamheader;
1167
1168     gst_matroska_mux_set_codec_id (context, GST_MATROSKA_CODEC_ID_VIDEO_THEORA);
1169
1170     gst_matroska_mux_free_codec_priv (context);
1171
1172     streamheader = gst_structure_get_value (structure, "streamheader");
1173     if (!theora_streamheader_to_codecdata (streamheader, context)) {
1174       GST_ELEMENT_ERROR (mux, STREAM, MUX, (NULL),
1175           ("theora stream headers missing or malformed"));
1176       goto refuse_caps;
1177     }
1178   } else if (!strcmp (mimetype, "video/x-dirac")) {
1179     gst_matroska_mux_set_codec_id (context, GST_MATROSKA_CODEC_ID_VIDEO_DIRAC);
1180   } else if (!strcmp (mimetype, "video/x-vp8")) {
1181     gst_matroska_mux_set_codec_id (context, GST_MATROSKA_CODEC_ID_VIDEO_VP8);
1182   } else if (!strcmp (mimetype, "video/x-vp9")) {
1183     gst_matroska_mux_set_codec_id (context, GST_MATROSKA_CODEC_ID_VIDEO_VP9);
1184   } else if (!strcmp (mimetype, "video/mpeg")) {
1185     gint mpegversion;
1186
1187     gst_structure_get_int (structure, "mpegversion", &mpegversion);
1188     switch (mpegversion) {
1189       case 1:
1190         gst_matroska_mux_set_codec_id (context,
1191             GST_MATROSKA_CODEC_ID_VIDEO_MPEG1);
1192         break;
1193       case 2:
1194         gst_matroska_mux_set_codec_id (context,
1195             GST_MATROSKA_CODEC_ID_VIDEO_MPEG2);
1196         break;
1197       case 4:
1198         gst_matroska_mux_set_codec_id (context,
1199             GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP);
1200         break;
1201       default:
1202         goto refuse_caps;
1203     }
1204
1205     /* global headers may be in codec data */
1206     if (codec_buf != NULL) {
1207       gst_matroska_mux_free_codec_priv (context);
1208       context->codec_priv_size = gst_buffer_get_size (codec_buf);
1209       context->codec_priv = g_malloc0 (context->codec_priv_size);
1210       gst_buffer_extract (codec_buf, 0, context->codec_priv, -1);
1211     }
1212   } else if (!strcmp (mimetype, "video/x-msmpeg")) {
1213   msmpeg43:
1214     /* can only make it here if preceding case verified it was version 3 */
1215     gst_matroska_mux_set_codec_id (context,
1216         GST_MATROSKA_CODEC_ID_VIDEO_MSMPEG4V3);
1217   } else if (!strcmp (mimetype, "video/x-pn-realvideo")) {
1218     gint rmversion;
1219     const GValue *mdpr_data;
1220
1221     gst_structure_get_int (structure, "rmversion", &rmversion);
1222     switch (rmversion) {
1223       case 1:
1224         gst_matroska_mux_set_codec_id (context,
1225             GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1);
1226         break;
1227       case 2:
1228         gst_matroska_mux_set_codec_id (context,
1229             GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2);
1230         break;
1231       case 3:
1232         gst_matroska_mux_set_codec_id (context,
1233             GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3);
1234         break;
1235       case 4:
1236         gst_matroska_mux_set_codec_id (context,
1237             GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4);
1238         break;
1239       default:
1240         goto refuse_caps;
1241     }
1242
1243     mdpr_data = gst_structure_get_value (structure, "mdpr_data");
1244     if (mdpr_data != NULL) {
1245       guint8 *priv_data = NULL;
1246       guint priv_data_size = 0;
1247
1248       GstBuffer *codec_data_buf = g_value_peek_pointer (mdpr_data);
1249
1250       priv_data_size = gst_buffer_get_size (codec_data_buf);
1251       priv_data = g_malloc0 (priv_data_size);
1252
1253       gst_buffer_extract (codec_data_buf, 0, priv_data, -1);
1254
1255       gst_matroska_mux_free_codec_priv (context);
1256       context->codec_priv = priv_data;
1257       context->codec_priv_size = priv_data_size;
1258     }
1259   } else if (strcmp (mimetype, "video/x-prores") == 0) {
1260     const gchar *variant;
1261
1262     gst_matroska_mux_free_codec_priv (context);
1263
1264     variant = gst_structure_get_string (structure, "format");
1265     if (!variant || !g_strcmp0 (variant, "standard"))
1266       context->codec_priv = g_strdup ("apcn");
1267     else if (!g_strcmp0 (variant, "hq"))
1268       context->codec_priv = g_strdup ("apch");
1269     else if (!g_strcmp0 (variant, "lt"))
1270       context->codec_priv = g_strdup ("apcs");
1271     else if (!g_strcmp0 (variant, "proxy"))
1272       context->codec_priv = g_strdup ("apco");
1273     else if (!g_strcmp0 (variant, "4444"))
1274       context->codec_priv = g_strdup ("ap4h");
1275     else {
1276       GST_WARNING_OBJECT (mux, "Unhandled prores format: %s", variant);
1277
1278       goto refuse_caps;
1279     }
1280
1281     context->codec_priv_size = sizeof (guint32);
1282     gst_matroska_mux_set_codec_id (context, GST_MATROSKA_CODEC_ID_VIDEO_PRORES);
1283   }
1284
1285   return TRUE;
1286
1287   /* ERRORS */
1288 refuse_caps:
1289   {
1290     GST_WARNING_OBJECT (mux, "pad %s refused caps %" GST_PTR_FORMAT,
1291         GST_PAD_NAME (pad), caps);
1292     return FALSE;
1293   }
1294 }
1295
1296 /* N > 0 to expect a particular number of headers, negative if the
1297    number of headers is variable */
1298 static gboolean
1299 xiphN_streamheader_to_codecdata (const GValue * streamheader,
1300     GstMatroskaTrackContext * context, GstBuffer ** p_buf0, int N)
1301 {
1302   GstBuffer **buf = NULL;
1303   GArray *bufarr;
1304   guint8 *priv_data;
1305   guint bufi, i, offset, priv_data_size;
1306
1307   if (streamheader == NULL)
1308     goto no_stream_headers;
1309
1310   if (G_VALUE_TYPE (streamheader) != GST_TYPE_ARRAY)
1311     goto wrong_type;
1312
1313   bufarr = g_value_peek_pointer (streamheader);
1314   if (bufarr->len <= 0 || bufarr->len > 255)    /* at least one header, and count stored in a byte */
1315     goto wrong_count;
1316   if (N > 0 && bufarr->len != N)
1317     goto wrong_count;
1318
1319   context->xiph_headers_to_skip = bufarr->len;
1320
1321   buf = (GstBuffer **) g_malloc0 (sizeof (GstBuffer *) * bufarr->len);
1322   for (i = 0; i < bufarr->len; i++) {
1323     GValue *bufval = &g_array_index (bufarr, GValue, i);
1324
1325     if (G_VALUE_TYPE (bufval) != GST_TYPE_BUFFER) {
1326       g_free (buf);
1327       goto wrong_content_type;
1328     }
1329
1330     buf[i] = g_value_peek_pointer (bufval);
1331   }
1332
1333   priv_data_size = 1;
1334   if (bufarr->len > 0) {
1335     for (i = 0; i < bufarr->len - 1; i++) {
1336       priv_data_size += gst_buffer_get_size (buf[i]) / 0xff + 1;
1337     }
1338   }
1339
1340   for (i = 0; i < bufarr->len; ++i) {
1341     priv_data_size += gst_buffer_get_size (buf[i]);
1342   }
1343
1344   priv_data = g_malloc0 (priv_data_size);
1345
1346   priv_data[0] = bufarr->len - 1;
1347   offset = 1;
1348
1349   if (bufarr->len > 0) {
1350     for (bufi = 0; bufi < bufarr->len - 1; bufi++) {
1351       for (i = 0; i < gst_buffer_get_size (buf[bufi]) / 0xff; ++i) {
1352         priv_data[offset++] = 0xff;
1353       }
1354       priv_data[offset++] = gst_buffer_get_size (buf[bufi]) % 0xff;
1355     }
1356   }
1357
1358   for (i = 0; i < bufarr->len; ++i) {
1359     gst_buffer_extract (buf[i], 0, priv_data + offset, -1);
1360     offset += gst_buffer_get_size (buf[i]);
1361   }
1362
1363   gst_matroska_mux_free_codec_priv (context);
1364   context->codec_priv = priv_data;
1365   context->codec_priv_size = priv_data_size;
1366
1367   if (p_buf0)
1368     *p_buf0 = gst_buffer_ref (buf[0]);
1369
1370   g_free (buf);
1371
1372   return TRUE;
1373
1374 /* ERRORS */
1375 no_stream_headers:
1376   {
1377     GST_WARNING ("required streamheaders missing in sink caps!");
1378     return FALSE;
1379   }
1380 wrong_type:
1381   {
1382     GST_WARNING ("streamheaders are not a GST_TYPE_ARRAY, but a %s",
1383         G_VALUE_TYPE_NAME (streamheader));
1384     return FALSE;
1385   }
1386 wrong_count:
1387   {
1388     GST_WARNING ("got %u streamheaders, not %d as expected", bufarr->len, N);
1389     return FALSE;
1390   }
1391 wrong_content_type:
1392   {
1393     GST_WARNING ("streamheaders array does not contain GstBuffers");
1394     return FALSE;
1395   }
1396 }
1397
1398 static gboolean
1399 vorbis_streamheader_to_codecdata (const GValue * streamheader,
1400     GstMatroskaTrackContext * context)
1401 {
1402   GstBuffer *buf0 = NULL;
1403
1404   if (!xiphN_streamheader_to_codecdata (streamheader, context, &buf0, 3))
1405     return FALSE;
1406
1407   if (buf0 == NULL || gst_buffer_get_size (buf0) < 1 + 6 + 4) {
1408     GST_WARNING ("First vorbis header too small, ignoring");
1409   } else {
1410     if (gst_buffer_memcmp (buf0, 1, "vorbis", 6) == 0) {
1411       GstMatroskaTrackAudioContext *audiocontext;
1412       GstMapInfo map;
1413       guint8 *hdr;
1414
1415       gst_buffer_map (buf0, &map, GST_MAP_READ);
1416       hdr = map.data + 1 + 6 + 4;
1417       audiocontext = (GstMatroskaTrackAudioContext *) context;
1418       audiocontext->channels = GST_READ_UINT8 (hdr);
1419       audiocontext->samplerate = GST_READ_UINT32_LE (hdr + 1);
1420       gst_buffer_unmap (buf0, &map);
1421     }
1422   }
1423
1424   if (buf0)
1425     gst_buffer_unref (buf0);
1426
1427   return TRUE;
1428 }
1429
1430 static gboolean
1431 theora_streamheader_to_codecdata (const GValue * streamheader,
1432     GstMatroskaTrackContext * context)
1433 {
1434   GstBuffer *buf0 = NULL;
1435
1436   if (!xiphN_streamheader_to_codecdata (streamheader, context, &buf0, 3))
1437     return FALSE;
1438
1439   if (buf0 == NULL || gst_buffer_get_size (buf0) < 1 + 6 + 26) {
1440     GST_WARNING ("First theora header too small, ignoring");
1441   } else if (gst_buffer_memcmp (buf0, 0, "\200theora\003\002", 9) != 0) {
1442     GST_WARNING ("First header not a theora identification header, ignoring");
1443   } else {
1444     GstMatroskaTrackVideoContext *videocontext;
1445     guint fps_num, fps_denom, par_num, par_denom;
1446     GstMapInfo map;
1447     guint8 *hdr;
1448
1449     gst_buffer_map (buf0, &map, GST_MAP_READ);
1450     hdr = map.data + 1 + 6 + 3 + 2 + 2;
1451
1452     videocontext = (GstMatroskaTrackVideoContext *) context;
1453     videocontext->pixel_width = GST_READ_UINT32_BE (hdr) >> 8;
1454     videocontext->pixel_height = GST_READ_UINT32_BE (hdr + 3) >> 8;
1455     hdr += 3 + 3 + 1 + 1;
1456     fps_num = GST_READ_UINT32_BE (hdr);
1457     fps_denom = GST_READ_UINT32_BE (hdr + 4);
1458     context->default_duration = gst_util_uint64_scale_int (GST_SECOND,
1459         fps_denom, fps_num);
1460     hdr += 4 + 4;
1461     par_num = GST_READ_UINT32_BE (hdr) >> 8;
1462     par_denom = GST_READ_UINT32_BE (hdr + 3) >> 8;
1463     if (par_num > 0 && par_denom > 0) {
1464       if (par_num > par_denom) {
1465         videocontext->display_width =
1466             videocontext->pixel_width * par_num / par_denom;
1467         videocontext->display_height = videocontext->pixel_height;
1468       } else if (par_num < par_denom) {
1469         videocontext->display_width = videocontext->pixel_width;
1470         videocontext->display_height =
1471             videocontext->pixel_height * par_denom / par_num;
1472       } else {
1473         videocontext->display_width = 0;
1474         videocontext->display_height = 0;
1475       }
1476     } else {
1477       videocontext->display_width = 0;
1478       videocontext->display_height = 0;
1479     }
1480
1481     gst_buffer_unmap (buf0, &map);
1482   }
1483
1484   if (buf0)
1485     gst_buffer_unref (buf0);
1486
1487   return TRUE;
1488 }
1489
1490 static gboolean
1491 kate_streamheader_to_codecdata (const GValue * streamheader,
1492     GstMatroskaTrackContext * context)
1493 {
1494   GstBuffer *buf0 = NULL;
1495
1496   if (!xiphN_streamheader_to_codecdata (streamheader, context, &buf0, -1))
1497     return FALSE;
1498
1499   if (buf0 == NULL || gst_buffer_get_size (buf0) < 64) {        /* Kate ID header is 64 bytes */
1500     GST_WARNING ("First kate header too small, ignoring");
1501   } else if (gst_buffer_memcmp (buf0, 0, "\200kate\0\0\0", 8) != 0) {
1502     GST_WARNING ("First header not a kate identification header, ignoring");
1503   }
1504
1505   if (buf0)
1506     gst_buffer_unref (buf0);
1507
1508   return TRUE;
1509 }
1510
1511 static gboolean
1512 flac_streamheader_to_codecdata (const GValue * streamheader,
1513     GstMatroskaTrackContext * context)
1514 {
1515   GArray *bufarr;
1516   gint i;
1517   GValue *bufval;
1518   GstBuffer *buffer;
1519
1520   if (streamheader == NULL || G_VALUE_TYPE (streamheader) != GST_TYPE_ARRAY) {
1521     GST_WARNING ("No or invalid streamheader field in the caps");
1522     return FALSE;
1523   }
1524
1525   bufarr = g_value_peek_pointer (streamheader);
1526   if (bufarr->len < 2) {
1527     GST_WARNING ("Too few headers in streamheader field");
1528     return FALSE;
1529   }
1530
1531   context->xiph_headers_to_skip = bufarr->len + 1;
1532
1533   bufval = &g_array_index (bufarr, GValue, 0);
1534   if (G_VALUE_TYPE (bufval) != GST_TYPE_BUFFER) {
1535     GST_WARNING ("streamheaders array does not contain GstBuffers");
1536     return FALSE;
1537   }
1538
1539   buffer = g_value_peek_pointer (bufval);
1540
1541   /* Need at least OggFLAC mapping header, fLaC marker and STREAMINFO block */
1542   if (gst_buffer_get_size (buffer) < 9 + 4 + 4 + 34
1543       || gst_buffer_memcmp (buffer, 1, "FLAC", 4) != 0
1544       || gst_buffer_memcmp (buffer, 9, "fLaC", 4) != 0) {
1545     GST_WARNING ("Invalid streamheader for FLAC");
1546     return FALSE;
1547   }
1548
1549   gst_matroska_mux_free_codec_priv (context);
1550   context->codec_priv_size = gst_buffer_get_size (buffer) - 9;
1551   context->codec_priv = g_malloc (context->codec_priv_size);
1552   gst_buffer_extract (buffer, 9, context->codec_priv, -1);
1553
1554   for (i = 1; i < bufarr->len; i++) {
1555     guint old_size;
1556     bufval = &g_array_index (bufarr, GValue, i);
1557
1558     if (G_VALUE_TYPE (bufval) != GST_TYPE_BUFFER) {
1559       gst_matroska_mux_free_codec_priv (context);
1560       GST_WARNING ("streamheaders array does not contain GstBuffers");
1561       return FALSE;
1562     }
1563
1564     buffer = g_value_peek_pointer (bufval);
1565
1566     old_size = context->codec_priv_size;
1567     context->codec_priv_size += gst_buffer_get_size (buffer);
1568
1569     context->codec_priv = g_realloc (context->codec_priv,
1570         context->codec_priv_size);
1571     gst_buffer_extract (buffer, 0,
1572         (guint8 *) context->codec_priv + old_size, -1);
1573   }
1574
1575   return TRUE;
1576 }
1577
1578 static gboolean
1579 speex_streamheader_to_codecdata (const GValue * streamheader,
1580     GstMatroskaTrackContext * context)
1581 {
1582   GArray *bufarr;
1583   GValue *bufval;
1584   GstBuffer *buffer;
1585   guint old_size;
1586
1587   if (streamheader == NULL || G_VALUE_TYPE (streamheader) != GST_TYPE_ARRAY) {
1588     GST_WARNING ("No or invalid streamheader field in the caps");
1589     return FALSE;
1590   }
1591
1592   bufarr = g_value_peek_pointer (streamheader);
1593   if (bufarr->len != 2) {
1594     GST_WARNING ("Too few headers in streamheader field");
1595     return FALSE;
1596   }
1597
1598   context->xiph_headers_to_skip = bufarr->len + 1;
1599
1600   bufval = &g_array_index (bufarr, GValue, 0);
1601   if (G_VALUE_TYPE (bufval) != GST_TYPE_BUFFER) {
1602     GST_WARNING ("streamheaders array does not contain GstBuffers");
1603     return FALSE;
1604   }
1605
1606   buffer = g_value_peek_pointer (bufval);
1607
1608   if (gst_buffer_get_size (buffer) < 80
1609       || gst_buffer_memcmp (buffer, 0, "Speex   ", 8) != 0) {
1610     GST_WARNING ("Invalid streamheader for Speex");
1611     return FALSE;
1612   }
1613
1614   gst_matroska_mux_free_codec_priv (context);
1615   context->codec_priv_size = gst_buffer_get_size (buffer);
1616   context->codec_priv = g_malloc (context->codec_priv_size);
1617   gst_buffer_extract (buffer, 0, context->codec_priv, -1);
1618
1619   bufval = &g_array_index (bufarr, GValue, 1);
1620
1621   if (G_VALUE_TYPE (bufval) != GST_TYPE_BUFFER) {
1622     gst_matroska_mux_free_codec_priv (context);
1623     GST_WARNING ("streamheaders array does not contain GstBuffers");
1624     return FALSE;
1625   }
1626
1627   buffer = g_value_peek_pointer (bufval);
1628
1629   old_size = context->codec_priv_size;
1630   context->codec_priv_size += gst_buffer_get_size (buffer);
1631   context->codec_priv = g_realloc (context->codec_priv,
1632       context->codec_priv_size);
1633   gst_buffer_extract (buffer, 0, (guint8 *) context->codec_priv + old_size, -1);
1634
1635   return TRUE;
1636 }
1637
1638 static gboolean
1639 opus_streamheader_to_codecdata (const GValue * streamheader,
1640     GstMatroskaTrackContext * context)
1641 {
1642   GArray *bufarr;
1643   GValue *bufval;
1644   GstBuffer *buf;
1645
1646   if (G_VALUE_TYPE (streamheader) != GST_TYPE_ARRAY)
1647     goto wrong_type;
1648
1649   bufarr = g_value_peek_pointer (streamheader);
1650   if (bufarr->len != 1 && bufarr->len != 2)     /* one header, and count stored in a byte */
1651     goto wrong_count;
1652
1653   /* Opus headers are not in-band */
1654   context->xiph_headers_to_skip = 0;
1655
1656   bufval = &g_array_index (bufarr, GValue, 0);
1657   if (G_VALUE_TYPE (bufval) != GST_TYPE_BUFFER) {
1658     goto wrong_content_type;
1659   }
1660   buf = g_value_peek_pointer (bufval);
1661
1662   gst_matroska_mux_free_codec_priv (context);
1663
1664   context->codec_priv_size = gst_buffer_get_size (buf);
1665   context->codec_priv = g_malloc0 (context->codec_priv_size);
1666   gst_buffer_extract (buf, 0, context->codec_priv, -1);
1667
1668   context->codec_delay =
1669       GST_READ_UINT16_LE ((guint8 *) context->codec_priv + 10);
1670   context->codec_delay =
1671       gst_util_uint64_scale_round (context->codec_delay, GST_SECOND, 48000);
1672   context->seek_preroll = 80 * GST_MSECOND;
1673
1674   return TRUE;
1675
1676 /* ERRORS */
1677 wrong_type:
1678   {
1679     GST_WARNING ("streamheaders are not a GST_TYPE_ARRAY, but a %s",
1680         G_VALUE_TYPE_NAME (streamheader));
1681     return FALSE;
1682   }
1683 wrong_count:
1684   {
1685     GST_WARNING ("got %u streamheaders, not 1 or 2 as expected", bufarr->len);
1686     return FALSE;
1687   }
1688 wrong_content_type:
1689   {
1690     GST_WARNING ("streamheaders array does not contain GstBuffers");
1691     return FALSE;
1692   }
1693 }
1694
1695 static gboolean
1696 opus_make_codecdata (GstMatroskaTrackContext * context, GstCaps * caps)
1697 {
1698   guint32 rate;
1699   guint8 channels;
1700   guint8 channel_mapping_family;
1701   guint8 stream_count, coupled_count, channel_mapping[256];
1702   GstBuffer *buffer;
1703   GstMapInfo map;
1704
1705   /* Opus headers are not in-band */
1706   context->xiph_headers_to_skip = 0;
1707
1708   context->codec_delay = 0;
1709   context->seek_preroll = 80 * GST_MSECOND;
1710
1711   if (!gst_codec_utils_opus_parse_caps (caps, &rate, &channels,
1712           &channel_mapping_family, &stream_count, &coupled_count,
1713           channel_mapping)) {
1714     GST_WARNING ("Failed to parse caps for Opus");
1715     return FALSE;
1716   }
1717
1718   buffer =
1719       gst_codec_utils_opus_create_header (rate, channels,
1720       channel_mapping_family, stream_count, coupled_count, channel_mapping, 0,
1721       0);
1722   if (!buffer) {
1723     GST_WARNING ("Failed to create Opus header from caps");
1724     return FALSE;
1725   }
1726
1727   gst_buffer_map (buffer, &map, GST_MAP_READ);
1728   context->codec_priv_size = map.size;
1729   context->codec_priv = g_malloc (context->codec_priv_size);
1730   memcpy (context->codec_priv, map.data, map.size);
1731   gst_buffer_unmap (buffer, &map);
1732   gst_buffer_unref (buffer);
1733
1734   return TRUE;
1735 }
1736
1737 /**
1738  * gst_matroska_mux_audio_pad_setcaps:
1739  * @pad: Pad which got the caps.
1740  * @caps: New caps.
1741  *
1742  * Setcaps function for audio sink pad.
1743  *
1744  * Returns: #TRUE on success.
1745  */
1746 static gboolean
1747 gst_matroska_mux_audio_pad_setcaps (GstPad * pad, GstCaps * caps)
1748 {
1749   GstMatroskaTrackContext *context = NULL;
1750   GstMatroskaTrackAudioContext *audiocontext;
1751   GstMatroskaMux *mux;
1752   GstMatroskaPad *collect_pad;
1753   const gchar *mimetype;
1754   gint samplerate = 0, channels = 0;
1755   GstStructure *structure;
1756   const GValue *codec_data = NULL;
1757   GstBuffer *buf = NULL;
1758   const gchar *stream_format = NULL;
1759
1760   mux = GST_MATROSKA_MUX (GST_PAD_PARENT (pad));
1761
1762   /* find context */
1763   collect_pad = (GstMatroskaPad *) gst_pad_get_element_private (pad);
1764   g_assert (collect_pad);
1765   context = collect_pad->track;
1766   g_assert (context);
1767   g_assert (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO);
1768   audiocontext = (GstMatroskaTrackAudioContext *) context;
1769
1770   structure = gst_caps_get_structure (caps, 0);
1771   mimetype = gst_structure_get_name (structure);
1772
1773   /* general setup */
1774   gst_structure_get_int (structure, "rate", &samplerate);
1775   gst_structure_get_int (structure, "channels", &channels);
1776
1777   audiocontext->samplerate = samplerate;
1778   audiocontext->channels = channels;
1779   audiocontext->bitdepth = 0;
1780   context->default_duration = 0;
1781
1782   codec_data = gst_structure_get_value (structure, "codec_data");
1783   if (codec_data)
1784     buf = gst_value_get_buffer (codec_data);
1785
1786   /* TODO: - check if we handle all codecs by the spec, i.e. codec private
1787    *         data and other settings
1788    *       - add new formats
1789    */
1790
1791   if (!strcmp (mimetype, "audio/mpeg")) {
1792     gint mpegversion = 0;
1793
1794     gst_structure_get_int (structure, "mpegversion", &mpegversion);
1795     switch (mpegversion) {
1796       case 1:{
1797         gint layer;
1798         gint version = 1;
1799         gint spf;
1800
1801         gst_structure_get_int (structure, "layer", &layer);
1802
1803         if (!gst_structure_get_int (structure, "mpegaudioversion", &version)) {
1804           GST_WARNING_OBJECT (mux,
1805               "Unable to determine MPEG audio version, assuming 1");
1806           version = 1;
1807         }
1808
1809         if (layer == 1)
1810           spf = 384;
1811         else if (layer == 2)
1812           spf = 1152;
1813         else if (version == 2)
1814           spf = 576;
1815         else
1816           spf = 1152;
1817
1818         context->default_duration =
1819             gst_util_uint64_scale (GST_SECOND, spf, audiocontext->samplerate);
1820
1821         switch (layer) {
1822           case 1:
1823             gst_matroska_mux_set_codec_id (context,
1824                 GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1);
1825             break;
1826           case 2:
1827             gst_matroska_mux_set_codec_id (context,
1828                 GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2);
1829             break;
1830           case 3:
1831             gst_matroska_mux_set_codec_id (context,
1832                 GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L3);
1833             break;
1834           default:
1835             goto refuse_caps;
1836         }
1837         break;
1838       }
1839       case 2:
1840       case 4:
1841         stream_format = gst_structure_get_string (structure, "stream-format");
1842         /* check this is raw aac */
1843         if (stream_format) {
1844           if (strcmp (stream_format, "raw") != 0) {
1845             GST_WARNING_OBJECT (mux, "AAC stream-format must be 'raw', not %s",
1846                 stream_format);
1847           }
1848         } else {
1849           GST_WARNING_OBJECT (mux, "AAC stream-format not specified, "
1850               "assuming 'raw'");
1851         }
1852
1853         if (buf) {
1854           gst_matroska_mux_set_codec_id (context,
1855               GST_MATROSKA_CODEC_ID_AUDIO_AAC);
1856           context->codec_priv_size = gst_buffer_get_size (buf);
1857           context->codec_priv = g_malloc (context->codec_priv_size);
1858           gst_buffer_extract (buf, 0, context->codec_priv,
1859               context->codec_priv_size);
1860         } else {
1861           GST_DEBUG_OBJECT (mux, "no AAC codec_data; not packetized");
1862           goto refuse_caps;
1863         }
1864         break;
1865       default:
1866         goto refuse_caps;
1867     }
1868   } else if (!strcmp (mimetype, "audio/x-raw")) {
1869     GstAudioInfo info;
1870
1871     gst_audio_info_init (&info);
1872     if (!gst_audio_info_from_caps (&info, caps)) {
1873       GST_DEBUG_OBJECT (mux,
1874           "broken caps, rejected by gst_audio_info_from_caps");
1875       goto refuse_caps;
1876     }
1877
1878     switch (GST_AUDIO_INFO_FORMAT (&info)) {
1879       case GST_AUDIO_FORMAT_U8:
1880       case GST_AUDIO_FORMAT_S16BE:
1881       case GST_AUDIO_FORMAT_S16LE:
1882       case GST_AUDIO_FORMAT_S24BE:
1883       case GST_AUDIO_FORMAT_S24LE:
1884       case GST_AUDIO_FORMAT_S32BE:
1885       case GST_AUDIO_FORMAT_S32LE:
1886         if (GST_AUDIO_INFO_WIDTH (&info) != GST_AUDIO_INFO_DEPTH (&info)) {
1887           GST_DEBUG_OBJECT (mux, "width must be same as depth!");
1888           goto refuse_caps;
1889         }
1890         if (GST_AUDIO_INFO_IS_BIG_ENDIAN (&info))
1891           gst_matroska_mux_set_codec_id (context,
1892               GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE);
1893         else
1894           gst_matroska_mux_set_codec_id (context,
1895               GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_LE);
1896         break;
1897       case GST_AUDIO_FORMAT_F32LE:
1898       case GST_AUDIO_FORMAT_F64LE:
1899         gst_matroska_mux_set_codec_id (context,
1900             GST_MATROSKA_CODEC_ID_AUDIO_PCM_FLOAT);
1901         break;
1902
1903       default:
1904         GST_DEBUG_OBJECT (mux, "wrong format in raw audio caps");
1905         goto refuse_caps;
1906     }
1907
1908     audiocontext->bitdepth = GST_AUDIO_INFO_WIDTH (&info);
1909   } else if (!strcmp (mimetype, "audio/x-vorbis")) {
1910     const GValue *streamheader;
1911
1912     gst_matroska_mux_set_codec_id (context, GST_MATROSKA_CODEC_ID_AUDIO_VORBIS);
1913
1914     gst_matroska_mux_free_codec_priv (context);
1915
1916     streamheader = gst_structure_get_value (structure, "streamheader");
1917     if (!vorbis_streamheader_to_codecdata (streamheader, context)) {
1918       GST_ELEMENT_ERROR (mux, STREAM, MUX, (NULL),
1919           ("vorbis stream headers missing or malformed"));
1920       goto refuse_caps;
1921     }
1922   } else if (!strcmp (mimetype, "audio/x-flac")) {
1923     const GValue *streamheader;
1924
1925     gst_matroska_mux_set_codec_id (context, GST_MATROSKA_CODEC_ID_AUDIO_FLAC);
1926
1927     gst_matroska_mux_free_codec_priv (context);
1928
1929     streamheader = gst_structure_get_value (structure, "streamheader");
1930     if (!flac_streamheader_to_codecdata (streamheader, context)) {
1931       GST_ELEMENT_ERROR (mux, STREAM, MUX, (NULL),
1932           ("flac stream headers missing or malformed"));
1933       goto refuse_caps;
1934     }
1935   } else if (!strcmp (mimetype, "audio/x-speex")) {
1936     const GValue *streamheader;
1937
1938     gst_matroska_mux_set_codec_id (context, GST_MATROSKA_CODEC_ID_AUDIO_SPEEX);
1939     gst_matroska_mux_free_codec_priv (context);
1940
1941     streamheader = gst_structure_get_value (structure, "streamheader");
1942     if (!speex_streamheader_to_codecdata (streamheader, context)) {
1943       GST_ELEMENT_ERROR (mux, STREAM, MUX, (NULL),
1944           ("speex stream headers missing or malformed"));
1945       goto refuse_caps;
1946     }
1947   } else if (!strcmp (mimetype, "audio/x-opus")) {
1948     const GValue *streamheader;
1949
1950     gst_matroska_mux_set_codec_id (context, GST_MATROSKA_CODEC_ID_AUDIO_OPUS);
1951
1952     streamheader = gst_structure_get_value (structure, "streamheader");
1953     if (streamheader) {
1954       gst_matroska_mux_free_codec_priv (context);
1955       if (!opus_streamheader_to_codecdata (streamheader, context)) {
1956         GST_ELEMENT_ERROR (mux, STREAM, MUX, (NULL),
1957             ("opus stream headers missing or malformed"));
1958         goto refuse_caps;
1959       }
1960     } else {
1961       /* no streamheader, but we need to have one, so we make one up
1962          based on caps */
1963       gst_matroska_mux_free_codec_priv (context);
1964       if (!opus_make_codecdata (context, caps)) {
1965         GST_ELEMENT_ERROR (mux, STREAM, MUX, (NULL),
1966             ("opus stream headers missing or malformed"));
1967         goto refuse_caps;
1968       }
1969     }
1970   } else if (!strcmp (mimetype, "audio/x-ac3")) {
1971     gst_matroska_mux_set_codec_id (context, GST_MATROSKA_CODEC_ID_AUDIO_AC3);
1972   } else if (!strcmp (mimetype, "audio/x-eac3")) {
1973     gst_matroska_mux_set_codec_id (context, GST_MATROSKA_CODEC_ID_AUDIO_EAC3);
1974   } else if (!strcmp (mimetype, "audio/x-dts")) {
1975     gst_matroska_mux_set_codec_id (context, GST_MATROSKA_CODEC_ID_AUDIO_DTS);
1976   } else if (!strcmp (mimetype, "audio/x-tta")) {
1977     gint width;
1978
1979     /* TTA frame duration */
1980     context->default_duration = 1.04489795918367346939 * GST_SECOND;
1981
1982     gst_structure_get_int (structure, "width", &width);
1983     audiocontext->bitdepth = width;
1984     gst_matroska_mux_set_codec_id (context, GST_MATROSKA_CODEC_ID_AUDIO_TTA);
1985
1986   } else if (!strcmp (mimetype, "audio/x-pn-realaudio")) {
1987     gint raversion;
1988     const GValue *mdpr_data;
1989
1990     gst_structure_get_int (structure, "raversion", &raversion);
1991     switch (raversion) {
1992       case 1:
1993         gst_matroska_mux_set_codec_id (context,
1994             GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4);
1995         break;
1996       case 2:
1997         gst_matroska_mux_set_codec_id (context,
1998             GST_MATROSKA_CODEC_ID_AUDIO_REAL_28_8);
1999         break;
2000       case 8:
2001         gst_matroska_mux_set_codec_id (context,
2002             GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK);
2003         break;
2004       default:
2005         goto refuse_caps;
2006     }
2007
2008     mdpr_data = gst_structure_get_value (structure, "mdpr_data");
2009     if (mdpr_data != NULL) {
2010       guint8 *priv_data = NULL;
2011       guint priv_data_size = 0;
2012
2013       GstBuffer *codec_data_buf = g_value_peek_pointer (mdpr_data);
2014
2015       priv_data_size = gst_buffer_get_size (codec_data_buf);
2016       priv_data = g_malloc0 (priv_data_size);
2017
2018       gst_buffer_extract (codec_data_buf, 0, priv_data, -1);
2019
2020       gst_matroska_mux_free_codec_priv (context);
2021
2022       context->codec_priv = priv_data;
2023       context->codec_priv_size = priv_data_size;
2024     }
2025
2026   } else if (!strcmp (mimetype, "audio/x-wma")
2027       || !strcmp (mimetype, "audio/x-alaw")
2028       || !strcmp (mimetype, "audio/x-mulaw")
2029       || !strcmp (mimetype, "audio/x-adpcm")
2030       || !strcmp (mimetype, "audio/G722")) {
2031     guint8 *codec_priv;
2032     guint codec_priv_size;
2033     guint16 format = 0;
2034     gint block_align = 0;
2035     gint bitrate = 0;
2036
2037     if (samplerate == 0 || channels == 0) {
2038       GST_WARNING_OBJECT (mux, "Missing channels/samplerate on caps");
2039       goto refuse_caps;
2040     }
2041
2042     if (!strcmp (mimetype, "audio/x-wma")) {
2043       gint wmaversion;
2044       gint depth;
2045
2046       if (!gst_structure_get_int (structure, "wmaversion", &wmaversion)
2047           || !gst_structure_get_int (structure, "block_align", &block_align)
2048           || !gst_structure_get_int (structure, "bitrate", &bitrate)) {
2049         GST_WARNING_OBJECT (mux, "Missing wmaversion/block_align/bitrate"
2050             " on WMA caps");
2051         goto refuse_caps;
2052       }
2053
2054       switch (wmaversion) {
2055         case 1:
2056           format = GST_RIFF_WAVE_FORMAT_WMAV1;
2057           break;
2058         case 2:
2059           format = GST_RIFF_WAVE_FORMAT_WMAV2;
2060           break;
2061         case 3:
2062           format = GST_RIFF_WAVE_FORMAT_WMAV3;
2063           break;
2064         default:
2065           GST_WARNING_OBJECT (mux, "Unexpected WMA version: %d", wmaversion);
2066           goto refuse_caps;
2067       }
2068
2069       if (gst_structure_get_int (structure, "depth", &depth))
2070         audiocontext->bitdepth = depth;
2071     } else if (!strcmp (mimetype, "audio/x-alaw")
2072         || !strcmp (mimetype, "audio/x-mulaw")) {
2073       audiocontext->bitdepth = 8;
2074       if (!strcmp (mimetype, "audio/x-alaw"))
2075         format = GST_RIFF_WAVE_FORMAT_ALAW;
2076       else
2077         format = GST_RIFF_WAVE_FORMAT_MULAW;
2078
2079       block_align = channels;
2080       bitrate = block_align * samplerate;
2081     } else if (!strcmp (mimetype, "audio/x-adpcm")) {
2082       const char *layout;
2083
2084       layout = gst_structure_get_string (structure, "layout");
2085       if (!layout) {
2086         GST_WARNING_OBJECT (mux, "Missing layout on adpcm caps");
2087         goto refuse_caps;
2088       }
2089
2090       if (!gst_structure_get_int (structure, "block_align", &block_align)) {
2091         GST_WARNING_OBJECT (mux, "Missing block_align on adpcm caps");
2092         goto refuse_caps;
2093       }
2094
2095       if (!strcmp (layout, "dvi")) {
2096         format = GST_RIFF_WAVE_FORMAT_DVI_ADPCM;
2097       } else if (!strcmp (layout, "g726")) {
2098         format = GST_RIFF_WAVE_FORMAT_ITU_G726_ADPCM;
2099         if (!gst_structure_get_int (structure, "bitrate", &bitrate)) {
2100           GST_WARNING_OBJECT (mux, "Missing bitrate on adpcm g726 caps");
2101           goto refuse_caps;
2102         }
2103       } else {
2104         GST_WARNING_OBJECT (mux, "Unknown layout on adpcm caps");
2105         goto refuse_caps;
2106       }
2107
2108     } else if (!strcmp (mimetype, "audio/G722")) {
2109       format = GST_RIFF_WAVE_FORMAT_ADPCM_G722;
2110     }
2111     g_assert (format != 0);
2112
2113     codec_priv_size = WAVEFORMATEX_SIZE;
2114     if (buf)
2115       codec_priv_size += gst_buffer_get_size (buf);
2116
2117     /* serialize waveformatex structure */
2118     codec_priv = g_malloc0 (codec_priv_size);
2119     GST_WRITE_UINT16_LE (codec_priv, format);
2120     GST_WRITE_UINT16_LE (codec_priv + 2, channels);
2121     GST_WRITE_UINT32_LE (codec_priv + 4, samplerate);
2122     GST_WRITE_UINT32_LE (codec_priv + 8, bitrate / 8);
2123     GST_WRITE_UINT16_LE (codec_priv + 12, block_align);
2124     GST_WRITE_UINT16_LE (codec_priv + 14, 0);
2125     if (buf)
2126       GST_WRITE_UINT16_LE (codec_priv + 16, gst_buffer_get_size (buf));
2127     else
2128       GST_WRITE_UINT16_LE (codec_priv + 16, 0);
2129
2130     /* process codec private/initialization data, if any */
2131     if (buf) {
2132       gst_buffer_extract (buf, 0,
2133           (guint8 *) codec_priv + WAVEFORMATEX_SIZE, -1);
2134     }
2135
2136     gst_matroska_mux_set_codec_id (context, GST_MATROSKA_CODEC_ID_AUDIO_ACM);
2137     gst_matroska_mux_free_codec_priv (context);
2138     context->codec_priv = (gpointer) codec_priv;
2139     context->codec_priv_size = codec_priv_size;
2140   }
2141
2142   return TRUE;
2143
2144   /* ERRORS */
2145 refuse_caps:
2146   {
2147     GST_WARNING_OBJECT (mux, "pad %s refused caps %" GST_PTR_FORMAT,
2148         GST_PAD_NAME (pad), caps);
2149     return FALSE;
2150   }
2151 }
2152
2153 /* we probably don't have the data at start,
2154  * so have to reserve (a maximum) space to write this at the end.
2155  * bit spacy, but some formats can hold quite some */
2156 #define SUBTITLE_MAX_CODEC_PRIVATE   2048       /* must be > 128 */
2157
2158 /**
2159  * gst_matroska_mux_subtitle_pad_setcaps:
2160  * @pad: Pad which got the caps.
2161  * @caps: New caps.
2162  *
2163  * Setcaps function for subtitle sink pad.
2164  *
2165  * Returns: #TRUE on success.
2166  */
2167 static gboolean
2168 gst_matroska_mux_subtitle_pad_setcaps (GstPad * pad, GstCaps * caps)
2169 {
2170   /* There is now (at least) one such alement (kateenc), and I'm going
2171      to handle it here and claim it works when it can be piped back
2172      through GStreamer and VLC */
2173
2174   GstMatroskaTrackContext *context = NULL;
2175   GstMatroskaTrackSubtitleContext *scontext;
2176   GstMatroskaMux *mux;
2177   GstMatroskaPad *collect_pad;
2178   const gchar *mimetype;
2179   GstStructure *structure;
2180   const GValue *value = NULL;
2181   GstBuffer *buf = NULL;
2182   gboolean ret = TRUE;
2183
2184   mux = GST_MATROSKA_MUX (GST_PAD_PARENT (pad));
2185
2186   /* find context */
2187   collect_pad = (GstMatroskaPad *) gst_pad_get_element_private (pad);
2188   g_assert (collect_pad);
2189   context = collect_pad->track;
2190   g_assert (context);
2191   g_assert (context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE);
2192   scontext = (GstMatroskaTrackSubtitleContext *) context;
2193
2194   structure = gst_caps_get_structure (caps, 0);
2195   mimetype = gst_structure_get_name (structure);
2196
2197   /* general setup */
2198   scontext->check_utf8 = 1;
2199   scontext->invalid_utf8 = 0;
2200   context->default_duration = 0;
2201
2202   if (!strcmp (mimetype, "subtitle/x-kate")) {
2203     const GValue *streamheader;
2204
2205     gst_matroska_mux_set_codec_id (context,
2206         GST_MATROSKA_CODEC_ID_SUBTITLE_KATE);
2207
2208     gst_matroska_mux_free_codec_priv (context);
2209
2210     streamheader = gst_structure_get_value (structure, "streamheader");
2211     if (!kate_streamheader_to_codecdata (streamheader, context)) {
2212       GST_ELEMENT_ERROR (mux, STREAM, MUX, (NULL),
2213           ("kate stream headers missing or malformed"));
2214       ret = FALSE;
2215       goto exit;
2216     }
2217   } else if (!strcmp (mimetype, "text/x-raw")) {
2218     gst_matroska_mux_set_codec_id (context,
2219         GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8);
2220   } else if (!strcmp (mimetype, "application/x-ssa")) {
2221     gst_matroska_mux_set_codec_id (context, GST_MATROSKA_CODEC_ID_SUBTITLE_SSA);
2222   } else if (!strcmp (mimetype, "application/x-ass")) {
2223     gst_matroska_mux_set_codec_id (context, GST_MATROSKA_CODEC_ID_SUBTITLE_ASS);
2224   } else if (!strcmp (mimetype, "application/x-usf")) {
2225     gst_matroska_mux_set_codec_id (context, GST_MATROSKA_CODEC_ID_SUBTITLE_USF);
2226   } else if (!strcmp (mimetype, "subpicture/x-dvd")) {
2227     gst_matroska_mux_set_codec_id (context,
2228         GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB);
2229   } else {
2230     ret = FALSE;
2231     goto exit;
2232   }
2233
2234   /* maybe some private data, e.g. vobsub */
2235   value = gst_structure_get_value (structure, "codec_data");
2236   if (value)
2237     buf = gst_value_get_buffer (value);
2238   if (buf != NULL) {
2239     GstMapInfo map;
2240     guint8 *priv_data = NULL;
2241
2242     gst_buffer_map (buf, &map, GST_MAP_READ);
2243
2244     if (map.size > SUBTITLE_MAX_CODEC_PRIVATE) {
2245       GST_WARNING_OBJECT (mux, "pad %" GST_PTR_FORMAT " subtitle private data"
2246           " exceeded maximum (%d); discarding", pad,
2247           SUBTITLE_MAX_CODEC_PRIVATE);
2248       gst_buffer_unmap (buf, &map);
2249       return TRUE;
2250     }
2251
2252     gst_matroska_mux_free_codec_priv (context);
2253
2254     priv_data = g_malloc0 (map.size);
2255     memcpy (priv_data, map.data, map.size);
2256     context->codec_priv = priv_data;
2257     context->codec_priv_size = map.size;
2258     gst_buffer_unmap (buf, &map);
2259   }
2260
2261   GST_DEBUG_OBJECT (pad, "codec_id %s, codec data size %" G_GSIZE_FORMAT,
2262       GST_STR_NULL (context->codec_id), context->codec_priv_size);
2263
2264 exit:
2265
2266   return ret;
2267 }
2268
2269
2270 /**
2271  * gst_matroska_mux_request_new_pad:
2272  * @element: #GstMatroskaMux.
2273  * @templ: #GstPadTemplate.
2274  * @pad_name: New pad name.
2275  *
2276  * Request pad function for sink templates.
2277  *
2278  * Returns: New #GstPad.
2279  */
2280 static GstPad *
2281 gst_matroska_mux_request_new_pad (GstElement * element,
2282     GstPadTemplate * templ, const gchar * req_name, const GstCaps * caps)
2283 {
2284   GstElementClass *klass = GST_ELEMENT_GET_CLASS (element);
2285   GstMatroskaMux *mux = GST_MATROSKA_MUX (element);
2286   GstMatroskaPad *collect_pad;
2287   GstMatroskamuxPad *newpad;
2288   gchar *name = NULL;
2289   const gchar *pad_name = NULL;
2290   GstMatroskaCapsFunc capsfunc = NULL;
2291   GstMatroskaTrackContext *context = NULL;
2292   gint pad_id;
2293   gboolean locked = TRUE;
2294   const gchar *id = NULL;
2295
2296   if (templ == gst_element_class_get_pad_template (klass, "audio_%u")) {
2297     /* don't mix named and unnamed pads, if the pad already exists we fail when
2298      * trying to add it */
2299     if (req_name != NULL && sscanf (req_name, "audio_%u", &pad_id) == 1) {
2300       pad_name = req_name;
2301     } else {
2302       name = g_strdup_printf ("audio_%u", mux->num_a_streams++);
2303       pad_name = name;
2304     }
2305     capsfunc = GST_DEBUG_FUNCPTR (gst_matroska_mux_audio_pad_setcaps);
2306     context = (GstMatroskaTrackContext *)
2307         g_new0 (GstMatroskaTrackAudioContext, 1);
2308     context->type = GST_MATROSKA_TRACK_TYPE_AUDIO;
2309     context->name = g_strdup ("Audio");
2310   } else if (templ == gst_element_class_get_pad_template (klass, "video_%u")) {
2311     /* don't mix named and unnamed pads, if the pad already exists we fail when
2312      * trying to add it */
2313     if (req_name != NULL && sscanf (req_name, "video_%u", &pad_id) == 1) {
2314       pad_name = req_name;
2315     } else {
2316       name = g_strdup_printf ("video_%u", mux->num_v_streams++);
2317       pad_name = name;
2318     }
2319     capsfunc = GST_DEBUG_FUNCPTR (gst_matroska_mux_video_pad_setcaps);
2320     context = (GstMatroskaTrackContext *)
2321         g_new0 (GstMatroskaTrackVideoContext, 1);
2322     context->type = GST_MATROSKA_TRACK_TYPE_VIDEO;
2323     context->name = g_strdup ("Video");
2324   } else if (templ == gst_element_class_get_pad_template (klass, "subtitle_%u")) {
2325     /* don't mix named and unnamed pads, if the pad already exists we fail when
2326      * trying to add it */
2327     if (req_name != NULL && sscanf (req_name, "subtitle_%u", &pad_id) == 1) {
2328       pad_name = req_name;
2329     } else {
2330       name = g_strdup_printf ("subtitle_%u", mux->num_t_streams++);
2331       pad_name = name;
2332     }
2333     capsfunc = GST_DEBUG_FUNCPTR (gst_matroska_mux_subtitle_pad_setcaps);
2334     context = (GstMatroskaTrackContext *)
2335         g_new0 (GstMatroskaTrackSubtitleContext, 1);
2336     context->type = GST_MATROSKA_TRACK_TYPE_SUBTITLE;
2337     context->name = g_strdup ("Subtitle");
2338     /* setcaps may only provide proper one a lot later */
2339     id = "S_SUB_UNKNOWN";
2340     locked = FALSE;
2341   } else {
2342     GST_WARNING_OBJECT (mux, "This is not our template!");
2343     return NULL;
2344   }
2345
2346   newpad = g_object_new (GST_TYPE_MATROSKAMUX_PAD,
2347       "name", pad_name, "direction", templ->direction, "template", templ, NULL);
2348
2349   gst_matroskamux_pad_init (newpad);
2350   collect_pad = (GstMatroskaPad *)
2351       gst_collect_pads_add_pad (mux->collect, GST_PAD (newpad),
2352       sizeof (GstMatroskamuxPad),
2353       (GstCollectDataDestroyNotify) gst_matroska_pad_free, locked);
2354
2355   collect_pad->mux = mux;
2356   collect_pad->track = context;
2357   gst_matroska_pad_reset (collect_pad, FALSE);
2358   if (id)
2359     gst_matroska_mux_set_codec_id (collect_pad->track, id);
2360   collect_pad->track->dts_only = FALSE;
2361
2362   collect_pad->capsfunc = capsfunc;
2363   gst_pad_set_active (GST_PAD (newpad), TRUE);
2364   if (!gst_element_add_pad (element, GST_PAD (newpad)))
2365     goto pad_add_failed;
2366
2367   g_free (name);
2368
2369   mux->num_streams++;
2370
2371   GST_DEBUG_OBJECT (newpad, "Added new request pad");
2372
2373   return GST_PAD (newpad);
2374
2375   /* ERROR cases */
2376 pad_add_failed:
2377   {
2378     GST_WARNING_OBJECT (mux, "Adding the new pad '%s' failed", pad_name);
2379     g_free (name);
2380     gst_object_unref (newpad);
2381     return NULL;
2382   }
2383 }
2384
2385 /**
2386  * gst_matroska_mux_release_pad:
2387  * @element: #GstMatroskaMux.
2388  * @pad: Pad to release.
2389  *
2390  * Release a previously requested pad.
2391 */
2392 static void
2393 gst_matroska_mux_release_pad (GstElement * element, GstPad * pad)
2394 {
2395   GstMatroskaMux *mux;
2396   GSList *walk;
2397
2398   mux = GST_MATROSKA_MUX (GST_PAD_PARENT (pad));
2399
2400   for (walk = mux->collect->data; walk; walk = g_slist_next (walk)) {
2401     GstCollectData *cdata = (GstCollectData *) walk->data;
2402     GstMatroskaPad *collect_pad = (GstMatroskaPad *) cdata;
2403
2404     if (cdata->pad == pad) {
2405       /*
2406        * observed duration, this will remain GST_CLOCK_TIME_NONE
2407        * only if the pad is resetted 
2408        */
2409       GstClockTime collected_duration = GST_CLOCK_TIME_NONE;
2410
2411       if (GST_CLOCK_TIME_IS_VALID (collect_pad->start_ts) &&
2412           GST_CLOCK_TIME_IS_VALID (collect_pad->end_ts)) {
2413         collected_duration =
2414             GST_CLOCK_DIFF (collect_pad->start_ts, collect_pad->end_ts);
2415       }
2416
2417       if (GST_CLOCK_TIME_IS_VALID (collected_duration)
2418           && mux->duration < collected_duration)
2419         mux->duration = collected_duration;
2420
2421       break;
2422     }
2423   }
2424
2425   gst_collect_pads_remove_pad (mux->collect, pad);
2426   if (gst_element_remove_pad (element, pad))
2427     mux->num_streams--;
2428 }
2429
2430
2431 /**
2432  * gst_matroska_mux_track_header:
2433  * @mux: #GstMatroskaMux
2434  * @context: Tack context.
2435  *
2436  * Write a track header.
2437  */
2438 static void
2439 gst_matroska_mux_track_header (GstMatroskaMux * mux,
2440     GstMatroskaTrackContext * context)
2441 {
2442   GstEbmlWrite *ebml = mux->ebml_write;
2443   guint64 master;
2444
2445   /* TODO: check if everything necessary is written and check default values */
2446
2447   /* track type goes before the type-specific stuff */
2448   gst_ebml_write_uint (ebml, GST_MATROSKA_ID_TRACKNUMBER, context->num);
2449   gst_ebml_write_uint (ebml, GST_MATROSKA_ID_TRACKTYPE, context->type);
2450
2451   gst_ebml_write_uint (ebml, GST_MATROSKA_ID_TRACKUID, context->uid);
2452   if (context->default_duration) {
2453     gst_ebml_write_uint (ebml, GST_MATROSKA_ID_TRACKDEFAULTDURATION,
2454         context->default_duration);
2455   }
2456   if (context->language) {
2457     gst_ebml_write_utf8 (ebml, GST_MATROSKA_ID_TRACKLANGUAGE,
2458         context->language);
2459   }
2460
2461   /* FIXME: until we have a nice way of getting the codecname
2462    * out of the caps, I'm not going to enable this. Too much
2463    * (useless, double, boring) work... */
2464   /* TODO: Use value from tags if any */
2465   /*gst_ebml_write_utf8 (ebml, GST_MATROSKA_ID_CODECNAME,
2466      context->codec_name); */
2467   gst_ebml_write_utf8 (ebml, GST_MATROSKA_ID_TRACKNAME, context->name);
2468
2469   /* type-specific stuff */
2470   switch (context->type) {
2471     case GST_MATROSKA_TRACK_TYPE_VIDEO:{
2472       GstMatroskaTrackVideoContext *videocontext =
2473           (GstMatroskaTrackVideoContext *) context;
2474
2475       master = gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_TRACKVIDEO);
2476       gst_ebml_write_uint (ebml, GST_MATROSKA_ID_VIDEOPIXELWIDTH,
2477           videocontext->pixel_width);
2478       gst_ebml_write_uint (ebml, GST_MATROSKA_ID_VIDEOPIXELHEIGHT,
2479           videocontext->pixel_height);
2480       if (videocontext->display_width && videocontext->display_height) {
2481         gst_ebml_write_uint (ebml, GST_MATROSKA_ID_VIDEODISPLAYWIDTH,
2482             videocontext->display_width);
2483         gst_ebml_write_uint (ebml, GST_MATROSKA_ID_VIDEODISPLAYHEIGHT,
2484             videocontext->display_height);
2485       }
2486       if (context->flags & GST_MATROSKA_VIDEOTRACK_INTERLACED)
2487         gst_ebml_write_uint (ebml, GST_MATROSKA_ID_VIDEOFLAGINTERLACED, 1);
2488       if (videocontext->fourcc) {
2489         guint32 fcc_le = GUINT32_TO_LE (videocontext->fourcc);
2490
2491         gst_ebml_write_binary (ebml, GST_MATROSKA_ID_VIDEOCOLOURSPACE,
2492             (gpointer) & fcc_le, 4);
2493       }
2494       if (videocontext->multiview_mode != GST_VIDEO_MULTIVIEW_MODE_NONE) {
2495         guint64 stereo_mode = 0;
2496
2497         switch (videocontext->multiview_mode) {
2498           case GST_VIDEO_MULTIVIEW_MODE_MONO:
2499             break;
2500           case GST_VIDEO_MULTIVIEW_MODE_SIDE_BY_SIDE:
2501             if (videocontext->multiview_flags &
2502                 GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST)
2503               stereo_mode = GST_MATROSKA_STEREO_MODE_SBS_RL;
2504             else
2505               stereo_mode = GST_MATROSKA_STEREO_MODE_SBS_LR;
2506             break;
2507           case GST_VIDEO_MULTIVIEW_MODE_TOP_BOTTOM:
2508             if (videocontext->multiview_flags &
2509                 GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST)
2510               stereo_mode = GST_MATROSKA_STEREO_MODE_TB_RL;
2511             else
2512               stereo_mode = GST_MATROSKA_STEREO_MODE_TB_LR;
2513             break;
2514           case GST_VIDEO_MULTIVIEW_MODE_CHECKERBOARD:
2515             if (videocontext->multiview_flags &
2516                 GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST)
2517               stereo_mode = GST_MATROSKA_STEREO_MODE_CHECKER_RL;
2518             else
2519               stereo_mode = GST_MATROSKA_STEREO_MODE_CHECKER_LR;
2520             break;
2521           case GST_VIDEO_MULTIVIEW_MODE_FRAME_BY_FRAME:
2522             if (videocontext->multiview_flags &
2523                 GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST)
2524               stereo_mode = GST_MATROSKA_STEREO_MODE_FBF_RL;
2525             else
2526               stereo_mode = GST_MATROSKA_STEREO_MODE_FBF_LR;
2527             /* FIXME: In frame-by-frame mode, left/right frame buffers need to be
2528              * laced within one block. See http://www.matroska.org/technical/specs/index.html#StereoMode */
2529             GST_FIXME_OBJECT (mux,
2530                 "Frame-by-frame stereoscopic mode not fully implemented");
2531             break;
2532           default:
2533             GST_WARNING_OBJECT (mux,
2534                 "Multiview mode %d not supported in Matroska/WebM",
2535                 videocontext->multiview_mode);
2536             break;
2537         }
2538
2539         if (stereo_mode != 0)
2540           gst_ebml_write_uint (ebml, GST_MATROSKA_ID_VIDEOSTEREOMODE,
2541               stereo_mode);
2542       }
2543       gst_ebml_write_master_finish (ebml, master);
2544
2545       break;
2546     }
2547
2548     case GST_MATROSKA_TRACK_TYPE_AUDIO:{
2549       GstMatroskaTrackAudioContext *audiocontext =
2550           (GstMatroskaTrackAudioContext *) context;
2551
2552       master = gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_TRACKAUDIO);
2553       if (audiocontext->samplerate != 8000)
2554         gst_ebml_write_float (ebml, GST_MATROSKA_ID_AUDIOSAMPLINGFREQ,
2555             audiocontext->samplerate);
2556       if (audiocontext->channels != 1)
2557         gst_ebml_write_uint (ebml, GST_MATROSKA_ID_AUDIOCHANNELS,
2558             audiocontext->channels);
2559       if (audiocontext->bitdepth) {
2560         gst_ebml_write_uint (ebml, GST_MATROSKA_ID_AUDIOBITDEPTH,
2561             audiocontext->bitdepth);
2562       }
2563
2564       gst_ebml_write_master_finish (ebml, master);
2565
2566       break;
2567     }
2568
2569     case GST_MATROSKA_TRACK_TYPE_SUBTITLE:{
2570       break;
2571     }
2572     default:
2573       /* doesn't need type-specific data */
2574       break;
2575   }
2576
2577   gst_ebml_write_ascii (ebml, GST_MATROSKA_ID_CODECID, context->codec_id);
2578   if (context->codec_priv)
2579     gst_ebml_write_binary (ebml, GST_MATROSKA_ID_CODECPRIVATE,
2580         context->codec_priv, context->codec_priv_size);
2581
2582   if (context->seek_preroll) {
2583     gst_ebml_write_uint (ebml, GST_MATROSKA_ID_SEEKPREROLL,
2584         context->seek_preroll);
2585   }
2586
2587   if (context->codec_delay) {
2588     gst_ebml_write_uint (ebml, GST_MATROSKA_ID_CODECDELAY,
2589         context->codec_delay);
2590   }
2591 }
2592
2593 #if 0
2594 static void
2595 gst_matroska_mux_write_chapter_title (const gchar * title, GstEbmlWrite * ebml)
2596 {
2597   guint64 title_master;
2598
2599   title_master =
2600       gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_CHAPTERDISPLAY);
2601
2602   gst_ebml_write_utf8 (ebml, GST_MATROSKA_ID_CHAPSTRING, title);
2603   gst_ebml_write_ascii (ebml, GST_MATROSKA_ID_CHAPLANGUAGE,
2604       GST_MATROSKA_MUX_CHAPLANG);
2605
2606   gst_ebml_write_master_finish (ebml, title_master);
2607 }
2608
2609 static void
2610 gst_matroska_mux_write_chapter (GstMatroskaMux * mux, GstTocEntry * edition,
2611     GstTocEntry * entry, GstEbmlWrite * ebml, guint64 * master_chapters,
2612     guint64 * master_edition)
2613 {
2614   guint64 uid, master_chapteratom;
2615   GList *cur;
2616   GstTocEntry *cur_entry;
2617   guint count, i;
2618   gchar *title;
2619   gint64 start, stop;
2620
2621   if (G_UNLIKELY (master_chapters != NULL && *master_chapters == 0))
2622     *master_chapters =
2623         gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_CHAPTERS);
2624
2625   if (G_UNLIKELY (master_edition != NULL && *master_edition == 0)) {
2626     /* create uid for the parent */
2627     uid = gst_matroska_mux_create_uid ();
2628     g_free (edition->uid);
2629     edition->uid = g_strdup_printf ("%" G_GUINT64_FORMAT, uid);
2630
2631     *master_edition =
2632         gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_EDITIONENTRY);
2633
2634     gst_ebml_write_uint (ebml, GST_MATROSKA_ID_EDITIONUID, uid);
2635     gst_ebml_write_uint (ebml, GST_MATROSKA_ID_EDITIONFLAGHIDDEN, 0);
2636     gst_ebml_write_uint (ebml, GST_MATROSKA_ID_EDITIONFLAGDEFAULT, 0);
2637     gst_ebml_write_uint (ebml, GST_MATROSKA_ID_EDITIONFLAGORDERED, 0);
2638   }
2639
2640   uid = gst_matroska_mux_create_uid ();
2641   gst_toc_entry_get_start_stop_times (entry, &start, &stop);
2642
2643   master_chapteratom =
2644       gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_CHAPTERATOM);
2645   g_free (entry->uid);
2646   entry->uid = g_strdup_printf ("%" G_GUINT64_FORMAT, uid);
2647   gst_ebml_write_uint (ebml, GST_MATROSKA_ID_CHAPTERUID, uid);
2648   gst_ebml_write_uint (ebml, GST_MATROSKA_ID_CHAPTERTIMESTART, start);
2649   gst_ebml_write_uint (ebml, GST_MATROSKA_ID_CHAPTERTIMESTOP, stop);
2650   gst_ebml_write_uint (ebml, GST_MATROSKA_ID_CHAPTERFLAGHIDDEN, 0);
2651   gst_ebml_write_uint (ebml, GST_MATROSKA_ID_CHAPTERFLAGENABLED, 1);
2652
2653   cur = entry->subentries;
2654   while (cur != NULL) {
2655     cur_entry = cur->data;
2656     gst_matroska_mux_write_chapter (mux, NULL, cur_entry, ebml, NULL, NULL);
2657
2658     cur = cur->next;
2659   }
2660
2661   if (G_LIKELY (entry->tags != NULL)) {
2662     count = gst_tag_list_get_tag_size (entry->tags, GST_TAG_TITLE);
2663
2664     for (i = 0; i < count; ++i) {
2665       gst_tag_list_get_string_index (entry->tags, GST_TAG_TITLE, i, &title);
2666       gst_matroska_mux_write_chapter_title (title, ebml);
2667       g_free (title);
2668     }
2669
2670     /* remove title tag */
2671     if (G_LIKELY (count > 0))
2672       gst_tag_list_remove_tag (entry->tags, GST_TAG_TITLE);
2673   }
2674
2675   gst_ebml_write_master_finish (ebml, master_chapteratom);
2676 }
2677
2678 static void
2679 gst_matroska_mux_write_chapter_edition (GstMatroskaMux * mux,
2680     GstTocEntry * entry, GstEbmlWrite * ebml, guint64 * master_chapters)
2681 {
2682   guint64 master_edition = 0;
2683   GList *cur;
2684   GstTocEntry *subentry;
2685
2686   cur = gst_toc_entry_get_sub_entries (entry);
2687   while (cur != NULL) {
2688     subentry = cur->data;
2689     gst_matroska_mux_write_chapter (mux, entry, subentry, ebml, master_chapters,
2690         &master_edition);
2691
2692     cur = cur->next;
2693   }
2694
2695   if (G_LIKELY (master_edition != 0))
2696     gst_ebml_write_master_finish (ebml, master_edition);
2697 }
2698 #endif
2699
2700 /**
2701  * gst_matroska_mux_start:
2702  * @mux: #GstMatroskaMux
2703  *
2704  * Start a new matroska file (write headers etc...)
2705  */
2706 static void
2707 gst_matroska_mux_start (GstMatroskaMux * mux)
2708 {
2709   GstEbmlWrite *ebml = mux->ebml_write;
2710   const gchar *doctype;
2711   guint32 seekhead_id[] = { GST_MATROSKA_ID_SEGMENTINFO,
2712     GST_MATROSKA_ID_TRACKS,
2713     GST_MATROSKA_ID_CHAPTERS,
2714     GST_MATROSKA_ID_CUES,
2715     GST_MATROSKA_ID_TAGS,
2716     0
2717   };
2718   const gchar *media_type;
2719   gboolean audio_only;
2720   guint64 master, child;
2721   GSList *collected;
2722   int i;
2723   guint tracknum = 1;
2724   GstClockTime duration = 0;
2725   guint32 segment_uid[4];
2726   GTimeVal time = { 0, 0 };
2727   gchar s_id[32];
2728 #if 0
2729   GstToc *toc;
2730 #endif
2731
2732   /* if not streaming, check if downstream is seekable */
2733   if (!mux->ebml_write->streamable) {
2734     gboolean seekable;
2735     GstQuery *query;
2736
2737     query = gst_query_new_seeking (GST_FORMAT_BYTES);
2738     if (gst_pad_peer_query (mux->srcpad, query)) {
2739       gst_query_parse_seeking (query, NULL, &seekable, NULL, NULL);
2740       GST_INFO_OBJECT (mux, "downstream is %sseekable", seekable ? "" : "not ");
2741     } else {
2742       /* assume seeking is not supported if query not handled downstream */
2743       GST_WARNING_OBJECT (mux, "downstream did not handle seeking query");
2744       seekable = FALSE;
2745     }
2746     if (!seekable) {
2747       mux->ebml_write->streamable = TRUE;
2748       g_object_notify (G_OBJECT (mux), "streamable");
2749       GST_WARNING_OBJECT (mux, "downstream is not seekable, but "
2750           "streamable=false. Will ignore that and create streamable output "
2751           "instead");
2752     }
2753     gst_query_unref (query);
2754   }
2755
2756   /* stream-start (FIXME: create id based on input ids) */
2757   g_snprintf (s_id, sizeof (s_id), "matroskamux-%08x", g_random_int ());
2758   gst_pad_push_event (mux->srcpad, gst_event_new_stream_start (s_id));
2759
2760   /* output caps */
2761   audio_only = mux->num_v_streams == 0 && mux->num_a_streams > 0;
2762   if (mux->is_webm) {
2763     media_type = (audio_only) ? "audio/webm" : "video/webm";
2764   } else {
2765     media_type = (audio_only) ? "audio/x-matroska" : "video/x-matroska";
2766   }
2767   ebml->caps = gst_caps_new_empty_simple (media_type);
2768   gst_pad_set_caps (mux->srcpad, ebml->caps);
2769   /* we start with a EBML header */
2770   doctype = mux->doctype;
2771   GST_INFO_OBJECT (ebml, "DocType: %s, Version: %d",
2772       doctype, mux->doctype_version);
2773   gst_ebml_write_header (ebml, doctype, mux->doctype_version);
2774
2775   /* the rest of the header is cached */
2776   gst_ebml_write_set_cache (ebml, 0x1000);
2777
2778   /* start a segment */
2779   mux->segment_pos =
2780       gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_SEGMENT);
2781   mux->segment_master = ebml->pos;
2782
2783   if (!mux->ebml_write->streamable) {
2784     /* seekhead (table of contents) - we set the positions later */
2785     mux->seekhead_pos = ebml->pos;
2786     master = gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_SEEKHEAD);
2787     for (i = 0; seekhead_id[i] != 0; i++) {
2788       child = gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_SEEKENTRY);
2789       gst_ebml_write_uint (ebml, GST_MATROSKA_ID_SEEKID, seekhead_id[i]);
2790       gst_ebml_write_uint (ebml, GST_MATROSKA_ID_SEEKPOSITION, -1);
2791       gst_ebml_write_master_finish (ebml, child);
2792     }
2793     gst_ebml_write_master_finish (ebml, master);
2794   }
2795
2796   if (mux->ebml_write->streamable) {
2797     const GstTagList *tags;
2798     gboolean has_main_tags;
2799
2800     /* tags */
2801     tags = gst_tag_setter_get_tag_list (GST_TAG_SETTER (mux));
2802     has_main_tags = tags != NULL && !gst_matroska_mux_tag_list_is_empty (tags);
2803
2804     if (has_main_tags || gst_matroska_mux_streams_have_tags (mux)) {
2805       guint64 master_tags, master_tag;
2806
2807       GST_DEBUG_OBJECT (mux, "Writing tags");
2808
2809       mux->tags_pos = ebml->pos;
2810       master_tags = gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_TAGS);
2811       if (has_main_tags) {
2812         master_tag = gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_TAG);
2813         gst_tag_list_foreach (tags, gst_matroska_mux_write_simple_tag, ebml);
2814         gst_ebml_write_master_finish (ebml, master_tag);
2815       }
2816       gst_matroska_mux_write_streams_tags (mux);
2817       gst_ebml_write_master_finish (ebml, master_tags);
2818     }
2819   }
2820
2821   /* segment info */
2822   mux->info_pos = ebml->pos;
2823   master = gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_SEGMENTINFO);
2824
2825   /* WebM does not support SegmentUID field on SegmentInfo */
2826   if (!mux->is_webm) {
2827     for (i = 0; i < 4; i++) {
2828       segment_uid[i] = g_random_int ();
2829     }
2830     gst_ebml_write_binary (ebml, GST_MATROSKA_ID_SEGMENTUID,
2831         (guint8 *) segment_uid, 16);
2832   }
2833
2834   gst_ebml_write_uint (ebml, GST_MATROSKA_ID_TIMECODESCALE, mux->time_scale);
2835   mux->duration_pos = ebml->pos;
2836   /* get duration */
2837   if (!mux->ebml_write->streamable) {
2838     for (collected = mux->collect->data; collected;
2839         collected = g_slist_next (collected)) {
2840       GstMatroskaPad *collect_pad;
2841       GstPad *thepad;
2842       gint64 trackduration;
2843
2844       collect_pad = (GstMatroskaPad *) collected->data;
2845       thepad = collect_pad->collect.pad;
2846
2847       /* Query the total length of the track. */
2848       GST_DEBUG_OBJECT (thepad, "querying peer duration");
2849       if (gst_pad_peer_query_duration (thepad, GST_FORMAT_TIME, &trackduration)) {
2850         GST_DEBUG_OBJECT (thepad, "duration: %" GST_TIME_FORMAT,
2851             GST_TIME_ARGS (trackduration));
2852         if (trackduration != GST_CLOCK_TIME_NONE && trackduration > duration) {
2853           duration = (GstClockTime) trackduration;
2854         }
2855       }
2856     }
2857     gst_ebml_write_float (ebml, GST_MATROSKA_ID_DURATION,
2858         gst_guint64_to_gdouble (duration) /
2859         gst_guint64_to_gdouble (mux->time_scale));
2860   }
2861   gst_ebml_write_utf8 (ebml, GST_MATROSKA_ID_MUXINGAPP,
2862       "GStreamer matroskamux version " PACKAGE_VERSION);
2863   if (mux->writing_app && mux->writing_app[0]) {
2864     gst_ebml_write_utf8 (ebml, GST_MATROSKA_ID_WRITINGAPP, mux->writing_app);
2865   }
2866   g_get_current_time (&time);
2867   gst_ebml_write_date (ebml, GST_MATROSKA_ID_DATEUTC, time.tv_sec);
2868   gst_ebml_write_master_finish (ebml, master);
2869
2870   /* tracks */
2871   mux->tracks_pos = ebml->pos;
2872   master = gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_TRACKS);
2873
2874   for (collected = mux->collect->data; collected;
2875       collected = g_slist_next (collected)) {
2876     GstMatroskaPad *collect_pad;
2877
2878     collect_pad = (GstMatroskaPad *) collected->data;
2879
2880     /* This will cause an error at a later time */
2881     if (collect_pad->track->codec_id == NULL)
2882       continue;
2883
2884     collect_pad->track->num = tracknum++;
2885     child = gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_TRACKENTRY);
2886     gst_matroska_mux_track_header (mux, collect_pad->track);
2887     gst_ebml_write_master_finish (ebml, child);
2888     /* some remaining pad/track setup */
2889     collect_pad->default_duration_scaled =
2890         gst_util_uint64_scale (collect_pad->track->default_duration,
2891         1, mux->time_scale);
2892   }
2893   gst_ebml_write_master_finish (ebml, master);
2894
2895   /* FIXME: Check if we get a TOC that is supported by Matroska
2896    * and clean up the code below */
2897 #if 0
2898   /* chapters */
2899   toc = gst_toc_setter_get_toc (GST_TOC_SETTER (mux));
2900   if (toc != NULL && !mux->ebml_write->streamable) {
2901     guint64 master_chapters = 0;
2902     GstTocEntry *toc_entry;
2903     GList *cur, *to_write = NULL;
2904     gint64 start, stop;
2905
2906     GST_DEBUG ("Writing chapters");
2907
2908     /* check whether we have editions or chapters at the root level */
2909     toc_entry = toc->entries->data;
2910
2911     if (toc_entry->type != GST_TOC_ENTRY_TYPE_EDITION) {
2912       toc_entry = gst_toc_entry_new (GST_TOC_ENTRY_TYPE_EDITION, "");
2913       gst_toc_entry_set_start_stop_times (toc_entry, -1, -1);
2914
2915       /* aggregate all chapters without root edition */
2916       cur = gst_toc_get_entries (toc);
2917       while (cur != NULL) {
2918         toc_entry->subentries =
2919             g_list_prepend (toc_entry->subentries, cur->data);
2920         cur = cur->next;
2921       }
2922
2923       gst_toc_entry_get_start_stop_times (((GstTocEntry *)
2924               toc_entry->subentries->data), &start, NULL);
2925       toc_entry->subentries = g_list_reverse (toc_entry->subentries);
2926       gst_toc_entry_get_start_stop_times (((GstTocEntry *)
2927               toc_entry->subentries->data), NULL, &stop);
2928       gst_toc_entry_set_start_stop_times (toc_entry, start, stop);
2929
2930       to_write = g_list_append (to_write, toc_entry);
2931     } else {
2932       toc_entry = NULL;
2933       to_write = toc->entries;
2934     }
2935
2936     /* finally write chapters */
2937     mux->chapters_pos = ebml->pos;
2938
2939     cur = to_write;
2940     while (cur != NULL) {
2941       gst_matroska_mux_write_chapter_edition (mux, cur->data, ebml,
2942           &master_chapters);
2943       cur = cur->next;
2944     }
2945
2946     /* close master element if any edition was written */
2947     if (G_LIKELY (master_chapters != 0))
2948       gst_ebml_write_master_finish (ebml, master_chapters);
2949
2950     if (toc_entry != NULL) {
2951       g_list_free (toc_entry->subentries);
2952       toc_entry->subentries = NULL;
2953       gst_toc_entry_unref (toc_entry);
2954       g_list_free (to_write);
2955     }
2956   }
2957 #endif
2958
2959   /* lastly, flush the cache */
2960   gst_ebml_write_flush_cache (ebml, FALSE, 0);
2961
2962 #if 0
2963   if (toc != NULL)
2964     gst_toc_unref (toc);
2965 #endif
2966 }
2967
2968 /* TODO: more sensible tag mappings */
2969 static const struct
2970 {
2971   const gchar *matroska_tagname;
2972   const gchar *gstreamer_tagname;
2973 }
2974 gst_matroska_tag_conv[] = {
2975   {
2976   GST_MATROSKA_TAG_ID_TITLE, GST_TAG_TITLE}, {
2977   GST_MATROSKA_TAG_ID_ARTIST, GST_TAG_ARTIST}, {
2978   GST_MATROSKA_TAG_ID_ALBUM, GST_TAG_ALBUM}, {
2979   GST_MATROSKA_TAG_ID_COMMENTS, GST_TAG_COMMENT}, {
2980   GST_MATROSKA_TAG_ID_BITSPS, GST_TAG_BITRATE}, {
2981   GST_MATROSKA_TAG_ID_BPS, GST_TAG_BITRATE}, {
2982   GST_MATROSKA_TAG_ID_ENCODER, GST_TAG_ENCODER}, {
2983   GST_MATROSKA_TAG_ID_DATE, GST_TAG_DATE}, {
2984   GST_MATROSKA_TAG_ID_ISRC, GST_TAG_ISRC}, {
2985   GST_MATROSKA_TAG_ID_COPYRIGHT, GST_TAG_COPYRIGHT}, {
2986   GST_MATROSKA_TAG_ID_BPM, GST_TAG_BEATS_PER_MINUTE}, {
2987   GST_MATROSKA_TAG_ID_TERMS_OF_USE, GST_TAG_LICENSE}, {
2988   GST_MATROSKA_TAG_ID_COMPOSER, GST_TAG_COMPOSER}, {
2989   GST_MATROSKA_TAG_ID_LEAD_PERFORMER, GST_TAG_PERFORMER}, {
2990   GST_MATROSKA_TAG_ID_GENRE, GST_TAG_GENRE}
2991 };
2992
2993 /* Every stagefright implementation on android up to and including 6.0.1 is using
2994  libwebm with bug in matroska parsing, where it will choke on empty tag elements;
2995  so before outputting tags and tag elements we better make sure that there are
2996  actually tags we are going to write */
2997 static gboolean
2998 gst_matroska_mux_tag_list_is_empty (const GstTagList * list)
2999 {
3000   int i;
3001   for (i = 0; i < gst_tag_list_n_tags (list); i++) {
3002     const gchar *tag = gst_tag_list_nth_tag_name (list, i);
3003     int i;
3004     for (i = 0; i < G_N_ELEMENTS (gst_matroska_tag_conv); i++) {
3005       const gchar *tagname_gst = gst_matroska_tag_conv[i].gstreamer_tagname;
3006       if (strcmp (tagname_gst, tag) == 0) {
3007         GValue src = { 0, };
3008         gchar *dest;
3009
3010         if (!gst_tag_list_copy_value (&src, list, tag))
3011           break;
3012         dest = gst_value_serialize (&src);
3013
3014         g_value_unset (&src);
3015         if (dest) {
3016           g_free (dest);
3017           return FALSE;
3018         }
3019       }
3020     }
3021   }
3022   return TRUE;
3023 }
3024
3025 static void
3026 gst_matroska_mux_write_simple_tag (const GstTagList * list, const gchar * tag,
3027     gpointer data)
3028 {
3029   GstEbmlWrite *ebml = (GstEbmlWrite *) data;
3030   guint i;
3031   guint64 simpletag_master;
3032
3033   for (i = 0; i < G_N_ELEMENTS (gst_matroska_tag_conv); i++) {
3034     const gchar *tagname_gst = gst_matroska_tag_conv[i].gstreamer_tagname;
3035     const gchar *tagname_mkv = gst_matroska_tag_conv[i].matroska_tagname;
3036
3037     if (strcmp (tagname_gst, tag) == 0) {
3038       GValue src = { 0, };
3039       gchar *dest;
3040
3041       if (!gst_tag_list_copy_value (&src, list, tag))
3042         break;
3043       if ((dest = gst_value_serialize (&src))) {
3044
3045         simpletag_master = gst_ebml_write_master_start (ebml,
3046             GST_MATROSKA_ID_SIMPLETAG);
3047         gst_ebml_write_ascii (ebml, GST_MATROSKA_ID_TAGNAME, tagname_mkv);
3048         gst_ebml_write_utf8 (ebml, GST_MATROSKA_ID_TAGSTRING, dest);
3049         gst_ebml_write_master_finish (ebml, simpletag_master);
3050         g_free (dest);
3051       } else {
3052         GST_WARNING ("Can't transform tag '%s' to string", tagname_mkv);
3053       }
3054       g_value_unset (&src);
3055       break;
3056     }
3057   }
3058 }
3059
3060 static void
3061 gst_matroska_mux_write_stream_tags (GstMatroskaMux * mux, GstMatroskaPad * mpad)
3062 {
3063   guint64 master_tag, master_targets;
3064   GstEbmlWrite *ebml;
3065
3066   ebml = mux->ebml_write;
3067
3068   if (G_UNLIKELY (mpad->tags == NULL
3069           || gst_matroska_mux_tag_list_is_empty (mpad->tags)))
3070     return;
3071
3072   master_tag = gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_TAG);
3073   master_targets = gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_TARGETS);
3074
3075   gst_ebml_write_uint (ebml, GST_MATROSKA_ID_TARGETTRACKUID, mpad->track->uid);
3076
3077   gst_ebml_write_master_finish (ebml, master_targets);
3078   gst_tag_list_foreach (mpad->tags, gst_matroska_mux_write_simple_tag, ebml);
3079   gst_ebml_write_master_finish (ebml, master_tag);
3080 }
3081
3082 static void
3083 gst_matroska_mux_write_streams_tags (GstMatroskaMux * mux)
3084 {
3085   GSList *walk;
3086
3087   for (walk = mux->collect->data; walk; walk = g_slist_next (walk)) {
3088     GstMatroskaPad *collect_pad;
3089
3090     collect_pad = (GstMatroskaPad *) walk->data;
3091
3092     gst_matroska_mux_write_stream_tags (mux, collect_pad);
3093   }
3094 }
3095
3096 static gboolean
3097 gst_matroska_mux_streams_have_tags (GstMatroskaMux * mux)
3098 {
3099   GSList *walk;
3100
3101   for (walk = mux->collect->data; walk; walk = g_slist_next (walk)) {
3102     GstMatroskaPad *collect_pad;
3103
3104     collect_pad = (GstMatroskaPad *) walk->data;
3105     if (!gst_matroska_mux_tag_list_is_empty (collect_pad->tags))
3106       return TRUE;
3107   }
3108   return FALSE;
3109 }
3110
3111 #if 0
3112 static void
3113 gst_matroska_mux_write_toc_entry_tags (GstMatroskaMux * mux,
3114     const GstTocEntry * entry, guint64 * master_tags)
3115 {
3116   guint64 master_tag, master_targets;
3117   GstEbmlWrite *ebml;
3118   GList *cur;
3119
3120   ebml = mux->ebml_write;
3121
3122   if (G_UNLIKELY (entry->tags != NULL
3123           && !gst_matroska_mux_tag_list_is_empty (entry->tags))) {
3124     if (*master_tags == 0) {
3125       mux->tags_pos = ebml->pos;
3126       *master_tags = gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_TAGS);
3127     }
3128
3129     master_tag = gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_TAG);
3130     master_targets =
3131         gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_TARGETS);
3132
3133     if (entry->type == GST_TOC_ENTRY_TYPE_EDITION)
3134       gst_ebml_write_uint (ebml, GST_MATROSKA_ID_TARGETEDITIONUID,
3135           g_ascii_strtoull (entry->uid, NULL, 10));
3136     else
3137       gst_ebml_write_uint (ebml, GST_MATROSKA_ID_TARGETCHAPTERUID,
3138           g_ascii_strtoull (entry->uid, NULL, 10));
3139
3140     gst_ebml_write_master_finish (ebml, master_targets);
3141     gst_tag_list_foreach (entry->tags, gst_matroska_mux_write_simple_tag, ebml);
3142     gst_ebml_write_master_finish (ebml, master_tag);
3143   }
3144
3145   cur = entry->subentries;
3146   while (cur != NULL) {
3147     gst_matroska_mux_write_toc_entry_tags (mux, cur->data, master_tags);
3148     cur = cur->next;
3149   }
3150 }
3151 #endif
3152
3153 /**
3154  * gst_matroska_mux_finish:
3155  * @mux: #GstMatroskaMux
3156  *
3157  * Finish a new matroska file (write index etc...)
3158  */
3159 static void
3160 gst_matroska_mux_finish (GstMatroskaMux * mux)
3161 {
3162   GstEbmlWrite *ebml = mux->ebml_write;
3163   guint64 pos;
3164   guint64 duration = 0;
3165   GSList *collected;
3166   const GstTagList *tags;
3167   gboolean has_main_tags;
3168
3169   /* finish last cluster */
3170   if (mux->cluster) {
3171     gst_ebml_write_master_finish (ebml, mux->cluster);
3172   }
3173
3174   /* cues */
3175   if (mux->index != NULL) {
3176     guint n;
3177     guint64 master, pointentry_master, trackpos_master;
3178
3179     mux->cues_pos = ebml->pos;
3180     gst_ebml_write_set_cache (ebml, 12 + 41 * mux->num_indexes);
3181     master = gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_CUES);
3182
3183     for (n = 0; n < mux->num_indexes; n++) {
3184       GstMatroskaIndex *idx = &mux->index[n];
3185
3186       pointentry_master = gst_ebml_write_master_start (ebml,
3187           GST_MATROSKA_ID_POINTENTRY);
3188       gst_ebml_write_uint (ebml, GST_MATROSKA_ID_CUETIME,
3189           idx->time / mux->time_scale);
3190       trackpos_master = gst_ebml_write_master_start (ebml,
3191           GST_MATROSKA_ID_CUETRACKPOSITIONS);
3192       gst_ebml_write_uint (ebml, GST_MATROSKA_ID_CUETRACK, idx->track);
3193       gst_ebml_write_uint (ebml, GST_MATROSKA_ID_CUECLUSTERPOSITION,
3194           idx->pos - mux->segment_master);
3195       gst_ebml_write_master_finish (ebml, trackpos_master);
3196       gst_ebml_write_master_finish (ebml, pointentry_master);
3197     }
3198
3199     gst_ebml_write_master_finish (ebml, master);
3200     gst_ebml_write_flush_cache (ebml, FALSE, GST_CLOCK_TIME_NONE);
3201   }
3202
3203   /* tags */
3204   tags = gst_tag_setter_get_tag_list (GST_TAG_SETTER (mux));
3205   has_main_tags = tags != NULL && !gst_matroska_mux_tag_list_is_empty (tags);
3206
3207   if (has_main_tags || gst_matroska_mux_streams_have_tags (mux)
3208       || gst_toc_setter_get_toc (GST_TOC_SETTER (mux)) != NULL) {
3209     guint64 master_tags = 0, master_tag;
3210 #if 0
3211     const GstToc *toc;
3212 #endif
3213
3214     GST_DEBUG_OBJECT (mux, "Writing tags");
3215
3216 #if 0
3217     toc = gst_toc_setter_get_toc (GST_TOC_SETTER (mux));
3218 #endif
3219
3220     if (has_main_tags) {
3221       /* TODO: maybe limit via the TARGETS id by looking at the source pad */
3222       mux->tags_pos = ebml->pos;
3223       master_tags = gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_TAGS);
3224       master_tag = gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_TAG);
3225
3226       if (tags != NULL)
3227         gst_tag_list_foreach (tags, gst_matroska_mux_write_simple_tag, ebml);
3228 #if 0
3229       if (toc != NULL)
3230         gst_tag_list_foreach (toc->tags, gst_matroska_mux_write_simple_tag,
3231             ebml);
3232 #endif
3233
3234       gst_ebml_write_master_finish (ebml, master_tag);
3235     }
3236 #if 0
3237     if (toc != NULL) {
3238       cur = toc->entries;
3239       while (cur != NULL) {
3240         gst_matroska_mux_write_toc_entry_tags (mux, cur->data, &master_tags);
3241         cur = cur->next;
3242       }
3243     }
3244 #endif
3245
3246     if (master_tags == 0 && gst_matroska_mux_streams_have_tags (mux)) {
3247       mux->tags_pos = ebml->pos;
3248       master_tags = gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_TAGS);
3249     }
3250     gst_matroska_mux_write_streams_tags (mux);
3251
3252     if (master_tags != 0)
3253       gst_ebml_write_master_finish (ebml, master_tags);
3254   }
3255
3256   /* update seekhead. We know that:
3257    * - a seekhead contains 5 entries.
3258    * - order of entries is as above.
3259    * - a seekhead has a 4-byte header + 8-byte length
3260    * - each entry is 2-byte master, 2-byte ID pointer,
3261    *     2-byte length pointer, all 8/1-byte length, 4-
3262    *     byte ID and 8-byte length pointer, where the
3263    *     length pointer starts at 20.
3264    * - all entries are local to the segment (so pos - segment_master).
3265    * - so each entry is at 12 + 20 + num * 28. */
3266   gst_ebml_replace_uint (ebml, mux->seekhead_pos + 32,
3267       mux->info_pos - mux->segment_master);
3268   gst_ebml_replace_uint (ebml, mux->seekhead_pos + 60,
3269       mux->tracks_pos - mux->segment_master);
3270   if (gst_toc_setter_get_toc (GST_TOC_SETTER (mux)) != NULL
3271       && mux->chapters_pos > 0) {
3272     gst_ebml_replace_uint (ebml, mux->seekhead_pos + 88,
3273         mux->chapters_pos - mux->segment_master);
3274   } else {
3275     /* void'ify */
3276     guint64 my_pos = ebml->pos;
3277
3278     gst_ebml_write_seek (ebml, mux->seekhead_pos + 68);
3279     gst_ebml_write_buffer_header (ebml, GST_EBML_ID_VOID, 26);
3280     gst_ebml_write_seek (ebml, my_pos);
3281   }
3282   if (mux->index != NULL) {
3283     gst_ebml_replace_uint (ebml, mux->seekhead_pos + 116,
3284         mux->cues_pos - mux->segment_master);
3285   } else {
3286     /* void'ify */
3287     guint64 my_pos = ebml->pos;
3288
3289     gst_ebml_write_seek (ebml, mux->seekhead_pos + 96);
3290     gst_ebml_write_buffer_header (ebml, GST_EBML_ID_VOID, 26);
3291     gst_ebml_write_seek (ebml, my_pos);
3292   }
3293
3294   if (tags != NULL) {
3295     gst_ebml_replace_uint (ebml, mux->seekhead_pos + 144,
3296         mux->tags_pos - mux->segment_master);
3297   } else {
3298     /* void'ify */
3299     guint64 my_pos = ebml->pos;
3300
3301     gst_ebml_write_seek (ebml, mux->seekhead_pos + 124);
3302     gst_ebml_write_buffer_header (ebml, GST_EBML_ID_VOID, 26);
3303     gst_ebml_write_seek (ebml, my_pos);
3304   }
3305
3306   /* loop tracks:
3307    * - first get the overall duration
3308    *   (a released track may have left a duration in here)
3309    * - write some track header data for subtitles
3310    */
3311   duration = mux->duration;
3312   pos = ebml->pos;
3313   for (collected = mux->collect->data; collected;
3314       collected = g_slist_next (collected)) {
3315     GstMatroskaPad *collect_pad;
3316     /*
3317      * observed duration, this will never remain GST_CLOCK_TIME_NONE
3318      * since this means buffer without timestamps that is not possibile
3319      */
3320     GstClockTime collected_duration = GST_CLOCK_TIME_NONE;
3321
3322     collect_pad = (GstMatroskaPad *) collected->data;
3323
3324     GST_DEBUG_OBJECT (mux,
3325         "Pad %" GST_PTR_FORMAT " start ts %" GST_TIME_FORMAT
3326         " end ts %" GST_TIME_FORMAT, collect_pad,
3327         GST_TIME_ARGS (collect_pad->start_ts),
3328         GST_TIME_ARGS (collect_pad->end_ts));
3329
3330     if (GST_CLOCK_TIME_IS_VALID (collect_pad->start_ts) &&
3331         GST_CLOCK_TIME_IS_VALID (collect_pad->end_ts)) {
3332       collected_duration =
3333           GST_CLOCK_DIFF (collect_pad->start_ts, collect_pad->end_ts);
3334       GST_DEBUG_OBJECT (collect_pad,
3335           "final track duration: %" GST_TIME_FORMAT,
3336           GST_TIME_ARGS (collected_duration));
3337     } else {
3338       GST_WARNING_OBJECT (collect_pad, "unable to get final track duration");
3339     }
3340     if (GST_CLOCK_TIME_IS_VALID (collected_duration) &&
3341         duration < collected_duration)
3342       duration = collected_duration;
3343
3344   }
3345
3346   /* seek back (optional, but do anyway) */
3347   gst_ebml_write_seek (ebml, pos);
3348
3349   /* update duration */
3350   if (duration != 0) {
3351     GST_DEBUG_OBJECT (mux, "final total duration: %" GST_TIME_FORMAT,
3352         GST_TIME_ARGS (duration));
3353     pos = mux->ebml_write->pos;
3354     gst_ebml_write_seek (ebml, mux->duration_pos);
3355     gst_ebml_write_float (ebml, GST_MATROSKA_ID_DURATION,
3356         gst_guint64_to_gdouble (duration) /
3357         gst_guint64_to_gdouble (mux->time_scale));
3358     gst_ebml_write_seek (ebml, pos);
3359   } else {
3360     /* void'ify */
3361     guint64 my_pos = ebml->pos;
3362
3363     gst_ebml_write_seek (ebml, mux->duration_pos);
3364     gst_ebml_write_buffer_header (ebml, GST_EBML_ID_VOID, 8);
3365     gst_ebml_write_seek (ebml, my_pos);
3366   }
3367   GST_DEBUG_OBJECT (mux, "finishing segment");
3368   /* finish segment - this also writes element length */
3369   gst_ebml_write_master_finish (ebml, mux->segment_pos);
3370 }
3371
3372 /**
3373  * gst_matroska_mux_buffer_header:
3374  * @track: Track context.
3375  * @relative_timestamp: relative timestamp of the buffer
3376  * @flags: Buffer flags.
3377  *
3378  * Create a buffer containing buffer header.
3379  *
3380  * Returns: New buffer.
3381  */
3382 static GstBuffer *
3383 gst_matroska_mux_create_buffer_header (GstMatroskaTrackContext * track,
3384     gint16 relative_timestamp, int flags)
3385 {
3386   GstBuffer *hdr;
3387   guint8 *data = g_malloc (4);
3388
3389   hdr = gst_buffer_new_wrapped (data, 4);
3390   /* track num - FIXME: what if num >= 0x80 (unlikely)? */
3391   data[0] = track->num | 0x80;
3392   /* time relative to clustertime */
3393   GST_WRITE_UINT16_BE (data + 1, relative_timestamp);
3394
3395   /* flags */
3396   data[3] = flags;
3397
3398   return hdr;
3399 }
3400
3401 #define DIRAC_PARSE_CODE_SEQUENCE_HEADER 0x00
3402 #define DIRAC_PARSE_CODE_END_OF_SEQUENCE 0x10
3403 #define DIRAC_PARSE_CODE_IS_PICTURE(x) ((x & 0x08) != 0)
3404
3405 static GstBuffer *
3406 gst_matroska_mux_handle_dirac_packet (GstMatroskaMux * mux,
3407     GstMatroskaPad * collect_pad, GstBuffer * buf)
3408 {
3409   GstMatroskaTrackVideoContext *ctx =
3410       (GstMatroskaTrackVideoContext *) collect_pad->track;
3411   GstMapInfo map;
3412   guint8 *data;
3413   gsize size;
3414   guint8 parse_code;
3415   guint32 next_parse_offset;
3416   GstBuffer *ret = NULL;
3417   gboolean is_muxing_unit = FALSE;
3418
3419   gst_buffer_map (buf, &map, GST_MAP_READ);
3420   data = map.data;
3421   size = map.size;
3422
3423   if (size < 13) {
3424     gst_buffer_unmap (buf, &map);
3425     gst_buffer_unref (buf);
3426     return ret;
3427   }
3428
3429   /* Check if this buffer contains a picture or end-of-sequence packet */
3430   while (size >= 13) {
3431     if (GST_READ_UINT32_BE (data) != 0x42424344 /* 'BBCD' */ ) {
3432       gst_buffer_unmap (buf, &map);
3433       gst_buffer_unref (buf);
3434       return ret;
3435     }
3436
3437     parse_code = GST_READ_UINT8 (data + 4);
3438     if (parse_code == DIRAC_PARSE_CODE_SEQUENCE_HEADER) {
3439       if (ctx->dirac_unit) {
3440         gst_buffer_unref (ctx->dirac_unit);
3441         ctx->dirac_unit = NULL;
3442       }
3443     } else if (DIRAC_PARSE_CODE_IS_PICTURE (parse_code) ||
3444         parse_code == DIRAC_PARSE_CODE_END_OF_SEQUENCE) {
3445       is_muxing_unit = TRUE;
3446       break;
3447     }
3448
3449     next_parse_offset = GST_READ_UINT32_BE (data + 5);
3450
3451     if (G_UNLIKELY (next_parse_offset == 0 || next_parse_offset > size))
3452       break;
3453
3454     data += next_parse_offset;
3455     size -= next_parse_offset;
3456   }
3457
3458   if (ctx->dirac_unit)
3459     ctx->dirac_unit = gst_buffer_append (ctx->dirac_unit, gst_buffer_ref (buf));
3460   else
3461     ctx->dirac_unit = gst_buffer_ref (buf);
3462
3463   gst_buffer_unmap (buf, &map);
3464
3465   if (is_muxing_unit) {
3466     ret = gst_buffer_make_writable (ctx->dirac_unit);
3467     ctx->dirac_unit = NULL;
3468     gst_buffer_copy_into (ret, buf,
3469         GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS, 0, -1);
3470     gst_buffer_unref (buf);
3471   } else {
3472     gst_buffer_unref (buf);
3473     ret = NULL;
3474   }
3475
3476   return ret;
3477 }
3478
3479 static void
3480 gst_matroska_mux_stop_streamheader (GstMatroskaMux * mux)
3481 {
3482   GstCaps *caps;
3483   GstStructure *s;
3484   GValue streamheader = { 0 };
3485   GValue bufval = { 0 };
3486   GstBuffer *streamheader_buffer;
3487   GstEbmlWrite *ebml = mux->ebml_write;
3488
3489   streamheader_buffer = gst_ebml_stop_streamheader (ebml);
3490   caps = gst_caps_copy (mux->ebml_write->caps);
3491   s = gst_caps_get_structure (caps, 0);
3492   g_value_init (&streamheader, GST_TYPE_ARRAY);
3493   g_value_init (&bufval, GST_TYPE_BUFFER);
3494   GST_BUFFER_FLAG_SET (streamheader_buffer, GST_BUFFER_FLAG_HEADER);
3495   gst_value_set_buffer (&bufval, streamheader_buffer);
3496   gst_value_array_append_value (&streamheader, &bufval);
3497   g_value_unset (&bufval);
3498   gst_structure_set_value (s, "streamheader", &streamheader);
3499   g_value_unset (&streamheader);
3500   gst_caps_replace (&ebml->caps, caps);
3501   gst_buffer_unref (streamheader_buffer);
3502   gst_pad_set_caps (mux->srcpad, caps);
3503   gst_caps_unref (caps);
3504 }
3505
3506 /**
3507  * gst_matroska_mux_write_data:
3508  * @mux: #GstMatroskaMux
3509  * @collect_pad: #GstMatroskaPad with the data
3510  *
3511  * Write collected data (called from gst_matroska_mux_collected).
3512  *
3513  * Returns: Result of the gst_pad_push issued to write the data.
3514  */
3515 static GstFlowReturn
3516 gst_matroska_mux_write_data (GstMatroskaMux * mux, GstMatroskaPad * collect_pad,
3517     GstBuffer * buf)
3518 {
3519   GstEbmlWrite *ebml = mux->ebml_write;
3520   GstBuffer *hdr;
3521   guint64 blockgroup;
3522   gboolean write_duration;
3523   gint16 relative_timestamp;
3524   gint64 relative_timestamp64;
3525   guint64 block_duration, duration_diff = 0;
3526   gboolean is_video_keyframe = FALSE;
3527   gboolean is_video_invisible = FALSE;
3528   GstMatroskamuxPad *pad;
3529   gint flags = 0;
3530   GstClockTime buffer_timestamp;
3531   GstAudioClippingMeta *cmeta = NULL;
3532
3533   /* write data */
3534   pad = GST_MATROSKAMUX_PAD_CAST (collect_pad->collect.pad);
3535
3536   /* vorbis/theora headers are retrieved from caps and put in CodecPrivate */
3537   if (collect_pad->track->xiph_headers_to_skip > 0) {
3538     GST_LOG_OBJECT (collect_pad->collect.pad, "dropping streamheader buffer");
3539     gst_buffer_unref (buf);
3540     --collect_pad->track->xiph_headers_to_skip;
3541     return GST_FLOW_OK;
3542   }
3543
3544   /* for dirac we have to queue up everything up to a picture unit */
3545   if (!strcmp (collect_pad->track->codec_id, GST_MATROSKA_CODEC_ID_VIDEO_DIRAC)) {
3546     buf = gst_matroska_mux_handle_dirac_packet (mux, collect_pad, buf);
3547     if (!buf)
3548       return GST_FLOW_OK;
3549   } else if (!strcmp (collect_pad->track->codec_id,
3550           GST_MATROSKA_CODEC_ID_VIDEO_PRORES)) {
3551     /* Remove the 'Frame container atom' header' */
3552     buf = gst_buffer_make_writable (buf);
3553     gst_buffer_resize (buf, 8, gst_buffer_get_size (buf) - 8);
3554   }
3555
3556   buffer_timestamp =
3557       gst_matroska_track_get_buffer_timestamp (collect_pad->track, buf);
3558
3559   /* hm, invalid timestamp (due to --to be fixed--- element upstream);
3560    * this would wreak havoc with time stored in matroska file */
3561   /* TODO: maybe calculate a timestamp by using the previous timestamp
3562    * and default duration */
3563   if (!GST_CLOCK_TIME_IS_VALID (buffer_timestamp)) {
3564     GST_WARNING_OBJECT (collect_pad->collect.pad,
3565         "Invalid buffer timestamp; dropping buffer");
3566     gst_buffer_unref (buf);
3567     return GST_FLOW_OK;
3568   }
3569
3570   if (!strcmp (collect_pad->track->codec_id, GST_MATROSKA_CODEC_ID_AUDIO_OPUS)
3571       && collect_pad->track->codec_delay) {
3572     /* All timestamps should include the codec delay */
3573     if (buffer_timestamp > collect_pad->track->codec_delay) {
3574       buffer_timestamp += collect_pad->track->codec_delay;
3575     } else {
3576       buffer_timestamp = 0;
3577       duration_diff = collect_pad->track->codec_delay - buffer_timestamp;
3578     }
3579   }
3580
3581   /* set the timestamp for outgoing buffers */
3582   ebml->timestamp = buffer_timestamp;
3583
3584   if (collect_pad->track->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
3585     if (!GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT)) {
3586       GST_LOG_OBJECT (mux, "have video keyframe, ts=%" GST_TIME_FORMAT,
3587           GST_TIME_ARGS (buffer_timestamp));
3588       is_video_keyframe = TRUE;
3589     } else if (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DECODE_ONLY) &&
3590         (!strcmp (collect_pad->track->codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8)
3591             || !strcmp (collect_pad->track->codec_id,
3592                 GST_MATROSKA_CODEC_ID_VIDEO_VP9))) {
3593       GST_LOG_OBJECT (mux,
3594           "have VP8 video invisible frame, " "ts=%" GST_TIME_FORMAT,
3595           GST_TIME_ARGS (buffer_timestamp));
3596       is_video_invisible = TRUE;
3597     }
3598   }
3599
3600   if (mux->cluster) {
3601     /* start a new cluster at every keyframe, at every GstForceKeyUnit event,
3602      * or when we may be reaching the limit of the relative timestamp */
3603     if (mux->cluster_time +
3604         mux->max_cluster_duration < buffer_timestamp
3605         || is_video_keyframe || mux->force_key_unit_event) {
3606       if (!mux->ebml_write->streamable)
3607         gst_ebml_write_master_finish (ebml, mux->cluster);
3608
3609       /* Forward the GstForceKeyUnit event after finishing the cluster */
3610       if (mux->force_key_unit_event) {
3611         gst_pad_push_event (mux->srcpad, mux->force_key_unit_event);
3612         mux->force_key_unit_event = NULL;
3613       }
3614
3615       mux->prev_cluster_size = ebml->pos - mux->cluster_pos;
3616       mux->cluster_pos = ebml->pos;
3617       gst_ebml_write_set_cache (ebml, 0x20);
3618       mux->cluster =
3619           gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_CLUSTER);
3620       gst_ebml_write_uint (ebml, GST_MATROSKA_ID_CLUSTERTIMECODE,
3621           gst_util_uint64_scale (buffer_timestamp, 1, mux->time_scale));
3622       GST_LOG_OBJECT (mux, "cluster timestamp %" G_GUINT64_FORMAT,
3623           gst_util_uint64_scale (buffer_timestamp, 1, mux->time_scale));
3624       gst_ebml_write_flush_cache (ebml, TRUE, buffer_timestamp);
3625       mux->cluster_time = buffer_timestamp;
3626       gst_ebml_write_uint (ebml, GST_MATROSKA_ID_PREVSIZE,
3627           mux->prev_cluster_size);
3628     }
3629   } else {
3630     /* first cluster */
3631
3632     mux->cluster_pos = ebml->pos;
3633     gst_ebml_write_set_cache (ebml, 0x20);
3634     mux->cluster = gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_CLUSTER);
3635     gst_ebml_write_uint (ebml, GST_MATROSKA_ID_CLUSTERTIMECODE,
3636         gst_util_uint64_scale (buffer_timestamp, 1, mux->time_scale));
3637     gst_ebml_write_flush_cache (ebml, TRUE, buffer_timestamp);
3638     mux->cluster_time = buffer_timestamp;
3639   }
3640
3641   /* We currently write index entries for all video tracks or for the audio
3642    * track in a single-track audio file.  This could be improved by keeping the
3643    * index only for the *first* video track. */
3644
3645   /* TODO: index is useful for every track, should contain the number of
3646    * the block in the cluster which contains the timestamp, should also work
3647    * for files with multiple audio tracks.
3648    */
3649   if (!mux->ebml_write->streamable &&
3650       (is_video_keyframe ||
3651           ((collect_pad->track->type == GST_MATROSKA_TRACK_TYPE_AUDIO) &&
3652               (mux->num_streams == 1)))) {
3653     gint last_idx = -1;
3654
3655     if (mux->min_index_interval != 0) {
3656       for (last_idx = mux->num_indexes - 1; last_idx >= 0; last_idx--) {
3657         if (mux->index[last_idx].track == collect_pad->track->num)
3658           break;
3659       }
3660     }
3661
3662     if (last_idx < 0 || mux->min_index_interval == 0 ||
3663         (GST_CLOCK_DIFF (mux->index[last_idx].time, buffer_timestamp)
3664             >= mux->min_index_interval)) {
3665       GstMatroskaIndex *idx;
3666
3667       if (mux->num_indexes % 32 == 0) {
3668         mux->index = g_renew (GstMatroskaIndex, mux->index,
3669             mux->num_indexes + 32);
3670       }
3671       idx = &mux->index[mux->num_indexes++];
3672
3673       idx->pos = mux->cluster_pos;
3674       idx->time = buffer_timestamp;
3675       idx->track = collect_pad->track->num;
3676     }
3677   }
3678
3679   /* Check if the duration differs from the default duration. */
3680   write_duration = FALSE;
3681   block_duration = 0;
3682   if (pad->frame_duration && GST_BUFFER_DURATION_IS_VALID (buf)) {
3683     block_duration = GST_BUFFER_DURATION (buf) + duration_diff;
3684     block_duration = gst_util_uint64_scale (block_duration, 1, mux->time_scale);
3685
3686     /* small difference should be ok. */
3687     if (block_duration > collect_pad->default_duration_scaled + 1 ||
3688         block_duration < collect_pad->default_duration_scaled - 1) {
3689       write_duration = TRUE;
3690     }
3691   }
3692
3693   /* write the block, for doctype v2 use SimpleBlock if possible
3694    * one slice (*breath*).
3695    * FIXME: Need to do correct lacing! */
3696   relative_timestamp64 = buffer_timestamp - mux->cluster_time;
3697   if (relative_timestamp64 >= 0) {
3698     /* round the timestamp */
3699     relative_timestamp64 += gst_util_uint64_scale (mux->time_scale, 1, 2);
3700     relative_timestamp = gst_util_uint64_scale (relative_timestamp64, 1,
3701         mux->time_scale);
3702   } else {
3703     /* round the timestamp */
3704     relative_timestamp64 -= gst_util_uint64_scale (mux->time_scale, 1, 2);
3705     relative_timestamp =
3706         -((gint16) gst_util_uint64_scale (-relative_timestamp64, 1,
3707             mux->time_scale));
3708   }
3709
3710   if (is_video_invisible)
3711     flags |= 0x08;
3712
3713   if (!strcmp (collect_pad->track->codec_id, GST_MATROSKA_CODEC_ID_AUDIO_OPUS)) {
3714     cmeta = gst_buffer_get_audio_clipping_meta (buf);
3715     g_assert (!cmeta || cmeta->format == GST_FORMAT_DEFAULT);
3716
3717     /* Start clipping is done via header and CodecDelay */
3718     if (cmeta && !cmeta->end)
3719       cmeta = NULL;
3720   }
3721
3722   if (mux->doctype_version > 1 && !write_duration && !cmeta) {
3723     if (is_video_keyframe)
3724       flags |= 0x80;
3725
3726     hdr =
3727         gst_matroska_mux_create_buffer_header (collect_pad->track,
3728         relative_timestamp, flags);
3729     gst_ebml_write_set_cache (ebml, 0x40);
3730     gst_ebml_write_buffer_header (ebml, GST_MATROSKA_ID_SIMPLEBLOCK,
3731         gst_buffer_get_size (buf) + gst_buffer_get_size (hdr));
3732     gst_ebml_write_buffer (ebml, hdr);
3733     gst_ebml_write_flush_cache (ebml, FALSE, buffer_timestamp);
3734     gst_ebml_write_buffer (ebml, buf);
3735
3736     return gst_ebml_last_write_result (ebml);
3737   } else {
3738     gst_ebml_write_set_cache (ebml, gst_buffer_get_size (buf) * 2);
3739     /* write and call order slightly unnatural,
3740      * but avoids seek and minizes pushing */
3741     blockgroup = gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_BLOCKGROUP);
3742     hdr =
3743         gst_matroska_mux_create_buffer_header (collect_pad->track,
3744         relative_timestamp, flags);
3745     if (write_duration)
3746       gst_ebml_write_uint (ebml, GST_MATROSKA_ID_BLOCKDURATION, block_duration);
3747
3748     if (!strcmp (collect_pad->track->codec_id, GST_MATROSKA_CODEC_ID_AUDIO_OPUS)
3749         && cmeta) {
3750       /* Start clipping is done via header and CodecDelay */
3751       if (cmeta->end) {
3752         guint64 end =
3753             gst_util_uint64_scale_round (cmeta->end, GST_SECOND, 48000);
3754         gst_ebml_write_sint (ebml, GST_MATROSKA_ID_DISCARDPADDING, end);
3755       }
3756     }
3757
3758     gst_ebml_write_buffer_header (ebml, GST_MATROSKA_ID_BLOCK,
3759         gst_buffer_get_size (buf) + gst_buffer_get_size (hdr));
3760     gst_ebml_write_buffer (ebml, hdr);
3761     gst_ebml_write_master_finish_full (ebml, blockgroup,
3762         gst_buffer_get_size (buf));
3763     gst_ebml_write_flush_cache (ebml, FALSE, buffer_timestamp);
3764     gst_ebml_write_buffer (ebml, buf);
3765
3766     return gst_ebml_last_write_result (ebml);
3767   }
3768 }
3769
3770 /**
3771  * gst_matroska_mux_handle_buffer:
3772  * @pads: #GstCollectPads
3773  * @uuser_data: #GstMatroskaMux
3774  *
3775  * Collectpads callback.
3776  *
3777  * Returns: #GstFlowReturn
3778  */
3779 static GstFlowReturn
3780 gst_matroska_mux_handle_buffer (GstCollectPads * pads, GstCollectData * data,
3781     GstBuffer * buf, gpointer user_data)
3782 {
3783   GstClockTime buffer_timestamp;
3784   GstMatroskaMux *mux = GST_MATROSKA_MUX (user_data);
3785   GstEbmlWrite *ebml = mux->ebml_write;
3786   GstMatroskaPad *best;
3787   GstFlowReturn ret = GST_FLOW_OK;
3788   GST_DEBUG_OBJECT (mux, "Collected pads");
3789
3790   /* start with a header */
3791   if (mux->state == GST_MATROSKA_MUX_STATE_START) {
3792     if (mux->collect->data == NULL) {
3793       GST_ELEMENT_ERROR (mux, STREAM, MUX, (NULL),
3794           ("No input streams configured"));
3795       return GST_FLOW_ERROR;
3796     }
3797     mux->state = GST_MATROSKA_MUX_STATE_HEADER;
3798     gst_ebml_start_streamheader (ebml);
3799     gst_matroska_mux_start (mux);
3800     gst_matroska_mux_stop_streamheader (mux);
3801     mux->state = GST_MATROSKA_MUX_STATE_DATA;
3802   }
3803
3804   /* provided with stream to write from */
3805   best = (GstMatroskaPad *) data;
3806
3807   /* if there is no best pad, we have reached EOS */
3808   if (best == NULL) {
3809     GST_DEBUG_OBJECT (mux, "No best pad. Finishing...");
3810     if (!mux->ebml_write->streamable) {
3811       gst_matroska_mux_finish (mux);
3812     } else {
3813       GST_DEBUG_OBJECT (mux, "... but streamable, nothing to finish");
3814     }
3815     gst_pad_push_event (mux->srcpad, gst_event_new_eos ());
3816     ret = GST_FLOW_EOS;
3817     goto exit;
3818   }
3819
3820   if (best->track->codec_id == NULL) {
3821     GST_ERROR_OBJECT (best->collect.pad, "No codec-id for pad");
3822     ret = GST_FLOW_NOT_NEGOTIATED;
3823     goto exit;
3824   }
3825
3826   /* if we have a best stream, should also have a buffer */
3827   g_assert (buf);
3828
3829   buffer_timestamp = gst_matroska_track_get_buffer_timestamp (best->track, buf);
3830
3831   GST_DEBUG_OBJECT (best->collect.pad, "best pad - buffer ts %"
3832       GST_TIME_FORMAT " dur %" GST_TIME_FORMAT,
3833       GST_TIME_ARGS (buffer_timestamp),
3834       GST_TIME_ARGS (GST_BUFFER_DURATION (buf)));
3835
3836   /* make note of first and last encountered timestamps, so we can calculate
3837    * the actual duration later when we send an updated header on eos */
3838   if (GST_CLOCK_TIME_IS_VALID (buffer_timestamp)) {
3839     GstClockTime start_ts = buffer_timestamp;
3840     GstClockTime end_ts = start_ts;
3841
3842     if (GST_BUFFER_DURATION_IS_VALID (buf))
3843       end_ts += GST_BUFFER_DURATION (buf);
3844     else if (best->track->default_duration)
3845       end_ts += best->track->default_duration;
3846
3847     if (!GST_CLOCK_TIME_IS_VALID (best->end_ts) || end_ts > best->end_ts)
3848       best->end_ts = end_ts;
3849
3850     if (G_UNLIKELY (best->start_ts == GST_CLOCK_TIME_NONE ||
3851             start_ts < best->start_ts))
3852       best->start_ts = start_ts;
3853   }
3854
3855   /* write one buffer */
3856   ret = gst_matroska_mux_write_data (mux, best, buf);
3857
3858 exit:
3859   return ret;
3860 }
3861
3862
3863 /**
3864  * gst_matroska_mux_change_state:
3865  * @element: #GstMatroskaMux
3866  * @transition: State change transition.
3867  *
3868  * Change the muxer state.
3869  *
3870  * Returns: #GstStateChangeReturn
3871  */
3872 static GstStateChangeReturn
3873 gst_matroska_mux_change_state (GstElement * element, GstStateChange transition)
3874 {
3875   GstStateChangeReturn ret;
3876   GstMatroskaMux *mux = GST_MATROSKA_MUX (element);
3877
3878   switch (transition) {
3879     case GST_STATE_CHANGE_NULL_TO_READY:
3880       break;
3881     case GST_STATE_CHANGE_READY_TO_PAUSED:
3882       gst_collect_pads_start (mux->collect);
3883       break;
3884     case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
3885       break;
3886     case GST_STATE_CHANGE_PAUSED_TO_READY:
3887       gst_collect_pads_stop (mux->collect);
3888       break;
3889     default:
3890       break;
3891   }
3892
3893   ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
3894
3895   switch (transition) {
3896     case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
3897       break;
3898     case GST_STATE_CHANGE_PAUSED_TO_READY:
3899       gst_matroska_mux_reset (GST_ELEMENT (mux));
3900       break;
3901     case GST_STATE_CHANGE_READY_TO_NULL:
3902       break;
3903     default:
3904       break;
3905   }
3906
3907   return ret;
3908 }
3909
3910 static void
3911 gst_matroska_mux_set_property (GObject * object,
3912     guint prop_id, const GValue * value, GParamSpec * pspec)
3913 {
3914   GstMatroskaMux *mux;
3915
3916   g_return_if_fail (GST_IS_MATROSKA_MUX (object));
3917   mux = GST_MATROSKA_MUX (object);
3918
3919   switch (prop_id) {
3920     case PROP_WRITING_APP:
3921       if (!g_value_get_string (value)) {
3922         GST_WARNING_OBJECT (mux, "writing-app property can not be NULL");
3923         break;
3924       }
3925       g_free (mux->writing_app);
3926       mux->writing_app = g_value_dup_string (value);
3927       break;
3928     case PROP_DOCTYPE_VERSION:
3929       mux->doctype_version = g_value_get_int (value);
3930       break;
3931     case PROP_MIN_INDEX_INTERVAL:
3932       mux->min_index_interval = g_value_get_int64 (value);
3933       break;
3934     case PROP_STREAMABLE:
3935       mux->ebml_write->streamable = g_value_get_boolean (value);
3936       break;
3937     case PROP_TIMECODESCALE:
3938       mux->time_scale = g_value_get_int64 (value);
3939       break;
3940     default:
3941       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
3942       break;
3943   }
3944 }
3945
3946 static void
3947 gst_matroska_mux_get_property (GObject * object,
3948     guint prop_id, GValue * value, GParamSpec * pspec)
3949 {
3950   GstMatroskaMux *mux;
3951
3952   g_return_if_fail (GST_IS_MATROSKA_MUX (object));
3953   mux = GST_MATROSKA_MUX (object);
3954
3955   switch (prop_id) {
3956     case PROP_WRITING_APP:
3957       g_value_set_string (value, mux->writing_app);
3958       break;
3959     case PROP_DOCTYPE_VERSION:
3960       g_value_set_int (value, mux->doctype_version);
3961       break;
3962     case PROP_MIN_INDEX_INTERVAL:
3963       g_value_set_int64 (value, mux->min_index_interval);
3964       break;
3965     case PROP_STREAMABLE:
3966       g_value_set_boolean (value, mux->ebml_write->streamable);
3967       break;
3968     case PROP_TIMECODESCALE:
3969       g_value_set_int64 (value, mux->time_scale);
3970       break;
3971     default:
3972       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
3973       break;
3974   }
3975 }