mpegtsmux: Deterministically set the PCR stream to the first stream of the program
[platform/upstream/gstreamer.git] / gst / mpegtsmux / mpegtsmux.c
1 /* 
2  * Copyright 2006, 2007, 2008, 2009, 2010 Fluendo S.A. 
3  *  Authors: Jan Schmidt <jan@fluendo.com>
4  *           Kapil Agrawal <kapil@fluendo.com>
5  *           Julien Moutte <julien@fluendo.com>
6  *
7  * Copyright (C) 2011 Jan Schmidt <thaytan@noraisin.net>
8  *
9  * This library is licensed under 4 different licenses and you
10  * can choose to use it under the terms of any one of them. The
11  * four licenses are the MPL 1.1, the LGPL, the GPL and the MIT
12  * license.
13  *
14  * MPL:
15  * 
16  * The contents of this file are subject to the Mozilla Public License
17  * Version 1.1 (the "License"); you may not use this file except in
18  * compliance with the License. You may obtain a copy of the License at
19  * http://www.mozilla.org/MPL/.
20  *
21  * Software distributed under the License is distributed on an "AS IS"
22  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
23  * License for the specific language governing rights and limitations
24  * under the License.
25  *
26  * LGPL:
27  *
28  * This library is free software; you can redistribute it and/or
29  * modify it under the terms of the GNU Library General Public
30  * License as published by the Free Software Foundation; either
31  * version 2 of the License, or (at your option) any later version.
32  *
33  * This library is distributed in the hope that it will be useful,
34  * but WITHOUT ANY WARRANTY; without even the implied warranty of
35  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
36  * Library General Public License for more details.
37  *
38  * You should have received a copy of the GNU Library General Public
39  * License along with this library; if not, write to the
40  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
41  * Boston, MA 02110-1301, USA.
42  *
43  * GPL:
44  *
45  * This program is free software; you can redistribute it and/or modify
46  * it under the terms of the GNU General Public License as published by
47  * the Free Software Foundation; either version 2 of the License, or
48  * (at your option) any later version.
49  *
50  * This program is distributed in the hope that it will be useful,
51  * but WITHOUT ANY WARRANTY; without even the implied warranty of
52  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
53  * GNU General Public License for more details.
54  *
55  * You should have received a copy of the GNU General Public License
56  * along with this program; if not, write to the Free Software
57  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
58  *
59  * MIT:
60  *
61  * Unless otherwise indicated, Source Code is licensed under MIT license.
62  * See further explanation attached in License Statement (distributed in the file
63  * LICENSE).
64  * 
65  * Permission is hereby granted, free of charge, to any person obtaining a copy of
66  * this software and associated documentation files (the "Software"), to deal in
67  * the Software without restriction, including without limitation the rights to
68  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
69  * of the Software, and to permit persons to whom the Software is furnished to do
70  * so, subject to the following conditions:
71  * 
72  * The above copyright notice and this permission notice shall be included in all
73  * copies or substantial portions of the Software.
74  * 
75  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
76  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
77  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
78  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
79  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
80  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
81  * SOFTWARE.
82  *
83  */
84
85 #ifdef HAVE_CONFIG_H
86 #include "config.h"
87 #endif
88 #include <stdio.h>
89 #include <string.h>
90
91 #include <gst/tag/tag.h>
92 #include <gst/video/video.h>
93 #include <gst/mpegts/mpegts.h>
94 #include <gst/pbutils/pbutils.h>
95
96 #include "mpegtsmux.h"
97
98 #include "mpegtsmux_aac.h"
99 #include "mpegtsmux_ttxt.h"
100 #include "mpegtsmux_opus.h"
101 #include "mpegtsmux_jpeg2000.h"
102 #include <gst/videoparsers/gstjpeg2000parse.h>
103 #include <gst/video/video-color.h>
104
105 GST_DEBUG_CATEGORY (mpegtsmux_debug);
106 #define GST_CAT_DEFAULT mpegtsmux_debug
107
108 #define COLLECT_DATA_PAD(collect_data) (((GstCollectData *)(collect_data))->pad)
109
110 enum
111 {
112   PROP_0,
113   PROP_PROG_MAP,
114   PROP_M2TS_MODE,
115   PROP_PAT_INTERVAL,
116   PROP_PMT_INTERVAL,
117   PROP_ALIGNMENT,
118   PROP_SI_INTERVAL
119 };
120
121 #define MPEGTSMUX_DEFAULT_ALIGNMENT    -1
122 #define MPEGTSMUX_DEFAULT_M2TS         FALSE
123
124 static GstStaticPadTemplate mpegtsmux_sink_factory =
125     GST_STATIC_PAD_TEMPLATE ("sink_%d",
126     GST_PAD_SINK,
127     GST_PAD_REQUEST,
128     GST_STATIC_CAPS ("video/mpeg, "
129         "parsed = (boolean) TRUE, "
130         "mpegversion = (int) { 1, 2, 4 }, "
131         "systemstream = (boolean) false; "
132         "video/x-dirac;"
133         "image/x-jpc;"
134         "video/x-h264,stream-format=(string)byte-stream,"
135         "alignment=(string){au, nal}; "
136         "video/x-h265,stream-format=(string)byte-stream,"
137         "alignment=(string){au, nal}; "
138         "audio/mpeg, "
139         "parsed = (boolean) TRUE, "
140         "mpegversion = (int) { 1, 2 };"
141         "audio/mpeg, "
142         "framed = (boolean) TRUE, "
143         "mpegversion = (int) 4, stream-format = (string) adts;"
144         "audio/mpeg, "
145         "mpegversion = (int) 4, stream-format = (string) raw;"
146         "audio/x-lpcm, "
147         "width = (int) { 16, 20, 24 }, "
148         "rate = (int) { 48000, 96000 }, "
149         "channels = (int) [ 1, 8 ], "
150         "dynamic_range = (int) [ 0, 255 ], "
151         "emphasis = (boolean) { FALSE, TRUE }, "
152         "mute = (boolean) { FALSE, TRUE }; "
153         "audio/x-ac3, framed = (boolean) TRUE;"
154         "audio/x-dts, framed = (boolean) TRUE;"
155         "audio/x-opus, "
156         "channels = (int) [1, 8], "
157         "channel-mapping-family = (int) {0, 1};"
158         "subpicture/x-dvb; application/x-teletext; meta/x-klv, parsed=true;"
159         "image/x-jpc, profile = (int)[0, 49151];"));
160
161 static GstStaticPadTemplate mpegtsmux_src_factory =
162 GST_STATIC_PAD_TEMPLATE ("src",
163     GST_PAD_SRC,
164     GST_PAD_ALWAYS,
165     GST_STATIC_CAPS ("video/mpegts, "
166         "systemstream = (boolean) true, " "packetsize = (int) { 188, 192} ")
167     );
168
169 static void gst_mpegtsmux_set_property (GObject * object, guint prop_id,
170     const GValue * value, GParamSpec * pspec);
171 static void gst_mpegtsmux_get_property (GObject * object, guint prop_id,
172     GValue * value, GParamSpec * pspec);
173
174 static void mpegtsmux_reset (MpegTsMux * mux, gboolean alloc);
175 static void mpegtsmux_dispose (GObject * object);
176 static void alloc_packet_cb (GstBuffer ** _buf, void *user_data);
177 static gboolean new_packet_cb (GstBuffer * buf, void *user_data,
178     gint64 new_pcr);
179 static void release_buffer_cb (guint8 * data, void *user_data);
180 static GstFlowReturn mpegtsmux_collect_packet (MpegTsMux * mux,
181     GstBuffer * buf);
182 static GstFlowReturn mpegtsmux_push_packets (MpegTsMux * mux, gboolean force);
183 static gboolean new_packet_m2ts (MpegTsMux * mux, GstBuffer * buf,
184     gint64 new_pcr);
185
186 static void mpegtsmux_prepare_srcpad (MpegTsMux * mux);
187 GstFlowReturn mpegtsmux_clip_inc_running_time (GstCollectPads * pads,
188     GstCollectData * cdata, GstBuffer * buf, GstBuffer ** outbuf,
189     gpointer user_data);
190 static GstFlowReturn mpegtsmux_collected_buffer (GstCollectPads * pads,
191     GstCollectData * data, GstBuffer * buf, MpegTsMux * mux);
192
193 static gboolean mpegtsmux_sink_event (GstCollectPads * pads,
194     GstCollectData * data, GstEvent * event, gpointer user_data);
195 static GstPad *mpegtsmux_request_new_pad (GstElement * element,
196     GstPadTemplate * templ, const gchar * name, const GstCaps * caps);
197 static void mpegtsmux_release_pad (GstElement * element, GstPad * pad);
198 static GstStateChangeReturn mpegtsmux_change_state (GstElement * element,
199     GstStateChange transition);
200 static gboolean mpegtsmux_send_event (GstElement * element, GstEvent * event);
201 static void mpegtsmux_set_header_on_caps (MpegTsMux * mux);
202 static gboolean mpegtsmux_src_event (GstPad * pad, GstObject * parent,
203     GstEvent * event);
204
205 #if 0
206 static void mpegtsmux_set_index (GstElement * element, GstIndex * index);
207 static GstIndex *mpegtsmux_get_index (GstElement * element);
208
209 static GstFormat pts_format;
210 static GstFormat spn_format;
211 #endif
212
213 typedef struct
214 {
215   GstMapInfo map_info;
216   GstBuffer *buffer;
217 } StreamData;
218
219 G_DEFINE_TYPE (MpegTsMux, mpegtsmux, GST_TYPE_ELEMENT)
220
221 /* Takes over the ref on the buffer */
222      static StreamData *stream_data_new (GstBuffer * buffer)
223 {
224   StreamData *res = g_new (StreamData, 1);
225   res->buffer = buffer;
226   gst_buffer_map (buffer, &(res->map_info), GST_MAP_READ);
227
228   return res;
229 }
230
231 static void
232 stream_data_free (StreamData * data)
233 {
234   if (data) {
235     gst_buffer_unmap (data->buffer, &data->map_info);
236     gst_buffer_unref (data->buffer);
237     g_free (data);
238   }
239 }
240
241 #define parent_class mpegtsmux_parent_class
242
243 static void
244 mpegtsmux_class_init (MpegTsMuxClass * klass)
245 {
246   GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
247   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
248
249   gst_element_class_add_static_pad_template (gstelement_class,
250       &mpegtsmux_sink_factory);
251   gst_element_class_add_static_pad_template (gstelement_class,
252       &mpegtsmux_src_factory);
253
254   gst_element_class_set_static_metadata (gstelement_class,
255       "MPEG Transport Stream Muxer", "Codec/Muxer",
256       "Multiplexes media streams into an MPEG Transport Stream",
257       "Fluendo <contact@fluendo.com>");
258
259   gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_mpegtsmux_set_property);
260   gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_mpegtsmux_get_property);
261   gobject_class->dispose = mpegtsmux_dispose;
262
263   gstelement_class->request_new_pad = mpegtsmux_request_new_pad;
264   gstelement_class->release_pad = mpegtsmux_release_pad;
265   gstelement_class->change_state = mpegtsmux_change_state;
266   gstelement_class->send_event = mpegtsmux_send_event;
267
268 #if 0
269   gstelement_class->set_index = GST_DEBUG_FUNCPTR (mpegtsmux_set_index);
270   gstelement_class->get_index = GST_DEBUG_FUNCPTR (mpegtsmux_get_index);
271 #endif
272
273   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_PROG_MAP,
274       g_param_spec_boxed ("prog-map", "Program map",
275           "A GstStructure specifies the mapping from elementary streams to programs",
276           GST_TYPE_STRUCTURE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
277
278   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_M2TS_MODE,
279       g_param_spec_boolean ("m2ts-mode", "M2TS(192 bytes) Mode",
280           "Set to TRUE to output Blu-Ray disc format with 192 byte packets. "
281           "FALSE for standard TS format with 188 byte packets.",
282           MPEGTSMUX_DEFAULT_M2TS, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
283
284   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_PAT_INTERVAL,
285       g_param_spec_uint ("pat-interval", "PAT interval",
286           "Set the interval (in ticks of the 90kHz clock) for writing out the PAT table",
287           1, G_MAXUINT, TSMUX_DEFAULT_PAT_INTERVAL,
288           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
289
290   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_PMT_INTERVAL,
291       g_param_spec_uint ("pmt-interval", "PMT interval",
292           "Set the interval (in ticks of the 90kHz clock) for writing out the PMT table",
293           1, G_MAXUINT, TSMUX_DEFAULT_PMT_INTERVAL,
294           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
295
296   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_ALIGNMENT,
297       g_param_spec_int ("alignment", "packet alignment",
298           "Number of packets per buffer (padded with dummy packets on EOS) "
299           "(-1 = auto, 0 = all available packets, 7 for UDP streaming)",
300           -1, G_MAXINT, MPEGTSMUX_DEFAULT_ALIGNMENT,
301           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
302
303   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_SI_INTERVAL,
304       g_param_spec_uint ("si-interval", "SI interval",
305           "Set the interval (in ticks of the 90kHz clock) for writing out the Service"
306           "Information tables", 1, G_MAXUINT, TSMUX_DEFAULT_SI_INTERVAL,
307           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
308 }
309
310 static void
311 mpegtsmux_init (MpegTsMux * mux)
312 {
313   mux->srcpad =
314       gst_pad_new_from_static_template (&mpegtsmux_src_factory, "src");
315   gst_pad_use_fixed_caps (mux->srcpad);
316   gst_pad_set_event_function (mux->srcpad,
317       GST_DEBUG_FUNCPTR (mpegtsmux_src_event));
318   gst_element_add_pad (GST_ELEMENT (mux), mux->srcpad);
319
320   mux->collect = gst_collect_pads_new ();
321   gst_collect_pads_set_buffer_function (mux->collect,
322       (GstCollectPadsBufferFunction)
323       GST_DEBUG_FUNCPTR (mpegtsmux_collected_buffer), mux);
324
325   gst_collect_pads_set_event_function (mux->collect,
326       (GstCollectPadsEventFunction) GST_DEBUG_FUNCPTR (mpegtsmux_sink_event),
327       mux);
328   gst_collect_pads_set_clip_function (mux->collect, (GstCollectPadsClipFunction)
329       GST_DEBUG_FUNCPTR (mpegtsmux_clip_inc_running_time), mux);
330
331   mux->adapter = gst_adapter_new ();
332   mux->out_adapter = gst_adapter_new ();
333
334   /* properties */
335   mux->m2ts_mode = MPEGTSMUX_DEFAULT_M2TS;
336   mux->pat_interval = TSMUX_DEFAULT_PAT_INTERVAL;
337   mux->pmt_interval = TSMUX_DEFAULT_PMT_INTERVAL;
338   mux->si_interval = TSMUX_DEFAULT_SI_INTERVAL;
339   mux->prog_map = NULL;
340   mux->alignment = MPEGTSMUX_DEFAULT_ALIGNMENT;
341
342   /* initial state */
343   mpegtsmux_reset (mux, TRUE);
344 }
345
346 static void
347 mpegtsmux_pad_reset (MpegTsPadData * pad_data)
348 {
349   pad_data->dts = GST_CLOCK_STIME_NONE;
350   pad_data->prog_id = -1;
351 #if 0
352   pad_data->prog_id = -1;
353   pad_data->element_index_writer_id = -1;
354 #endif
355
356   if (pad_data->free_func)
357     pad_data->free_func (pad_data->prepare_data);
358   pad_data->prepare_data = NULL;
359   pad_data->prepare_func = NULL;
360   pad_data->free_func = NULL;
361
362   if (pad_data->codec_data)
363     gst_buffer_replace (&pad_data->codec_data, NULL);
364
365   /* reference owned elsewhere */
366   pad_data->stream = NULL;
367   pad_data->prog = NULL;
368
369   if (pad_data->language) {
370     g_free (pad_data->language);
371     pad_data->language = NULL;
372   }
373
374 }
375
376 static void
377 mpegtsmux_reset (MpegTsMux * mux, gboolean alloc)
378 {
379   GstBuffer *buf;
380   GSList *walk;
381
382   mux->first = TRUE;
383   mux->last_flow_ret = GST_FLOW_OK;
384   mux->previous_pcr = -1;
385   mux->previous_offset = 0;
386   mux->pcr_rate_num = mux->pcr_rate_den = 1;
387   mux->last_ts = 0;
388   mux->is_delta = TRUE;
389   mux->is_header = FALSE;
390
391   mux->streamheader_sent = FALSE;
392   mux->pending_key_unit_ts = GST_CLOCK_TIME_NONE;
393   gst_event_replace (&mux->force_key_unit_event, NULL);
394 #if 0
395   mux->spn_count = 0;
396
397   if (mux->element_index) {
398     gst_object_unref (mux->element_index);
399     mux->element_index = NULL;
400   }
401 #endif
402   if (mux->adapter)
403     gst_adapter_clear (mux->adapter);
404   if (mux->out_adapter)
405     gst_adapter_clear (mux->out_adapter);
406
407   if (mux->tsmux) {
408     tsmux_free (mux->tsmux);
409     mux->tsmux = NULL;
410   }
411
412   if (mux->programs) {
413     g_hash_table_destroy (mux->programs);
414   }
415   mux->programs = g_hash_table_new (g_direct_hash, g_direct_equal);
416
417   while ((buf = g_queue_pop_head (&mux->streamheader)))
418     gst_buffer_unref (buf);
419
420   gst_event_replace (&mux->force_key_unit_event, NULL);
421   gst_buffer_replace (&mux->out_buffer, NULL);
422
423   if (mux->collect) {
424     GST_COLLECT_PADS_STREAM_LOCK (mux->collect);
425     for (walk = mux->collect->data; walk != NULL; walk = g_slist_next (walk))
426       mpegtsmux_pad_reset ((MpegTsPadData *) walk->data);
427     GST_COLLECT_PADS_STREAM_UNLOCK (mux->collect);
428   }
429
430   if (alloc) {
431     mux->tsmux = tsmux_new ();
432     tsmux_set_write_func (mux->tsmux, new_packet_cb, mux);
433     tsmux_set_alloc_func (mux->tsmux, alloc_packet_cb, mux);
434   }
435 }
436
437 static void
438 mpegtsmux_dispose (GObject * object)
439 {
440   MpegTsMux *mux = GST_MPEG_TSMUX (object);
441
442   mpegtsmux_reset (mux, FALSE);
443
444   if (mux->adapter) {
445     g_object_unref (mux->adapter);
446     mux->adapter = NULL;
447   }
448   if (mux->out_adapter) {
449     g_object_unref (mux->out_adapter);
450     mux->out_adapter = NULL;
451   }
452   if (mux->collect) {
453     gst_object_unref (mux->collect);
454     mux->collect = NULL;
455   }
456   if (mux->prog_map) {
457     gst_structure_free (mux->prog_map);
458     mux->prog_map = NULL;
459   }
460   if (mux->programs) {
461     g_hash_table_destroy (mux->programs);
462     mux->programs = NULL;
463   }
464   GST_CALL_PARENT (G_OBJECT_CLASS, dispose, (object));
465 }
466
467 static void
468 gst_mpegtsmux_set_property (GObject * object, guint prop_id,
469     const GValue * value, GParamSpec * pspec)
470 {
471   MpegTsMux *mux = GST_MPEG_TSMUX (object);
472   GSList *walk;
473
474   switch (prop_id) {
475     case PROP_M2TS_MODE:
476       /*set incase if the output stream need to be of 192 bytes */
477       mux->m2ts_mode = g_value_get_boolean (value);
478       break;
479     case PROP_PROG_MAP:
480     {
481       const GstStructure *s = gst_value_get_structure (value);
482       if (mux->prog_map) {
483         gst_structure_free (mux->prog_map);
484       }
485       if (s)
486         mux->prog_map = gst_structure_copy (s);
487       else
488         mux->prog_map = NULL;
489       break;
490     }
491     case PROP_PAT_INTERVAL:
492       mux->pat_interval = g_value_get_uint (value);
493       if (mux->tsmux)
494         tsmux_set_pat_interval (mux->tsmux, mux->pat_interval);
495       break;
496     case PROP_PMT_INTERVAL:
497       walk = mux->collect->data;
498       mux->pmt_interval = g_value_get_uint (value);
499
500       while (walk) {
501         MpegTsPadData *ts_data = (MpegTsPadData *) walk->data;
502
503         tsmux_set_pmt_interval (ts_data->prog, mux->pmt_interval);
504         walk = g_slist_next (walk);
505       }
506       break;
507     case PROP_ALIGNMENT:
508       mux->alignment = g_value_get_int (value);
509       break;
510     case PROP_SI_INTERVAL:
511       mux->si_interval = g_value_get_uint (value);
512       tsmux_set_si_interval (mux->tsmux, mux->si_interval);
513       break;
514     default:
515       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
516       break;
517   }
518 }
519
520 static void
521 gst_mpegtsmux_get_property (GObject * object, guint prop_id,
522     GValue * value, GParamSpec * pspec)
523 {
524   MpegTsMux *mux = GST_MPEG_TSMUX (object);
525
526   switch (prop_id) {
527     case PROP_M2TS_MODE:
528       g_value_set_boolean (value, mux->m2ts_mode);
529       break;
530     case PROP_PROG_MAP:
531       gst_value_set_structure (value, mux->prog_map);
532       break;
533     case PROP_PAT_INTERVAL:
534       g_value_set_uint (value, mux->pat_interval);
535       break;
536     case PROP_PMT_INTERVAL:
537       g_value_set_uint (value, mux->pmt_interval);
538       break;
539     case PROP_ALIGNMENT:
540       g_value_set_int (value, mux->alignment);
541       break;
542     case PROP_SI_INTERVAL:
543       g_value_set_uint (value, mux->si_interval);
544       break;
545     default:
546       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
547       break;
548   }
549 }
550
551 #if 0
552 static void
553 mpegtsmux_set_index (GstElement * element, GstIndex * index)
554 {
555   MpegTsMux *mux = GST_MPEG_TSMUX (element);
556
557   GST_OBJECT_LOCK (mux);
558   if (mux->element_index)
559     gst_object_unref (mux->element_index);
560   mux->element_index = index ? gst_object_ref (index) : NULL;
561   GST_OBJECT_UNLOCK (mux);
562
563   GST_DEBUG_OBJECT (mux, "Set index %" GST_PTR_FORMAT, mux->element_index);
564 }
565
566 static GstIndex *
567 mpegtsmux_get_index (GstElement * element)
568 {
569   GstIndex *result = NULL;
570   MpegTsMux *mux = GST_MPEG_TSMUX (element);
571
572   GST_OBJECT_LOCK (mux);
573   if (mux->element_index)
574     result = gst_object_ref (mux->element_index);
575   GST_OBJECT_UNLOCK (mux);
576
577   GST_DEBUG_OBJECT (mux, "Returning index %" GST_PTR_FORMAT, result);
578
579   return result;
580 }
581 #endif
582
583 static void
584 release_buffer_cb (guint8 * data, void *user_data)
585 {
586   stream_data_free (user_data);
587 }
588
589 static GstFlowReturn
590 mpegtsmux_create_stream (MpegTsMux * mux, MpegTsPadData * ts_data)
591 {
592   GstFlowReturn ret = GST_FLOW_ERROR;
593   GstCaps *caps;
594   GstStructure *s;
595   GstPad *pad;
596   TsMuxStreamType st = TSMUX_ST_RESERVED;
597   const gchar *mt;
598   const GValue *value = NULL;
599   GstBuffer *codec_data = NULL;
600   guint8 opus_channel_config_code = 0;
601   guint16 profile = 0;
602   guint8 main_level = 0;
603   guint32 max_rate = 0;
604   guint8 color_spec = 0;
605   j2k_private_data *private_data = NULL;
606
607   pad = ts_data->collect.pad;
608   caps = gst_pad_get_current_caps (pad);
609   if (caps == NULL)
610     goto not_negotiated;
611
612   GST_DEBUG_OBJECT (pad, "Creating stream with PID 0x%04x for caps %"
613       GST_PTR_FORMAT, ts_data->pid, caps);
614
615   s = gst_caps_get_structure (caps, 0);
616
617   mt = gst_structure_get_name (s);
618   value = gst_structure_get_value (s, "codec_data");
619   if (value != NULL)
620     codec_data = gst_value_get_buffer (value);
621
622   if (strcmp (mt, "video/x-dirac") == 0) {
623     st = TSMUX_ST_VIDEO_DIRAC;
624   } else if (strcmp (mt, "audio/x-ac3") == 0) {
625     st = TSMUX_ST_PS_AUDIO_AC3;
626   } else if (strcmp (mt, "audio/x-dts") == 0) {
627     st = TSMUX_ST_PS_AUDIO_DTS;
628   } else if (strcmp (mt, "audio/x-lpcm") == 0) {
629     st = TSMUX_ST_PS_AUDIO_LPCM;
630   } else if (strcmp (mt, "video/x-h264") == 0) {
631     st = TSMUX_ST_VIDEO_H264;
632   } else if (strcmp (mt, "video/x-h265") == 0) {
633     st = TSMUX_ST_VIDEO_HEVC;
634   } else if (strcmp (mt, "audio/mpeg") == 0) {
635     gint mpegversion;
636
637     if (!gst_structure_get_int (s, "mpegversion", &mpegversion)) {
638       GST_ERROR_OBJECT (pad, "caps missing mpegversion");
639       goto not_negotiated;
640     }
641
642     switch (mpegversion) {
643       case 1:
644         st = TSMUX_ST_AUDIO_MPEG1;
645         break;
646       case 2:
647         st = TSMUX_ST_AUDIO_MPEG2;
648         break;
649       case 4:
650       {
651         st = TSMUX_ST_AUDIO_AAC;
652         if (codec_data) {       /* TODO - Check stream format - codec data should only come with RAW stream */
653           GST_DEBUG_OBJECT (pad,
654               "we have additional codec data (%" G_GSIZE_FORMAT " bytes)",
655               gst_buffer_get_size (codec_data));
656           ts_data->codec_data = gst_buffer_ref (codec_data);
657           ts_data->prepare_func = mpegtsmux_prepare_aac;
658         } else {
659           ts_data->codec_data = NULL;
660         }
661         break;
662       }
663       default:
664         GST_WARNING_OBJECT (pad, "unsupported mpegversion %d", mpegversion);
665         goto not_negotiated;
666     }
667   } else if (strcmp (mt, "video/mpeg") == 0) {
668     gint mpegversion;
669
670     if (!gst_structure_get_int (s, "mpegversion", &mpegversion)) {
671       GST_ERROR_OBJECT (pad, "caps missing mpegversion");
672       goto not_negotiated;
673     }
674
675     switch (mpegversion) {
676       case 1:
677         st = TSMUX_ST_VIDEO_MPEG1;
678         break;
679       case 2:
680         st = TSMUX_ST_VIDEO_MPEG2;
681         break;
682       case 4:
683         st = TSMUX_ST_VIDEO_MPEG4;
684         break;
685       default:
686         GST_WARNING_OBJECT (pad, "unsupported mpegversion %d", mpegversion);
687         goto not_negotiated;
688     }
689   } else if (strcmp (mt, "subpicture/x-dvb") == 0) {
690     st = TSMUX_ST_PS_DVB_SUBPICTURE;
691   } else if (strcmp (mt, "application/x-teletext") == 0) {
692     st = TSMUX_ST_PS_TELETEXT;
693     /* needs a particularly sized layout */
694     ts_data->prepare_func = mpegtsmux_prepare_teletext;
695   } else if (strcmp (mt, "audio/x-opus") == 0) {
696     guint8 channels, mapping_family, stream_count, coupled_count;
697     guint8 channel_mapping[256];
698
699     if (!gst_codec_utils_opus_parse_caps (caps, NULL, &channels,
700             &mapping_family, &stream_count, &coupled_count, channel_mapping)) {
701       GST_ERROR_OBJECT (pad, "Incomplete Opus caps");
702       goto not_negotiated;
703     }
704
705     if (channels <= 2 && mapping_family == 0) {
706       opus_channel_config_code = channels;
707     } else if (channels == 2 && mapping_family == 255 && stream_count == 1
708         && coupled_count == 1) {
709       /* Dual mono */
710       opus_channel_config_code = 0;
711     } else if (channels >= 2 && channels <= 8 && mapping_family == 1) {
712       static const guint8 coupled_stream_counts[9] = {
713         1, 0, 1, 1, 2, 2, 2, 3, 3
714       };
715       static const guint8 channel_map_a[8][8] = {
716         {0},
717         {0, 1},
718         {0, 2, 1},
719         {0, 1, 2, 3},
720         {0, 4, 1, 2, 3},
721         {0, 4, 1, 2, 3, 5},
722         {0, 4, 1, 2, 3, 5, 6},
723         {0, 6, 1, 2, 3, 4, 5, 7},
724       };
725       static const guint8 channel_map_b[8][8] = {
726         {0},
727         {0, 1},
728         {0, 1, 2},
729         {0, 1, 2, 3},
730         {0, 1, 2, 3, 4},
731         {0, 1, 2, 3, 4, 5},
732         {0, 1, 2, 3, 4, 5, 6},
733         {0, 1, 2, 3, 4, 5, 6, 7},
734       };
735
736       /* Vorbis mapping */
737       if (stream_count == channels - coupled_stream_counts[channels] &&
738           coupled_count == coupled_stream_counts[channels] &&
739           memcmp (channel_mapping, channel_map_a[channels - 1],
740               channels) == 0) {
741         opus_channel_config_code = channels;
742       } else if (stream_count == channels - coupled_stream_counts[channels] &&
743           coupled_count == coupled_stream_counts[channels] &&
744           memcmp (channel_mapping, channel_map_b[channels - 1],
745               channels) == 0) {
746         opus_channel_config_code = channels | 0x80;
747       } else {
748         GST_FIXME_OBJECT (pad, "Opus channel mapping not handled");
749         goto not_negotiated;
750       }
751     }
752
753     st = TSMUX_ST_PS_OPUS;
754     ts_data->prepare_func = mpegtsmux_prepare_opus;
755   } else if (strcmp (mt, "meta/x-klv") == 0) {
756     st = TSMUX_ST_PS_KLV;
757   } else if (strcmp (mt, "image/x-jpc") == 0) {
758     /*
759      * See this document for more details on standard:
760      *
761      * https://www.itu.int/rec/T-REC-H.222.0-201206-S/en
762      *  Annex S describes J2K details
763      *  Page 104 of this document describes J2k video descriptor
764      */
765
766     const GValue *vProfile = gst_structure_get_value (s, "profile");
767     const GValue *vMainlevel = gst_structure_get_value (s, "main-level");
768     const GValue *vFramerate = gst_structure_get_value (s, "framerate");
769     const GValue *vColorimetry = gst_structure_get_value (s, "colorimetry");
770     private_data = g_new0 (j2k_private_data, 1);
771     profile = g_value_get_uint (vProfile);
772     if (profile != GST_JPEG2000_PARSE_PROFILE_BC_SINGLE) {
773       /* for now, we will relax the condition that the profile must equal GST_JPEG2000_PARSE_PROFILE_BC_SINGLE */
774       /*GST_ERROR_OBJECT (pad, "Invalid JPEG 2000 profile %d", profile);
775          goto not_negotiated; */
776     }
777     /* for now, we will relax the condition that the main level must be present */
778     if (vMainlevel) {
779       main_level = g_value_get_uint (vMainlevel);
780       if (main_level > 11) {
781         GST_ERROR_OBJECT (pad, "Invalid main level %d", main_level);
782         goto not_negotiated;
783       }
784       if (main_level >= 6) {
785         max_rate = 2 ^ (main_level - 6) * 1600 * 1000000;
786       } else {
787         switch (main_level) {
788           case 0:
789           case 1:
790           case 2:
791           case 3:
792             max_rate = 200 * 1000000;
793             break;
794           case 4:
795             max_rate = 400 * 1000000;
796             break;
797           case 5:
798             max_rate = 800 * 1000000;
799             break;
800           default:
801             break;
802         }
803       }
804     } else {
805       /*GST_ERROR_OBJECT (pad, "Missing main level");
806          goto not_negotiated; */
807     }
808     /* We always mux video in J2K-over-MPEG-TS non-interlaced mode */
809     private_data->interlace = FALSE;
810     private_data->den = 0;
811     private_data->num = 0;
812     private_data->max_bitrate = max_rate;
813     private_data->color_spec = 1;
814     /* these two fields are not used, since we always mux as non-interlaced */
815     private_data->Fic = 1;
816     private_data->Fio = 0;
817
818     /* Get Framerate */
819     if (vFramerate != NULL) {
820       /* Data for ELSM header */
821       private_data->num = gst_value_get_fraction_numerator (vFramerate);
822       private_data->den = gst_value_get_fraction_denominator (vFramerate);
823     }
824     /* Get Colorimetry */
825     if (vColorimetry) {
826       const char *colorimetry = g_value_get_string (vColorimetry);
827       color_spec = GST_MPEGTS_JPEG2000_COLORSPEC_SRGB;  /* RGB as default */
828       if (g_str_equal (colorimetry, GST_VIDEO_COLORIMETRY_BT601)) {
829         color_spec = GST_MPEGTS_JPEG2000_COLORSPEC_REC601;
830       } else {
831         if (g_str_equal (colorimetry, GST_VIDEO_COLORIMETRY_BT709)
832             || g_str_equal (colorimetry, GST_VIDEO_COLORIMETRY_SMPTE240M)) {
833           color_spec = GST_MPEGTS_JPEG2000_COLORSPEC_REC709;
834         }
835       }
836       private_data->color_spec = color_spec;
837     } else {
838       GST_ERROR_OBJECT (pad, "Colorimetry not present in caps");
839       goto not_negotiated;
840     }
841     st = TSMUX_ST_VIDEO_JP2K;
842     ts_data->prepare_func = mpegtsmux_prepare_jpeg2000;
843     ts_data->prepare_data = private_data;
844     ts_data->free_func = mpegtsmux_free_jpeg2000;
845   }
846
847   if (st != TSMUX_ST_RESERVED) {
848     ts_data->stream = tsmux_create_stream (mux->tsmux, st, ts_data->pid,
849         ts_data->language);
850   } else {
851     GST_DEBUG_OBJECT (pad, "Failed to determine stream type");
852   }
853
854   if (ts_data->stream != NULL) {
855     const char *interlace_mode = gst_structure_get_string (s, "interlace-mode");
856     gst_structure_get_int (s, "rate", &ts_data->stream->audio_sampling);
857     gst_structure_get_int (s, "channels", &ts_data->stream->audio_channels);
858     gst_structure_get_int (s, "bitrate", &ts_data->stream->audio_bitrate);
859
860     /* frame rate */
861     gst_structure_get_fraction (s, "framerate", &ts_data->stream->num,
862         &ts_data->stream->den);
863
864     /* Interlace mode */
865     ts_data->stream->interlace_mode = FALSE;
866     if (interlace_mode) {
867       ts_data->stream->interlace_mode =
868           g_str_equal (interlace_mode, "interleaved");
869     }
870     /* Width and Height */
871     gst_structure_get_int (s, "width", &ts_data->stream->horizontal_size);
872     gst_structure_get_int (s, "height", &ts_data->stream->vertical_size);
873
874     ts_data->stream->color_spec = color_spec;
875     ts_data->stream->max_bitrate = max_rate;
876     ts_data->stream->profile_and_level = profile | main_level;
877
878     ts_data->stream->opus_channel_config_code = opus_channel_config_code;
879
880     tsmux_stream_set_buffer_release_func (ts_data->stream, release_buffer_cb);
881     tsmux_program_add_stream (ts_data->prog, ts_data->stream);
882
883     ret = GST_FLOW_OK;
884   }
885 #if 0
886   GST_OBJECT_LOCK (mux);
887   if (mux->element_index) {
888     gboolean parsed = FALSE;
889
890     if (ts_data->stream->is_video_stream) {
891       if (gst_structure_get_boolean (s, "parsed", &parsed) && parsed) {
892         if (ts_data->element_index_writer_id == -1) {
893           gst_index_get_writer_id (mux->element_index, GST_OBJECT (mux),
894               &ts_data->element_index_writer_id);
895           GST_DEBUG_OBJECT (mux, "created GstIndex writer_id = %d for stream",
896               ts_data->element_index_writer_id);
897           gst_index_add_format (mux->element_index,
898               ts_data->element_index_writer_id, pts_format);
899           gst_index_add_format (mux->element_index,
900               ts_data->element_index_writer_id, spn_format);
901         }
902       } else {
903         GST_WARNING_OBJECT (pad, "no indexing for (unparsed) stream !");
904       }
905     }
906   }
907   GST_OBJECT_UNLOCK (mux);
908 #endif
909   gst_caps_unref (caps);
910   return ret;
911   /* ERRORS */
912 not_negotiated:
913   {
914     g_free (private_data);
915     GST_DEBUG_OBJECT (pad, "Sink pad caps were not set before pushing");
916     if (caps)
917       gst_caps_unref (caps);
918     return GST_FLOW_NOT_NEGOTIATED;
919   }
920 }
921
922 static GstFlowReturn
923 mpegtsmux_create_streams (MpegTsMux * mux)
924 {
925   GstFlowReturn ret = GST_FLOW_OK;
926   GSList *walk = mux->collect->data;
927
928   /* Create the streams */
929   while (walk) {
930     GstCollectData *c_data = (GstCollectData *) walk->data;
931     MpegTsPadData *ts_data = (MpegTsPadData *) walk->data;
932     gchar *name = NULL;
933
934     walk = g_slist_next (walk);
935
936     if (ts_data->prog_id == -1) {
937       name = GST_PAD_NAME (c_data->pad);
938       if (mux->prog_map != NULL && gst_structure_has_field (mux->prog_map,
939               name)) {
940         gint idx;
941         gboolean ret = gst_structure_get_int (mux->prog_map, name, &idx);
942         if (!ret) {
943           GST_ELEMENT_ERROR (mux, STREAM, MUX,
944               ("Reading program map failed. Assuming default"), (NULL));
945           idx = DEFAULT_PROG_ID;
946         }
947         if (idx < 0) {
948           GST_DEBUG_OBJECT (mux, "Program number %d associate with pad %s less "
949               "than zero; DEFAULT_PROGRAM = %d is used instead",
950               idx, name, DEFAULT_PROG_ID);
951           idx = DEFAULT_PROG_ID;
952         }
953         ts_data->prog_id = idx;
954       } else {
955         ts_data->prog_id = DEFAULT_PROG_ID;
956       }
957     }
958
959     ts_data->prog =
960         g_hash_table_lookup (mux->programs, GINT_TO_POINTER (ts_data->prog_id));
961     if (ts_data->prog == NULL) {
962       ts_data->prog = tsmux_program_new (mux->tsmux, ts_data->prog_id);
963       if (ts_data->prog == NULL)
964         goto no_program;
965       tsmux_set_pmt_interval (ts_data->prog, mux->pmt_interval);
966       g_hash_table_insert (mux->programs,
967           GINT_TO_POINTER (ts_data->prog_id), ts_data->prog);
968
969       /* Take the first stream of the program for the PCR */
970       GST_DEBUG_OBJECT (COLLECT_DATA_PAD (ts_data),
971           "Use stream (pid=%d) from pad as PCR for program (prog_id = %d)",
972           ts_data->pid, ts_data->prog_id);
973
974       tsmux_program_set_pcr_stream (ts_data->prog, ts_data->stream);
975     }
976
977     if (ts_data->stream == NULL) {
978       ret = mpegtsmux_create_stream (mux, ts_data);
979       if (ret != GST_FLOW_OK)
980         goto no_stream;
981     }
982   }
983
984   return GST_FLOW_OK;
985
986   /* ERRORS */
987 no_program:
988   {
989     GST_ELEMENT_ERROR (mux, STREAM, MUX,
990         ("Could not create new program"), (NULL));
991     return GST_FLOW_ERROR;
992   }
993 no_stream:
994   {
995     GST_ELEMENT_ERROR (mux, STREAM, MUX,
996         ("Could not create handler for stream"), (NULL));
997     return ret;
998   }
999 }
1000
1001 static gboolean
1002 mpegtsmux_sink_event (GstCollectPads * pads, GstCollectData * data,
1003     GstEvent * event, gpointer user_data)
1004 {
1005   MpegTsMux *mux = GST_MPEG_TSMUX (user_data);
1006   gboolean res = FALSE;
1007   gboolean forward = TRUE;
1008   MpegTsPadData *pad_data = (MpegTsPadData *) data;
1009
1010 #ifndef GST_DISABLE_GST_DEBUG
1011   GstPad *pad;
1012
1013   pad = data->pad;
1014 #endif
1015
1016   switch (GST_EVENT_TYPE (event)) {
1017     case GST_EVENT_CUSTOM_DOWNSTREAM:
1018     {
1019       GstClockTime timestamp, stream_time, running_time;
1020       gboolean all_headers;
1021       guint count;
1022
1023       if (!gst_video_event_is_force_key_unit (event))
1024         goto out;
1025
1026       res = TRUE;
1027       forward = FALSE;
1028
1029       gst_video_event_parse_downstream_force_key_unit (event,
1030           &timestamp, &stream_time, &running_time, &all_headers, &count);
1031       GST_INFO_OBJECT (pad, "have downstream force-key-unit event, "
1032           "seqnum %d, running-time %" GST_TIME_FORMAT " count %d",
1033           gst_event_get_seqnum (event), GST_TIME_ARGS (running_time), count);
1034
1035       if (mux->force_key_unit_event != NULL) {
1036         GST_INFO_OBJECT (mux, "skipping downstream force key unit event "
1037             "as an upstream force key unit is already queued");
1038         goto out;
1039       }
1040
1041       if (!all_headers)
1042         goto out;
1043
1044       mux->pending_key_unit_ts = running_time;
1045       gst_event_replace (&mux->force_key_unit_event, event);
1046       break;
1047     }
1048     case GST_EVENT_TAG:{
1049       GstTagList *list;
1050       gchar *lang = NULL;
1051
1052       GST_DEBUG_OBJECT (mux, "received tag event");
1053       gst_event_parse_tag (event, &list);
1054
1055       /* Matroska wants ISO 639-2B code, taglist most likely contains 639-1 */
1056       if (gst_tag_list_get_string (list, GST_TAG_LANGUAGE_CODE, &lang)) {
1057         const gchar *lang_code;
1058
1059         lang_code = gst_tag_get_language_code_iso_639_2B (lang);
1060         if (lang_code) {
1061           GST_DEBUG_OBJECT (pad, "Setting language to '%s'", lang_code);
1062
1063           g_free (pad_data->language);
1064           pad_data->language = g_strdup (lang_code);
1065         } else {
1066           GST_WARNING_OBJECT (pad, "Did not get language code for '%s'", lang);
1067         }
1068         g_free (lang);
1069       }
1070
1071       /* handled this, don't want collectpads to forward it downstream */
1072       res = TRUE;
1073       forward = gst_tag_list_get_scope (list) == GST_TAG_SCOPE_GLOBAL;
1074       break;
1075     }
1076     case GST_EVENT_STREAM_START:{
1077       GstStreamFlags flags;
1078
1079       gst_event_parse_stream_flags (event, &flags);
1080
1081       /* Don't wait for data on sparse inputs like metadata streams */
1082       if ((flags & GST_STREAM_FLAG_SPARSE)) {
1083         GST_COLLECT_PADS_STATE_UNSET (data, GST_COLLECT_PADS_STATE_LOCKED);
1084         gst_collect_pads_set_waiting (pads, data, FALSE);
1085         GST_COLLECT_PADS_STATE_SET (data, GST_COLLECT_PADS_STATE_LOCKED);
1086       }
1087       break;
1088     }
1089     default:
1090       break;
1091   }
1092
1093 out:
1094   if (!forward)
1095     gst_event_unref (event);
1096   else
1097     res = gst_collect_pads_event_default (pads, data, event, FALSE);
1098
1099   return res;
1100 }
1101
1102 static gboolean
1103 mpegtsmux_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
1104 {
1105   MpegTsMux *mux = GST_MPEG_TSMUX (parent);
1106   gboolean res = TRUE, forward = TRUE;
1107
1108   switch (GST_EVENT_TYPE (event)) {
1109     case GST_EVENT_CUSTOM_UPSTREAM:
1110     {
1111       GstIterator *iter;
1112       GstIteratorResult iter_ret;
1113       GstPad *sinkpad;
1114       GValue sinkpad_value = G_VALUE_INIT;
1115       GstClockTime running_time;
1116       gboolean all_headers, done, res = FALSE;
1117       guint count;
1118
1119       if (!gst_video_event_is_force_key_unit (event))
1120         break;
1121
1122       forward = FALSE;
1123
1124       gst_video_event_parse_upstream_force_key_unit (event,
1125           &running_time, &all_headers, &count);
1126
1127       GST_INFO_OBJECT (mux, "received upstream force-key-unit event, "
1128           "seqnum %d running_time %" GST_TIME_FORMAT " all_headers %d count %d",
1129           gst_event_get_seqnum (event), GST_TIME_ARGS (running_time),
1130           all_headers, count);
1131
1132       if (!all_headers)
1133         break;
1134
1135       mux->pending_key_unit_ts = running_time;
1136       gst_event_replace (&mux->force_key_unit_event, event);
1137
1138       iter = gst_element_iterate_sink_pads (GST_ELEMENT_CAST (mux));
1139       done = FALSE;
1140       while (!done) {
1141         gboolean tmp;
1142
1143         iter_ret = gst_iterator_next (iter, &sinkpad_value);
1144         sinkpad = g_value_get_object (&sinkpad_value);
1145
1146         switch (iter_ret) {
1147           case GST_ITERATOR_DONE:
1148             done = TRUE;
1149             break;
1150           case GST_ITERATOR_OK:
1151             GST_INFO_OBJECT (pad, "forwarding");
1152             tmp = gst_pad_push_event (sinkpad, gst_event_ref (event));
1153             GST_INFO_OBJECT (mux, "result %d", tmp);
1154             /* succeed if at least one pad succeeds */
1155             res |= tmp;
1156             break;
1157           case GST_ITERATOR_ERROR:
1158             done = TRUE;
1159             break;
1160           case GST_ITERATOR_RESYNC:
1161             break;
1162         }
1163         g_value_reset (&sinkpad_value);
1164       }
1165       g_value_unset (&sinkpad_value);
1166       gst_iterator_free (iter);
1167       break;
1168     }
1169     default:
1170       break;
1171   }
1172
1173   if (forward)
1174     res = gst_pad_event_default (pad, parent, event);
1175   else
1176     gst_event_unref (event);
1177
1178   return res;
1179 }
1180
1181 static GstEvent *
1182 check_pending_key_unit_event (GstEvent * pending_event, GstSegment * segment,
1183     GstClockTime timestamp, guint flags, GstClockTime pending_key_unit_ts)
1184 {
1185   GstClockTime running_time, stream_time;
1186   gboolean all_headers;
1187   guint count;
1188   GstEvent *event = NULL;
1189
1190   g_assert (segment != NULL);
1191
1192   if (pending_event == NULL)
1193     goto out;
1194
1195   if (GST_CLOCK_TIME_IS_VALID (pending_key_unit_ts) &&
1196       timestamp == GST_CLOCK_TIME_NONE)
1197     goto out;
1198
1199   running_time = timestamp;
1200
1201   GST_INFO ("now %" GST_TIME_FORMAT " wanted %" GST_TIME_FORMAT,
1202       GST_TIME_ARGS (running_time), GST_TIME_ARGS (pending_key_unit_ts));
1203   if (GST_CLOCK_TIME_IS_VALID (pending_key_unit_ts) &&
1204       running_time < pending_key_unit_ts)
1205     goto out;
1206
1207   if (flags & GST_BUFFER_FLAG_DELTA_UNIT) {
1208     GST_INFO ("pending force key unit, waiting for keyframe");
1209     goto out;
1210   }
1211
1212   stream_time = gst_segment_to_stream_time (segment,
1213       GST_FORMAT_TIME, timestamp);
1214
1215   if (GST_EVENT_TYPE (pending_event) == GST_EVENT_CUSTOM_DOWNSTREAM) {
1216     gst_video_event_parse_downstream_force_key_unit (pending_event,
1217         NULL, NULL, NULL, &all_headers, &count);
1218   } else {
1219     gst_video_event_parse_upstream_force_key_unit (pending_event, NULL,
1220         &all_headers, &count);
1221   }
1222
1223   event =
1224       gst_video_event_new_downstream_force_key_unit (timestamp, stream_time,
1225       running_time, all_headers, count);
1226   gst_event_set_seqnum (event, gst_event_get_seqnum (pending_event));
1227
1228 out:
1229   return event;
1230 }
1231
1232 GstFlowReturn
1233 mpegtsmux_clip_inc_running_time (GstCollectPads * pads,
1234     GstCollectData * cdata, GstBuffer * buf, GstBuffer ** outbuf,
1235     gpointer user_data)
1236 {
1237   MpegTsPadData *pad_data = (MpegTsPadData *) cdata;
1238   GstClockTime time;
1239
1240   *outbuf = buf;
1241
1242   /* PTS */
1243   time = GST_BUFFER_PTS (buf);
1244
1245   /* invalid left alone and passed */
1246   if (G_LIKELY (GST_CLOCK_TIME_IS_VALID (time))) {
1247     time = gst_segment_to_running_time (&cdata->segment, GST_FORMAT_TIME, time);
1248     if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (time))) {
1249       GST_DEBUG_OBJECT (cdata->pad, "clipping buffer on pad outside segment");
1250       gst_buffer_unref (buf);
1251       *outbuf = NULL;
1252       goto beach;
1253     } else {
1254       GST_LOG_OBJECT (cdata->pad, "buffer pts %" GST_TIME_FORMAT " ->  %"
1255           GST_TIME_FORMAT " running time",
1256           GST_TIME_ARGS (GST_BUFFER_PTS (buf)), GST_TIME_ARGS (time));
1257       buf = *outbuf = gst_buffer_make_writable (buf);
1258       GST_BUFFER_PTS (*outbuf) = time;
1259     }
1260   }
1261
1262   /* DTS */
1263   time = GST_BUFFER_DTS (buf);
1264
1265   /* invalid left alone and passed */
1266   if (G_LIKELY (GST_CLOCK_TIME_IS_VALID (time))) {
1267     gint sign;
1268     gint64 dts;
1269
1270     sign = gst_segment_to_running_time_full (&cdata->segment, GST_FORMAT_TIME,
1271         time, &time);
1272
1273     if (sign > 0)
1274       dts = (gint64) time;
1275     else
1276       dts = -((gint64) time);
1277
1278     GST_LOG_OBJECT (cdata->pad, "buffer dts %" GST_TIME_FORMAT " -> %"
1279         GST_STIME_FORMAT " running time", GST_TIME_ARGS (GST_BUFFER_DTS (buf)),
1280         GST_STIME_ARGS (dts));
1281
1282     if (GST_CLOCK_STIME_IS_VALID (pad_data->dts) && dts < pad_data->dts) {
1283       /* Ignore DTS going backward */
1284       GST_WARNING_OBJECT (cdata->pad, "ignoring DTS going backward");
1285       dts = pad_data->dts;
1286     }
1287
1288     *outbuf = gst_buffer_make_writable (buf);
1289     if (sign > 0)
1290       GST_BUFFER_DTS (*outbuf) = time;
1291     else
1292       GST_BUFFER_DTS (*outbuf) = GST_CLOCK_TIME_NONE;
1293
1294     pad_data->dts = dts;
1295   } else {
1296     pad_data->dts = GST_CLOCK_STIME_NONE;
1297   }
1298
1299 beach:
1300   return GST_FLOW_OK;
1301 }
1302
1303 static GstFlowReturn
1304 mpegtsmux_collected_buffer (GstCollectPads * pads, GstCollectData * data,
1305     GstBuffer * buf, MpegTsMux * mux)
1306 {
1307   GstFlowReturn ret = GST_FLOW_OK;
1308   MpegTsPadData *best = (MpegTsPadData *) data;
1309   TsMuxProgram *prog;
1310   gint64 pts = GST_CLOCK_STIME_NONE;
1311   gint64 dts = GST_CLOCK_STIME_NONE;
1312   gboolean delta = TRUE, header = FALSE;
1313   StreamData *stream_data;
1314
1315   GST_DEBUG_OBJECT (mux, "Pads collected");
1316
1317   if (G_UNLIKELY (mux->first)) {
1318     ret = mpegtsmux_create_streams (mux);
1319     if (G_UNLIKELY (ret != GST_FLOW_OK)) {
1320       if (buf)
1321         gst_buffer_unref (buf);
1322       return ret;
1323     }
1324
1325     mpegtsmux_prepare_srcpad (mux);
1326
1327     mux->first = FALSE;
1328   }
1329
1330   if (G_UNLIKELY (best == NULL)) {
1331     /* EOS */
1332     GST_INFO_OBJECT (mux, "EOS");
1333     /* drain some possibly cached data */
1334     new_packet_m2ts (mux, NULL, -1);
1335     mpegtsmux_push_packets (mux, TRUE);
1336     gst_pad_push_event (mux->srcpad, gst_event_new_eos ());
1337
1338     if (buf)
1339       gst_buffer_unref (buf);
1340
1341     return GST_FLOW_OK;
1342   }
1343
1344   prog = best->prog;
1345   if (prog == NULL)
1346     goto no_program;
1347
1348   g_assert (buf != NULL);
1349
1350   if (best->prepare_func) {
1351     GstBuffer *tmp;
1352
1353     tmp = best->prepare_func (buf, best, mux);
1354     g_assert (tmp);
1355     gst_buffer_unref (buf);
1356     buf = tmp;
1357   }
1358
1359   if (mux->force_key_unit_event != NULL && best->stream->is_video_stream) {
1360     GstEvent *event;
1361
1362     event = check_pending_key_unit_event (mux->force_key_unit_event,
1363         &best->collect.segment, GST_BUFFER_PTS (buf),
1364         GST_BUFFER_FLAGS (buf), mux->pending_key_unit_ts);
1365     if (event) {
1366       GstClockTime running_time;
1367       guint count;
1368       GList *cur;
1369
1370       mux->pending_key_unit_ts = GST_CLOCK_TIME_NONE;
1371       gst_event_replace (&mux->force_key_unit_event, NULL);
1372
1373       gst_video_event_parse_downstream_force_key_unit (event,
1374           NULL, NULL, &running_time, NULL, &count);
1375
1376       GST_INFO_OBJECT (mux, "pushing downstream force-key-unit event %d "
1377           "%" GST_TIME_FORMAT " count %d", gst_event_get_seqnum (event),
1378           GST_TIME_ARGS (running_time), count);
1379       gst_pad_push_event (mux->srcpad, event);
1380
1381       /* output PAT */
1382       mux->tsmux->last_pat_ts = -1;
1383
1384       /* output PMT for each program */
1385       for (cur = mux->tsmux->programs; cur; cur = cur->next) {
1386         TsMuxProgram *program = (TsMuxProgram *) cur->data;
1387
1388         program->last_pmt_ts = -1;
1389       }
1390       tsmux_program_set_pcr_stream (prog, NULL);
1391     }
1392   }
1393
1394   if (G_UNLIKELY (prog->pcr_stream == NULL)) {
1395     /* Take the first data stream for the PCR */
1396     GST_DEBUG_OBJECT (COLLECT_DATA_PAD (best),
1397         "Use stream (pid=%d) from pad as PCR for program (prog_id = %d)",
1398         best->pid, best->prog_id);
1399
1400     /* Set the chosen PCR stream */
1401     tsmux_program_set_pcr_stream (prog, best->stream);
1402   }
1403
1404   GST_DEBUG_OBJECT (COLLECT_DATA_PAD (best),
1405       "Chose stream for output (PID: 0x%04x)", best->pid);
1406
1407   if (GST_CLOCK_TIME_IS_VALID (GST_BUFFER_PTS (buf))) {
1408     pts = GSTTIME_TO_MPEGTIME (GST_BUFFER_PTS (buf));
1409     GST_DEBUG_OBJECT (mux, "Buffer has PTS  %" GST_TIME_FORMAT " pts %"
1410         G_GINT64_FORMAT, GST_TIME_ARGS (GST_BUFFER_PTS (buf)), pts);
1411   }
1412
1413   if (GST_CLOCK_STIME_IS_VALID (best->dts)) {
1414     dts = GSTTIME_TO_MPEGTIME (best->dts);
1415     GST_DEBUG_OBJECT (mux, "Buffer has DTS %" GST_STIME_FORMAT " dts %"
1416         G_GINT64_FORMAT, GST_STIME_ARGS (best->dts), dts);
1417   }
1418
1419   /* should not have a DTS without PTS */
1420   if (!GST_CLOCK_STIME_IS_VALID (pts) && GST_CLOCK_STIME_IS_VALID (dts)) {
1421     GST_DEBUG_OBJECT (mux, "using DTS for unknown PTS");
1422     pts = dts;
1423   }
1424
1425   if (best->stream->is_video_stream) {
1426     delta = GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT);
1427     header = GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_HEADER);
1428 #if 0
1429     GST_OBJECT_LOCK (mux);
1430     if (mux->element_index && !delta && best->element_index_writer_id != -1) {
1431       gst_index_add_association (mux->element_index,
1432           best->element_index_writer_id,
1433           GST_ASSOCIATION_FLAG_KEY_UNIT, spn_format, mux->spn_count,
1434           pts_format, pts, NULL);
1435     }
1436     GST_OBJECT_UNLOCK (mux);
1437 #endif
1438   }
1439
1440   if (best->stream->is_meta && gst_buffer_get_size (buf) > (G_MAXUINT16 - 3)) {
1441     GST_WARNING_OBJECT (mux, "KLV meta unit too big, splitting not supported");
1442
1443     gst_buffer_unref (buf);
1444     return GST_FLOW_OK;
1445   }
1446
1447   GST_DEBUG_OBJECT (mux, "delta: %d", delta);
1448
1449   stream_data = stream_data_new (buf);
1450   tsmux_stream_add_data (best->stream, stream_data->map_info.data,
1451       stream_data->map_info.size, stream_data, pts, dts, !delta);
1452
1453   /* outgoing ts follows ts of PCR program stream */
1454   if (prog->pcr_stream == best->stream) {
1455     /* prefer DTS if present for PCR as it should be monotone */
1456     mux->last_ts =
1457         GST_CLOCK_TIME_IS_VALID (GST_BUFFER_DTS (buf)) ?
1458         GST_BUFFER_DTS (buf) : GST_BUFFER_PTS (buf);
1459   }
1460
1461   mux->is_delta = delta;
1462   mux->is_header = header;
1463   while (tsmux_stream_bytes_in_buffer (best->stream) > 0) {
1464     if (!tsmux_write_stream_packet (mux->tsmux, best->stream)) {
1465       /* Failed writing data for some reason. Set appropriate error */
1466       GST_DEBUG_OBJECT (mux, "Failed to write data packet");
1467       GST_ELEMENT_ERROR (mux, STREAM, MUX,
1468           ("Failed writing output data to stream %04x", best->stream->id),
1469           (NULL));
1470       goto write_fail;
1471     }
1472   }
1473   /* flush packet cache */
1474   return mpegtsmux_push_packets (mux, FALSE);
1475
1476   /* ERRORS */
1477 write_fail:
1478   {
1479     return mux->last_flow_ret;
1480   }
1481 no_program:
1482   {
1483     if (buf)
1484       gst_buffer_unref (buf);
1485     GST_ELEMENT_ERROR (mux, STREAM, MUX,
1486         ("Stream on pad %" GST_PTR_FORMAT
1487             " is not associated with any program", COLLECT_DATA_PAD (best)),
1488         (NULL));
1489     return GST_FLOW_ERROR;
1490   }
1491 }
1492
1493 static GstPad *
1494 mpegtsmux_request_new_pad (GstElement * element, GstPadTemplate * templ,
1495     const gchar * name, const GstCaps * caps)
1496 {
1497   MpegTsMux *mux = GST_MPEG_TSMUX (element);
1498   gint pid = -1;
1499   gchar *pad_name = NULL;
1500   GstPad *pad = NULL;
1501   MpegTsPadData *pad_data = NULL;
1502
1503   if (name != NULL && sscanf (name, "sink_%d", &pid) == 1) {
1504     if (tsmux_find_stream (mux->tsmux, pid))
1505       goto stream_exists;
1506   } else {
1507     pid = tsmux_get_new_pid (mux->tsmux);
1508   }
1509
1510   pad_name = g_strdup_printf ("sink_%d", pid);
1511   pad = gst_pad_new_from_template (templ, pad_name);
1512   g_free (pad_name);
1513
1514   pad_data = (MpegTsPadData *)
1515       gst_collect_pads_add_pad (mux->collect, pad, sizeof (MpegTsPadData),
1516       (GstCollectDataDestroyNotify) (mpegtsmux_pad_reset), TRUE);
1517   if (pad_data == NULL)
1518     goto pad_failure;
1519
1520   mpegtsmux_pad_reset (pad_data);
1521   pad_data->pid = pid;
1522
1523   if (G_UNLIKELY (!gst_element_add_pad (element, pad)))
1524     goto could_not_add;
1525
1526   return pad;
1527
1528   /* ERRORS */
1529 stream_exists:
1530   {
1531     GST_ELEMENT_ERROR (element, STREAM, MUX, ("Duplicate PID requested"),
1532         (NULL));
1533     return NULL;
1534   }
1535 could_not_add:
1536   {
1537     GST_ELEMENT_ERROR (element, STREAM, FAILED,
1538         ("Internal data stream error."), ("Could not add pad to element"));
1539     gst_collect_pads_remove_pad (mux->collect, pad);
1540     gst_object_unref (pad);
1541     return NULL;
1542   }
1543 pad_failure:
1544   {
1545     GST_ELEMENT_ERROR (element, STREAM, FAILED,
1546         ("Internal data stream error."), ("Could not add pad to collectpads"));
1547     gst_object_unref (pad);
1548     return NULL;
1549   }
1550 }
1551
1552 static void
1553 mpegtsmux_release_pad (GstElement * element, GstPad * pad)
1554 {
1555   MpegTsMux *mux = GST_MPEG_TSMUX (element);
1556
1557   GST_DEBUG_OBJECT (mux, "Pad %" GST_PTR_FORMAT " being released", pad);
1558
1559   if (mux->collect) {
1560     gst_collect_pads_remove_pad (mux->collect, pad);
1561   }
1562
1563   /* chain up */
1564   gst_element_remove_pad (element, pad);
1565 }
1566
1567 static void
1568 new_packet_common_init (MpegTsMux * mux, GstBuffer * buf, guint8 * data,
1569     guint len)
1570 {
1571   /* Packets should be at least 188 bytes, but check anyway */
1572   g_assert (len >= 2 || !data);
1573
1574   if (!mux->streamheader_sent && data) {
1575     guint pid = ((data[1] & 0x1f) << 8) | data[2];
1576     /* if it's a PAT or a PMT */
1577     if (pid == 0x00 || (pid >= TSMUX_START_PMT_PID && pid < TSMUX_START_ES_PID)) {
1578       GstBuffer *hbuf;
1579
1580       if (!buf) {
1581         hbuf = gst_buffer_new_and_alloc (len);
1582         gst_buffer_fill (hbuf, 0, data, len);
1583       } else {
1584         hbuf = gst_buffer_copy (buf);
1585       }
1586       GST_LOG_OBJECT (mux,
1587           "Collecting packet with pid 0x%04x into streamheaders", pid);
1588
1589       g_queue_push_tail (&mux->streamheader, hbuf);
1590     } else if (!g_queue_is_empty (&mux->streamheader)) {
1591       mpegtsmux_set_header_on_caps (mux);
1592       mux->streamheader_sent = TRUE;
1593     }
1594   }
1595
1596   if (buf) {
1597     if (mux->is_header) {
1598       GST_LOG_OBJECT (mux, "marking as header buffer");
1599       GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
1600     }
1601     if (mux->is_delta) {
1602       GST_LOG_OBJECT (mux, "marking as delta unit");
1603       GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT);
1604     } else {
1605       GST_DEBUG_OBJECT (mux, "marking as non-delta unit");
1606       mux->is_delta = TRUE;
1607     }
1608   }
1609 }
1610
1611 static GstFlowReturn
1612 mpegtsmux_push_packets (MpegTsMux * mux, gboolean force)
1613 {
1614   GstBufferList *buffer_list;
1615   gint align = mux->alignment;
1616   gint av, packet_size;
1617
1618   if (mux->m2ts_mode) {
1619     packet_size = M2TS_PACKET_LENGTH;
1620     if (align < 0)
1621       align = 32;
1622   } else {
1623     packet_size = NORMAL_TS_PACKET_LENGTH;
1624     if (align < 0)
1625       align = 0;
1626   }
1627
1628   av = gst_adapter_available (mux->out_adapter);
1629   GST_LOG_OBJECT (mux, "align %d, av %d", align, av);
1630
1631   if (av == 0)
1632     return GST_FLOW_OK;
1633
1634   /* no alignment, just push all available data */
1635   if (align == 0) {
1636     buffer_list = gst_adapter_take_buffer_list (mux->out_adapter, av);
1637     return gst_pad_push_list (mux->srcpad, buffer_list);
1638   }
1639
1640   align *= packet_size;
1641
1642   if (!force && align > av)
1643     return GST_FLOW_OK;
1644
1645   buffer_list = gst_buffer_list_new_sized ((av / align) + 1);
1646
1647   GST_LOG_OBJECT (mux, "aligning to %d bytes", align);
1648   while (align <= av) {
1649     GstBuffer *buf;
1650     GstClockTime pts;
1651
1652     pts = gst_adapter_prev_pts (mux->out_adapter, NULL);
1653     buf = gst_adapter_take_buffer (mux->out_adapter, align);
1654
1655     GST_BUFFER_PTS (buf) = pts;
1656
1657     gst_buffer_list_add (buffer_list, buf);
1658     av -= align;
1659   }
1660
1661   if (av > 0 && force) {
1662     GstBuffer *buf;
1663     GstClockTime pts;
1664     guint8 *data;
1665     guint32 header;
1666     gint dummy;
1667     GstMapInfo map;
1668
1669     GST_LOG_OBJECT (mux, "handling %d leftover bytes", av);
1670
1671     pts = gst_adapter_prev_pts (mux->out_adapter, NULL);
1672     buf = gst_buffer_new_and_alloc (align);
1673
1674     GST_BUFFER_PTS (buf) = pts;
1675
1676     gst_buffer_map (buf, &map, GST_MAP_READ);
1677     data = map.data;
1678
1679     gst_adapter_copy (mux->out_adapter, data, 0, av);
1680     gst_adapter_clear (mux->out_adapter);
1681
1682     data += av;
1683     header = GST_READ_UINT32_BE (data - packet_size);
1684
1685     dummy = (map.size - av) / packet_size;
1686     GST_LOG_OBJECT (mux, "adding %d null packets", dummy);
1687
1688     for (; dummy > 0; dummy--) {
1689       gint offset;
1690
1691       if (packet_size > NORMAL_TS_PACKET_LENGTH) {
1692         GST_WRITE_UINT32_BE (data, header);
1693         /* simply increase header a bit and never mind too much */
1694         header++;
1695         offset = 4;
1696       } else {
1697         offset = 0;
1698       }
1699       GST_WRITE_UINT8 (data + offset, TSMUX_SYNC_BYTE);
1700       /* null packet PID */
1701       GST_WRITE_UINT16_BE (data + offset + 1, 0x1FFF);
1702       /* no adaptation field exists | continuity counter undefined */
1703       GST_WRITE_UINT8 (data + offset + 3, 0x10);
1704       /* payload */
1705       memset (data + offset + 4, 0, NORMAL_TS_PACKET_LENGTH - 4);
1706       data += packet_size;
1707     }
1708
1709     gst_buffer_unmap (buf, &map);
1710     gst_buffer_list_add (buffer_list, buf);
1711   }
1712
1713   return gst_pad_push_list (mux->srcpad, buffer_list);
1714 }
1715
1716 static GstFlowReturn
1717 mpegtsmux_collect_packet (MpegTsMux * mux, GstBuffer * buf)
1718 {
1719   GST_LOG_OBJECT (mux, "collecting packet size %" G_GSIZE_FORMAT,
1720       gst_buffer_get_size (buf));
1721   gst_adapter_push (mux->out_adapter, buf);
1722
1723   return GST_FLOW_OK;
1724 }
1725
1726 static gboolean
1727 new_packet_m2ts (MpegTsMux * mux, GstBuffer * buf, gint64 new_pcr)
1728 {
1729   GstBuffer *out_buf;
1730   int chunk_bytes;
1731   GstMapInfo map;
1732
1733   GST_LOG_OBJECT (mux, "Have buffer %p with new_pcr=%" G_GINT64_FORMAT,
1734       buf, new_pcr);
1735
1736   chunk_bytes = gst_adapter_available (mux->adapter);
1737
1738   if (G_LIKELY (buf)) {
1739     if (new_pcr < 0) {
1740       /* If there is no pcr in current ts packet then just add the packet
1741          to the adapter for later output when we see a PCR */
1742       GST_LOG_OBJECT (mux, "Accumulating non-PCR packet");
1743       gst_adapter_push (mux->adapter, buf);
1744       goto exit;
1745     }
1746
1747     /* no first interpolation point yet, then this is the one,
1748      * otherwise it is the second interpolation point */
1749     if (mux->previous_pcr < 0 && chunk_bytes) {
1750       mux->previous_pcr = new_pcr;
1751       mux->previous_offset = chunk_bytes;
1752       GST_LOG_OBJECT (mux, "Accumulating non-PCR packet");
1753       gst_adapter_push (mux->adapter, buf);
1754       goto exit;
1755     }
1756   } else {
1757     g_assert (new_pcr == -1);
1758   }
1759
1760   /* interpolate if needed, and 2 points available */
1761   if (chunk_bytes && (new_pcr != mux->previous_pcr)) {
1762     gint64 offset = 0;
1763
1764     GST_LOG_OBJECT (mux, "Processing pending packets; "
1765         "previous pcr %" G_GINT64_FORMAT ", previous offset %d, "
1766         "current pcr %" G_GINT64_FORMAT ", current offset %d",
1767         mux->previous_pcr, (gint) mux->previous_offset,
1768         new_pcr, (gint) chunk_bytes);
1769
1770     g_assert (chunk_bytes > mux->previous_offset);
1771     /* if draining, use previous rate */
1772     if (G_LIKELY (new_pcr > 0)) {
1773       mux->pcr_rate_num = new_pcr - mux->previous_pcr;
1774       mux->pcr_rate_den = chunk_bytes - mux->previous_offset;
1775     }
1776
1777     while (offset < chunk_bytes) {
1778       guint64 cur_pcr, ts;
1779
1780       /* Loop, pulling packets of the adapter, updating their 4 byte
1781        * timestamp header and pushing */
1782
1783       /* interpolate PCR */
1784       if (G_LIKELY (offset >= mux->previous_offset))
1785         cur_pcr = mux->previous_pcr +
1786             gst_util_uint64_scale (offset - mux->previous_offset,
1787             mux->pcr_rate_num, mux->pcr_rate_den);
1788       else
1789         cur_pcr = mux->previous_pcr -
1790             gst_util_uint64_scale (mux->previous_offset - offset,
1791             mux->pcr_rate_num, mux->pcr_rate_den);
1792
1793       /* FIXME: what about DTS here? */
1794       ts = gst_adapter_prev_pts (mux->adapter, NULL);
1795       out_buf = gst_adapter_take_buffer (mux->adapter, M2TS_PACKET_LENGTH);
1796       g_assert (out_buf);
1797       offset += M2TS_PACKET_LENGTH;
1798
1799       GST_BUFFER_PTS (out_buf) = ts;
1800
1801       gst_buffer_map (out_buf, &map, GST_MAP_WRITE);
1802
1803       /* The header is the bottom 30 bits of the PCR, apparently not
1804        * encoded into base + ext as in the packets themselves */
1805       GST_WRITE_UINT32_BE (map.data, cur_pcr & 0x3FFFFFFF);
1806       gst_buffer_unmap (out_buf, &map);
1807
1808       GST_LOG_OBJECT (mux, "Outputting a packet of length %d PCR %"
1809           G_GUINT64_FORMAT, M2TS_PACKET_LENGTH, cur_pcr);
1810       mpegtsmux_collect_packet (mux, out_buf);
1811     }
1812   }
1813
1814   if (G_UNLIKELY (!buf))
1815     goto exit;
1816
1817   gst_buffer_map (buf, &map, GST_MAP_WRITE);
1818
1819   /* Finally, output the passed in packet */
1820   /* Only write the bottom 30 bits of the PCR */
1821   GST_WRITE_UINT32_BE (map.data, new_pcr & 0x3FFFFFFF);
1822
1823   gst_buffer_unmap (buf, &map);
1824
1825   GST_LOG_OBJECT (mux, "Outputting a packet of length %d PCR %"
1826       G_GUINT64_FORMAT, M2TS_PACKET_LENGTH, new_pcr);
1827   mpegtsmux_collect_packet (mux, buf);
1828
1829   if (new_pcr != mux->previous_pcr) {
1830     mux->previous_pcr = new_pcr;
1831     mux->previous_offset = -M2TS_PACKET_LENGTH;
1832   }
1833
1834 exit:
1835   return TRUE;
1836 }
1837
1838 /* Called when the TsMux has prepared a packet for output. Return FALSE
1839  * on error */
1840 static gboolean
1841 new_packet_cb (GstBuffer * buf, void *user_data, gint64 new_pcr)
1842 {
1843   MpegTsMux *mux = (MpegTsMux *) user_data;
1844   gint offset = 0;
1845   GstMapInfo map;
1846
1847 #if 0
1848   GST_LOG_OBJECT (mux, "handling packet %d", mux->spn_count);
1849   mux->spn_count++;
1850 #endif
1851
1852   if (mux->m2ts_mode) {
1853     offset = 4;
1854     gst_buffer_set_size (buf, NORMAL_TS_PACKET_LENGTH + offset);
1855   }
1856
1857   gst_buffer_map (buf, &map, GST_MAP_READWRITE);
1858
1859   if (offset) {
1860     /* there should be a better way to do this */
1861     memmove (map.data + offset, map.data, map.size - offset);
1862   }
1863
1864   GST_BUFFER_PTS (buf) = mux->last_ts;
1865   /* do common init (flags and streamheaders) */
1866   new_packet_common_init (mux, buf, map.data + offset, map.size);
1867
1868   gst_buffer_unmap (buf, &map);
1869
1870   /* all is meant for downstream, including any prefix */
1871   if (offset)
1872     return new_packet_m2ts (mux, buf, new_pcr);
1873   else
1874     mpegtsmux_collect_packet (mux, buf);
1875
1876   return TRUE;
1877 }
1878
1879 /* called when TsMux needs new packet to write into */
1880 static void
1881 alloc_packet_cb (GstBuffer ** _buf, void *user_data)
1882 {
1883   MpegTsMux *mux = (MpegTsMux *) user_data;
1884   GstBuffer *buf;
1885   gint offset = 0;
1886
1887   if (mux->m2ts_mode == TRUE)
1888     offset = 4;
1889
1890   buf = gst_buffer_new_and_alloc (NORMAL_TS_PACKET_LENGTH + offset);
1891   gst_buffer_set_size (buf, NORMAL_TS_PACKET_LENGTH);
1892
1893   *_buf = buf;
1894 }
1895
1896 static void
1897 mpegtsmux_set_header_on_caps (MpegTsMux * mux)
1898 {
1899   GstBuffer *buf;
1900   GstStructure *structure;
1901   GValue array = { 0 };
1902   GValue value = { 0 };
1903   GstCaps *caps;
1904
1905   caps = gst_caps_make_writable (gst_pad_get_current_caps (mux->srcpad));
1906   structure = gst_caps_get_structure (caps, 0);
1907
1908   g_value_init (&array, GST_TYPE_ARRAY);
1909
1910   GST_LOG_OBJECT (mux, "setting %u packets into streamheader",
1911       g_queue_get_length (&mux->streamheader));
1912
1913   while ((buf = g_queue_pop_head (&mux->streamheader))) {
1914     g_value_init (&value, GST_TYPE_BUFFER);
1915     gst_value_take_buffer (&value, buf);
1916     gst_value_array_append_value (&array, &value);
1917     g_value_unset (&value);
1918   }
1919
1920   gst_structure_set_value (structure, "streamheader", &array);
1921   gst_pad_set_caps (mux->srcpad, caps);
1922   g_value_unset (&array);
1923   gst_caps_unref (caps);
1924 }
1925
1926 static void
1927 mpegtsmux_prepare_srcpad (MpegTsMux * mux)
1928 {
1929   GstSegment seg;
1930   /* we are not going to seek */
1931   GstEvent *new_seg;
1932   gchar s_id[32];
1933   GstCaps *caps = gst_caps_new_simple ("video/mpegts",
1934       "systemstream", G_TYPE_BOOLEAN, TRUE,
1935       "packetsize", G_TYPE_INT,
1936       (mux->m2ts_mode ? M2TS_PACKET_LENGTH : NORMAL_TS_PACKET_LENGTH),
1937       NULL);
1938
1939   /* stream-start (FIXME: create id based on input ids) */
1940   g_snprintf (s_id, sizeof (s_id), "mpegtsmux-%08x", g_random_int ());
1941   gst_pad_push_event (mux->srcpad, gst_event_new_stream_start (s_id));
1942
1943   gst_segment_init (&seg, GST_FORMAT_TIME);
1944   new_seg = gst_event_new_segment (&seg);
1945
1946   /* Set caps on src pad from our template and push new segment */
1947   gst_pad_set_caps (mux->srcpad, caps);
1948   gst_caps_unref (caps);
1949
1950   if (!gst_pad_push_event (mux->srcpad, new_seg)) {
1951     GST_WARNING_OBJECT (mux, "New segment event was not handled downstream");
1952   }
1953 }
1954
1955 static GstStateChangeReturn
1956 mpegtsmux_change_state (GstElement * element, GstStateChange transition)
1957 {
1958   MpegTsMux *mux = GST_MPEG_TSMUX (element);
1959   GstStateChangeReturn ret;
1960
1961   switch (transition) {
1962     case GST_STATE_CHANGE_NULL_TO_READY:
1963       break;
1964     case GST_STATE_CHANGE_READY_TO_PAUSED:
1965       gst_collect_pads_start (mux->collect);
1966       break;
1967     case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
1968       break;
1969     case GST_STATE_CHANGE_PAUSED_TO_READY:
1970       gst_collect_pads_stop (mux->collect);
1971       break;
1972     case GST_STATE_CHANGE_READY_TO_NULL:
1973       break;
1974     default:
1975       break;
1976   }
1977
1978   ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
1979
1980   switch (transition) {
1981     case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
1982       break;
1983     case GST_STATE_CHANGE_PAUSED_TO_READY:
1984       mpegtsmux_reset (mux, TRUE);
1985       break;
1986     case GST_STATE_CHANGE_READY_TO_NULL:
1987       break;
1988     default:
1989       break;
1990   }
1991
1992   return ret;
1993 }
1994
1995 static gboolean
1996 mpegtsmux_send_event (GstElement * element, GstEvent * event)
1997 {
1998   GstMpegtsSection *section;
1999   MpegTsMux *mux = GST_MPEG_TSMUX (element);
2000
2001   section = gst_event_parse_mpegts_section (event);
2002   gst_event_unref (event);
2003
2004   if (section) {
2005     GST_DEBUG ("Received event with mpegts section");
2006
2007     /* TODO: Check that the section type is supported */
2008     tsmux_add_mpegts_si_section (mux->tsmux, section);
2009
2010     return TRUE;
2011   }
2012
2013   return FALSE;
2014 }
2015
2016 static gboolean
2017 plugin_init (GstPlugin * plugin)
2018 {
2019   gst_mpegts_initialize ();
2020   if (!gst_element_register (plugin, "mpegtsmux", GST_RANK_PRIMARY,
2021           mpegtsmux_get_type ()))
2022     return FALSE;
2023
2024   GST_DEBUG_CATEGORY_INIT (mpegtsmux_debug, "mpegtsmux", 0,
2025       "MPEG Transport Stream muxer");
2026
2027   return TRUE;
2028 }
2029
2030 GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, GST_VERSION_MINOR,
2031     mpegtsmux, "MPEG-TS muxer",
2032     plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN);