143145cbce8db4899709a68af860afeb78c2824c
[platform/upstream/gstreamer.git] / subprojects / gst-plugins-bad / gst / mpegtsmux / tsmux / tsmux.c
1 /*
2  * Copyright 2006 BBC and Fluendo S.A.
3  *
4  * This library is licensed under 3 different licenses and you
5  * can choose to use it under the terms of any one of them. The
6  * three licenses are the MPL 1.1, the LGPL, and the MIT license.
7  *
8  * MPL:
9  *
10  * The contents of this file are subject to the Mozilla Public License
11  * Version 1.1 (the "License"); you may not use this file except in
12  * compliance with the License. You may obtain a copy of the License at
13  * http://www.mozilla.org/MPL/.
14  *
15  * Software distributed under the License is distributed on an "AS IS"
16  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
17  * License for the specific language governing rights and limitations
18  * under the License.
19  *
20  * LGPL:
21  *
22  * This library is free software; you can redistribute it and/or
23  * modify it under the terms of the GNU Library General Public
24  * License as published by the Free Software Foundation; either
25  * version 2 of the License, or (at your option) any later version.
26  *
27  * This library is distributed in the hope that it will be useful,
28  * but WITHOUT ANY WARRANTY; without even the implied warranty of
29  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
30  * Library General Public License for more details.
31  *
32  * You should have received a copy of the GNU Library General Public
33  * License along with this library; if not, write to the
34  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
35  * Boston, MA 02110-1301, USA.
36  *
37  * MIT:
38  *
39  * Unless otherwise indicated, Source Code is licensed under MIT license.
40  * See further explanation attached in License Statement (distributed in the file
41  * LICENSE).
42  *
43  * Permission is hereby granted, free of charge, to any person obtaining a copy of
44  * this software and associated documentation files (the "Software"), to deal in
45  * the Software without restriction, including without limitation the rights to
46  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
47  * of the Software, and to permit persons to whom the Software is furnished to do
48  * so, subject to the following conditions:
49  *
50  * The above copyright notice and this permission notice shall be included in all
51  * copies or substantial portions of the Software.
52  *
53  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
54  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
55  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
56  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
57  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
58  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
59  * SOFTWARE.
60  *
61  * SPDX-License-Identifier: MPL-1.1 OR MIT OR LGPL-2.0-or-later
62  */
63
64 #ifdef HAVE_CONFIG_H
65 #include "config.h"
66 #endif
67
68 #include <string.h>
69
70 #include <gst/mpegts/mpegts.h>
71
72 #include "tsmux.h"
73 #include "tsmuxstream.h"
74
75 #define GST_CAT_DEFAULT gst_base_ts_mux_debug
76
77 /* Maximum total data length for a PAT section is 1024 bytes, minus an
78  * 8 byte header, then the length of each program entry is 32 bits,
79  * then finally a 32 bit CRC. Thus the maximum number of programs in this mux
80  * is (1024 - 8 - 4) / 4 = 253 because it only supports single section PATs */
81 #define TSMUX_MAX_PROGRAMS 253
82
83 #define TSMUX_SECTION_HDR_SIZE 8
84
85 #define TSMUX_DEFAULT_NETWORK_ID 0x0001
86 #define TSMUX_DEFAULT_TS_ID 0x0001
87
88 /* The last byte of the PCR in the header defines the byte position
89  * at which PCR should be calculated */
90 #define PCR_BYTE_OFFSET 11
91
92 /* HACK: We use a fixed buffering offset for the PCR at the moment -
93  * this is the amount 'in advance' of the stream that the PCR sits.
94  * 1/8 second atm */
95 #define TSMUX_PCR_OFFSET (TSMUX_CLOCK_FREQ / 8)
96
97 /* Base for all written PCR and DTS/PTS,
98  * so we have some slack to go backwards */
99 #define CLOCK_BASE (TSMUX_CLOCK_FREQ * 10 * 360)
100
101 static gboolean tsmux_write_pat (TsMux * mux);
102 static gboolean tsmux_write_pmt (TsMux * mux, TsMuxProgram * program);
103 static gboolean tsmux_write_scte_null (TsMux * mux, TsMuxProgram * program);
104 static gint64 get_next_pcr (TsMux * mux, gint64 cur_ts);
105 static gint64 get_current_pcr (TsMux * mux, gint64 cur_ts);
106 static gint64 write_new_pcr (TsMux * mux, TsMuxStream * stream, gint64 cur_pcr,
107     gint64 next_pcr);
108 static gboolean tsmux_write_ts_header (TsMux * mux, guint8 * buf,
109     TsMuxPacketInfo * pi, guint stream_avail, guint * payload_len_out,
110     guint * payload_offset_out);
111
112 static void
113 tsmux_section_free (TsMuxSection * section)
114 {
115   gst_mpegts_section_unref (section->section);
116   g_slice_free (TsMuxSection, section);
117 }
118
119 static TsMuxStream *
120 tsmux_new_stream_default (guint16 pid, guint stream_type, gpointer user_data)
121 {
122   return tsmux_stream_new (pid, stream_type);
123 }
124
125 /**
126  * tsmux_new:
127  *
128  * Create a new muxer session.
129  *
130  * Returns: A new #TsMux object.
131  */
132 TsMux *
133 tsmux_new (void)
134 {
135   TsMux *mux;
136
137   mux = g_slice_new0 (TsMux);
138
139   mux->transport_id = TSMUX_DEFAULT_TS_ID;
140
141   mux->next_pgm_no = TSMUX_START_PROGRAM_ID;
142   mux->next_pmt_pid = TSMUX_START_PMT_PID;
143   mux->next_stream_pid = TSMUX_START_ES_PID;
144
145   mux->pat_changed = TRUE;
146   mux->next_pat_pcr = -1;
147   mux->pat_interval = TSMUX_DEFAULT_PAT_INTERVAL;
148
149   mux->si_changed = TRUE;
150   mux->si_interval = TSMUX_DEFAULT_SI_INTERVAL;
151
152   mux->pcr_interval = TSMUX_DEFAULT_PCR_INTERVAL;
153
154   mux->next_si_pcr = -1;
155
156   mux->si_sections = g_hash_table_new_full (g_direct_hash, g_direct_equal,
157       NULL, (GDestroyNotify) tsmux_section_free);
158
159   mux->new_stream_func = tsmux_new_stream_default;
160   mux->new_stream_data = NULL;
161
162   mux->first_pcr_ts = G_MININT64;
163
164   return mux;
165 }
166
167 /**
168  * tsmux_set_write_func:
169  * @mux: a #TsMux
170  * @func: a user callback function
171  * @user_data: user data passed to @func
172  *
173  * Set the callback function and user data to be called when @mux has output to
174  * produce. @user_data will be passed as user data in @func.
175  */
176 void
177 tsmux_set_write_func (TsMux * mux, TsMuxWriteFunc func, void *user_data)
178 {
179   g_return_if_fail (mux != NULL);
180
181   mux->write_func = func;
182   mux->write_func_data = user_data;
183 }
184
185 /**
186  * tsmux_set_alloc_func:
187  * @mux: a #TsMux
188  * @func: a user callback function
189  * @user_data: user data passed to @func
190  *
191  * Set the callback function and user data to be called when @mux needs
192  * a new buffer to write a packet into.
193  * @user_data will be passed as user data in @func.
194  */
195 void
196 tsmux_set_alloc_func (TsMux * mux, TsMuxAllocFunc func, void *user_data)
197 {
198   g_return_if_fail (mux != NULL);
199
200   mux->alloc_func = func;
201   mux->alloc_func_data = user_data;
202 }
203
204 /**
205  * tsmux_set_new_stream_func:
206  * @mux: a #TsMux
207  * @func: a user callback function
208  * @user_data: user data passed to @func
209  *
210  * Set the callback function and user data to be called when @mux needs
211  * to create a new stream.
212  * @user_data will be passed as user data in @func.
213  */
214 void
215 tsmux_set_new_stream_func (TsMux * mux, TsMuxNewStreamFunc func,
216     void *user_data)
217 {
218   g_return_if_fail (mux != NULL);
219
220   mux->new_stream_func = func;
221   mux->new_stream_data = user_data;
222 }
223
224 /**
225  * tsmux_set_pat_interval:
226  * @mux: a #TsMux
227  * @freq: a new PAT interval
228  *
229  * Set the interval (in cycles of the 90kHz clock) for writing out the PAT table.
230  *
231  * Many transport stream clients might have problems if the PAT table is not
232  * inserted in the stream at regular intervals, especially when initially trying
233  * to figure out the contents of the stream.
234  */
235 void
236 tsmux_set_pat_interval (TsMux * mux, guint freq)
237 {
238   g_return_if_fail (mux != NULL);
239
240   mux->pat_interval = freq;
241 }
242
243 /**
244  * tsmux_set_pcr_interval:
245  * @mux: a #TsMux
246  * @freq: a new PCR interval
247  *
248  * Set the interval (in cycles of the 90kHz clock) for writing the PCR.
249  */
250 void
251 tsmux_set_pcr_interval (TsMux * mux, guint freq)
252 {
253   g_return_if_fail (mux != NULL);
254
255   mux->pcr_interval = freq;
256 }
257
258 /**
259  * tsmux_get_pat_interval:
260  * @mux: a #TsMux
261  *
262  * Get the configured PAT interval. See also tsmux_set_pat_interval().
263  *
264  * Returns: the configured PAT interval
265  */
266 guint
267 tsmux_get_pat_interval (TsMux * mux)
268 {
269   g_return_val_if_fail (mux != NULL, 0);
270
271   return mux->pat_interval;
272 }
273
274 /**
275  * tsmux_resend_pat:
276  * @mux: a #TsMux
277  *
278  * Resends the PAT before the next stream packet.
279  */
280 void
281 tsmux_resend_pat (TsMux * mux)
282 {
283   g_return_if_fail (mux != NULL);
284
285   mux->next_pat_pcr = -1;
286 }
287
288 /**
289  * tsmux_set_si_interval:
290  * @mux: a #TsMux
291  * @freq: a new SI table interval
292  *
293  * Set the interval (in cycles of the 90kHz clock) for writing out the SI tables.
294  *
295  */
296 void
297 tsmux_set_si_interval (TsMux * mux, guint freq)
298 {
299   g_return_if_fail (mux != NULL);
300
301   mux->si_interval = freq;
302 }
303
304 /**
305  * tsmux_get_si_interval:
306  * @mux: a #TsMux
307  *
308  * Get the configured SI table interval. See also tsmux_set_si_interval().
309  *
310  * Returns: the configured SI interval
311  */
312 guint
313 tsmux_get_si_interval (TsMux * mux)
314 {
315   g_return_val_if_fail (mux != NULL, 0);
316
317   return mux->si_interval;
318 }
319
320 /**
321  * tsmux_resend_si:
322  * @mux: a #TsMux
323  *
324  * Resends the SI tables before the next stream packet.
325  *
326  */
327 void
328 tsmux_resend_si (TsMux * mux)
329 {
330   g_return_if_fail (mux != NULL);
331
332   mux->next_si_pcr = -1;
333 }
334
335 /**
336  * tsmux_add_mpegts_si_section:
337  * @mux: a #TsMux
338  * @section: (transfer full): a #GstMpegtsSection to add
339  *
340  * Add a Service Information #GstMpegtsSection to the stream
341  *
342  * Returns: %TRUE on success, %FALSE otherwise
343  */
344 gboolean
345 tsmux_add_mpegts_si_section (TsMux * mux, GstMpegtsSection * section)
346 {
347   TsMuxSection *tsmux_section;
348
349   g_return_val_if_fail (mux != NULL, FALSE);
350   g_return_val_if_fail (section != NULL, FALSE);
351   g_return_val_if_fail (mux->si_sections != NULL, FALSE);
352
353   tsmux_section = g_slice_new0 (TsMuxSection);
354
355   GST_DEBUG ("Adding mpegts section with type %d to mux",
356       section->section_type);
357
358   tsmux_section->section = section;
359   tsmux_section->pi.pid = section->pid;
360
361   g_hash_table_insert (mux->si_sections,
362       GINT_TO_POINTER (section->section_type), tsmux_section);
363
364   mux->si_changed = TRUE;
365
366   return TRUE;
367 }
368
369
370 /**
371  * tsmux_free:
372  * @mux: a #TsMux
373  *
374  * Free all resources associated with @mux. After calling this function @mux can
375  * not be used anymore.
376  */
377 void
378 tsmux_free (TsMux * mux)
379 {
380   GList *cur;
381
382   g_return_if_fail (mux != NULL);
383
384   /* Free PAT section */
385   if (mux->pat.section)
386     gst_mpegts_section_unref (mux->pat.section);
387
388   /* Free all programs */
389   for (cur = mux->programs; cur; cur = cur->next) {
390     TsMuxProgram *program = (TsMuxProgram *) cur->data;
391
392     tsmux_program_free (program);
393   }
394   g_list_free (mux->programs);
395
396   /* Free all streams */
397   for (cur = mux->streams; cur; cur = cur->next) {
398     TsMuxStream *stream = (TsMuxStream *) cur->data;
399
400     tsmux_stream_free (stream);
401   }
402   g_list_free (mux->streams);
403
404   /* Free SI table sections */
405   g_hash_table_unref (mux->si_sections);
406
407   g_slice_free (TsMux, mux);
408 }
409
410 static gint
411 tsmux_program_compare (TsMuxProgram * program, gint * needle)
412 {
413   return (program->pgm_number - *needle);
414 }
415
416 /**
417  * tsmux_program_new:
418  * @mux: a #TsMux
419  *
420  * Create a new program in the missing session @mux.
421  *
422  * Returns: a new #TsMuxProgram or %NULL when the maximum number of programs has
423  * been reached.
424  */
425 TsMuxProgram *
426 tsmux_program_new (TsMux * mux, gint prog_id)
427 {
428   TsMuxProgram *program;
429
430   g_return_val_if_fail (mux != NULL, NULL);
431
432   /* Ensure we have room for another program */
433   if (mux->nb_programs == TSMUX_MAX_PROGRAMS)
434     return NULL;
435
436   program = g_slice_new0 (TsMuxProgram);
437
438   program->pmt_changed = TRUE;
439   program->pmt_interval = TSMUX_DEFAULT_PMT_INTERVAL;
440
441   program->next_pmt_pcr = -1;
442
443   if (prog_id == 0) {
444     program->pgm_number = mux->next_pgm_no++;
445     while (g_list_find_custom (mux->programs, &program->pgm_number,
446             (GCompareFunc) tsmux_program_compare) != NULL) {
447       program->pgm_number = mux->next_pgm_no++;
448     }
449   } else {
450     program->pgm_number = prog_id;
451     while (g_list_find_custom (mux->programs, &program->pgm_number,
452             (GCompareFunc) tsmux_program_compare) != NULL) {
453       program->pgm_number++;
454     }
455   }
456
457   program->pmt_pid = mux->next_pmt_pid++;
458   program->pcr_stream = NULL;
459
460   /* SCTE35 is disabled by default */
461   program->scte35_pid = 0;
462   program->scte35_null_interval = TSMUX_DEFAULT_SCTE_35_NULL_INTERVAL;
463   program->next_scte35_pcr = -1;
464
465   /* mux->streams owns the streams */
466   program->streams = g_ptr_array_new_full (1, NULL);
467
468   mux->programs = g_list_prepend (mux->programs, program);
469   mux->nb_programs++;
470   mux->pat_changed = TRUE;
471
472   return program;
473 }
474
475 gboolean
476 tsmux_program_delete (TsMux * mux, TsMuxProgram * program)
477 {
478   g_return_val_if_fail (mux != NULL, FALSE);
479
480   if (mux->nb_programs == 0)
481     return FALSE;
482
483   if (!program)
484     return FALSE;
485
486   mux->programs = g_list_remove (mux->programs, program);
487   mux->nb_programs--;
488   mux->pat_changed = TRUE;
489   tsmux_program_free ((TsMuxProgram *) program);
490
491   return TRUE;
492 }
493
494 /**
495  * tsmux_set_pmt_interval:
496  * @program: a #TsMuxProgram
497  * @freq: a new PMT interval
498  *
499  * Set the interval (in cycles of the 90kHz clock) for writing out the PMT table.
500  *
501  * Many transport stream clients might have problems if the PMT table is not
502  * inserted in the stream at regular intervals, especially when initially trying
503  * to figure out the contents of the stream.
504  */
505 void
506 tsmux_set_pmt_interval (TsMuxProgram * program, guint freq)
507 {
508   g_return_if_fail (program != NULL);
509
510   program->pmt_interval = freq;
511 }
512
513 /**
514  * tsmux_get_pmt_interval:
515  * @program: a #TsMuxProgram
516  *
517  * Get the configured PMT interval. See also tsmux_set_pmt_interval().
518  *
519  * Returns: the configured PMT interval
520  */
521 guint
522 tsmux_get_pmt_interval (TsMuxProgram * program)
523 {
524   g_return_val_if_fail (program != NULL, 0);
525
526   return program->pmt_interval;
527 }
528
529 /**
530  * tsmux_program_set_scte35_interval:
531  * @program: a #TsMuxProgram
532  * @freq: a new SCTE-35 NULL interval
533  *
534  * Set the interval (in cycles of the 90kHz clock) for sending out the SCTE-35
535  * NULL command. This is only effective is the SCTE-35 PID is not 0.
536  */
537 void
538 tsmux_program_set_scte35_interval (TsMuxProgram * program, guint interval)
539 {
540   g_return_if_fail (program != NULL);
541
542   program->scte35_null_interval = interval;
543 }
544
545 /**
546  * tsmux_resend_pmt:
547  * @program: a #TsMuxProgram
548  *
549  * Resends the PMT before the next stream packet.
550  */
551 void
552 tsmux_resend_pmt (TsMuxProgram * program)
553 {
554   g_return_if_fail (program != NULL);
555
556   program->next_pmt_pcr = -1;
557 }
558
559 /**
560  * tsmux_program_set_scte35_pid:
561  * @program: a #TsMuxProgram
562  * @pid: The pid to use, or 0 to deactivate usage.
563  *
564  * Set the @pid to use for sending SCTE-35 packets on the given
565  * @program.
566  *
567  * This needs to be called as early as possible if SCTE-35 sections
568  * are even going to be used with the given @program so that the PMT
569  * can be properly configured.
570  */
571 void
572 tsmux_program_set_scte35_pid (TsMuxProgram * program, guint16 pid)
573 {
574   TsMuxSection *section;
575   GstMpegtsSCTESIT *sit;
576   g_return_if_fail (program != NULL);
577
578   program->scte35_pid = pid;
579   /* Create/Update the section */
580   if (program->scte35_null_section) {
581     tsmux_section_free (program->scte35_null_section);
582     program->scte35_null_section = NULL;
583   }
584   if (pid != 0) {
585     program->scte35_null_section = section = g_slice_new0 (TsMuxSection);
586     section->pi.pid = pid;
587     sit = gst_mpegts_scte_null_new ();
588     section->section = gst_mpegts_section_from_scte_sit (sit, pid);
589   }
590 }
591
592 /**
593  * tsmux_program_get_scte35_pid:
594  * @program: a #TsMuxProgram
595  *
596  * Get the PID configured for sending SCTE-35 packets.
597  *
598  * Returns: the configured SCTE-35 PID, or 0 if not active.
599  */
600 guint16
601 tsmux_program_get_scte35_pid (TsMuxProgram * program)
602 {
603   g_return_val_if_fail (program != NULL, 0);
604
605   return program->scte35_pid;
606 }
607
608 /**
609  * tsmux_program_add_stream:
610  * @program: a #TsMuxProgram
611  * @stream: a #TsMuxStream
612  *
613  * Add @stream to @program.
614  */
615 void
616 tsmux_program_add_stream (TsMuxProgram * program, TsMuxStream * stream)
617 {
618   GPtrArray *streams;
619   guint i;
620   gint pmt_index, array_index = -1 /* append */ ;
621   guint16 pid;
622
623   g_return_if_fail (program != NULL);
624   g_return_if_fail (stream != NULL);
625
626   streams = program->streams;
627   pmt_index = stream->pmt_index;
628   pid = tsmux_stream_get_pid (stream);
629
630   if (pmt_index >= 0) {
631     /* Insert into streams with known indices */
632     for (i = 0; i < streams->len; i++) {
633       TsMuxStream *s = g_ptr_array_index (streams, i);
634
635       if (s->pmt_index < 0 || pmt_index < s->pmt_index) {
636         array_index = i;
637         GST_DEBUG ("PID 0x%04x: Using known-order index %d/%u",
638             pid, array_index, streams->len);
639         break;
640       }
641     }
642   } else {
643     /* Insert after streams with known indices, sorted by PID */
644     for (i = 0; i < streams->len; i++) {
645       TsMuxStream *s = g_ptr_array_index (streams, i);
646
647       if (s->pmt_index < 0 && pid < tsmux_stream_get_pid (s)) {
648         array_index = i;
649         GST_DEBUG ("PID 0x%04x: Using PID-order index %d/%u",
650             pid, array_index, streams->len);
651         break;
652       }
653     }
654   }
655
656   g_ptr_array_insert (streams, array_index, stream);
657   program->pmt_changed = TRUE;
658 }
659
660 /**
661  * tsmux_program_set_pcr_stream:
662  * @program: a #TsMuxProgram
663  * @stream: a #TsMuxStream
664  *
665  * Set @stream as the PCR stream for @program, overwriting the previously
666  * configured PCR stream. When @stream is NULL, program will have no PCR stream
667  * configured.
668  */
669 void
670 tsmux_program_set_pcr_stream (TsMuxProgram * program, TsMuxStream * stream)
671 {
672   g_return_if_fail (program != NULL);
673
674   if (program->pcr_stream == stream)
675     return;
676
677   if (program->pcr_stream != NULL)
678     tsmux_stream_pcr_unref (program->pcr_stream);
679   if (stream)
680     tsmux_stream_pcr_ref (stream);
681   program->pcr_stream = stream;
682
683   program->pmt_changed = TRUE;
684 }
685
686 /**
687  * tsmux_get_new_pid:
688  * @mux: a #TsMux
689  *
690  * Get a new free PID.
691  *
692  * Returns: a new free PID.
693  */
694 guint16
695 tsmux_get_new_pid (TsMux * mux)
696 {
697   g_return_val_if_fail (mux != NULL, -1);
698
699   /* make sure this PID is free
700    * (and not taken by a specific earlier request) */
701   do {
702     mux->next_stream_pid++;
703   } while (tsmux_find_stream (mux, mux->next_stream_pid));
704
705   return mux->next_stream_pid;
706 }
707
708 /**
709  * tsmux_create_stream:
710  * @mux: a #TsMux
711  * @stream_type: the stream type
712  * @pid: the PID of the new stream.
713  *
714  * Create a new stream of @stream_type in the muxer session @mux.
715  *
716  * When @pid is set to #TSMUX_PID_AUTO, a new free PID will automatically
717  * be allocated for the new stream.
718  *
719  * Returns: a new #TsMuxStream.
720  */
721 TsMuxStream *
722 tsmux_create_stream (TsMux * mux, guint stream_type, guint16 pid,
723     gchar * language)
724 {
725   TsMuxStream *stream;
726   guint16 new_pid;
727
728   g_return_val_if_fail (mux != NULL, NULL);
729   g_return_val_if_fail (mux->new_stream_func != NULL, NULL);
730
731   if (pid == TSMUX_PID_AUTO) {
732     new_pid = tsmux_get_new_pid (mux);
733   } else {
734     new_pid = pid & 0x1FFF;
735   }
736
737   /* Ensure we're not creating a PID collision */
738   if (tsmux_find_stream (mux, new_pid))
739     return NULL;
740
741   stream = mux->new_stream_func (new_pid, stream_type, mux->new_stream_data);
742
743   mux->streams = g_list_prepend (mux->streams, stream);
744   mux->nb_streams++;
745
746   if (language) {
747     strncpy (stream->language, language, 4);
748     stream->language[3] = 0;
749   } else {
750     stream->language[0] = 0;
751   }
752
753   return stream;
754 }
755
756 /**
757  * tsmux_find_stream:
758  * @mux: a #TsMux
759  * @pid: the PID to find.
760  *
761  * Find the stream associated with PID.
762  *
763  * Returns: a #TsMuxStream with @pid or NULL when the stream was not found.
764  */
765 TsMuxStream *
766 tsmux_find_stream (TsMux * mux, guint16 pid)
767 {
768   TsMuxStream *found = NULL;
769   GList *cur;
770
771   g_return_val_if_fail (mux != NULL, NULL);
772
773   for (cur = mux->streams; cur; cur = cur->next) {
774     TsMuxStream *stream = (TsMuxStream *) cur->data;
775
776     if (tsmux_stream_get_pid (stream) == pid) {
777       found = stream;
778       break;
779     }
780   }
781   return found;
782 }
783
784 static gboolean
785 tsmux_program_remove_stream (TsMuxProgram * program, TsMuxStream * stream)
786 {
787   GPtrArray *streams = program->streams;
788
789   if (!g_ptr_array_remove (streams, stream)) {
790     g_warn_if_reached ();
791     return FALSE;
792   }
793
794   return streams->len == 0;
795 }
796
797
798 gboolean
799 tsmux_remove_stream (TsMux * mux, guint16 pid, TsMuxProgram * program)
800 {
801   GList *cur;
802   gboolean ret = FALSE;
803
804   g_return_val_if_fail (mux != NULL, FALSE);
805
806   for (cur = mux->streams; cur; cur = cur->next) {
807     TsMuxStream *stream = (TsMuxStream *) cur->data;
808
809     if (tsmux_stream_get_pid (stream) == pid) {
810       ret = tsmux_program_remove_stream (program, stream);
811       mux->streams = g_list_remove (mux->streams, stream);
812       tsmux_stream_free (stream);
813       break;
814     }
815   }
816
817   if (ret)
818     tsmux_program_delete (mux, program);
819
820   return ret;
821 }
822
823 static gboolean
824 tsmux_get_buffer (TsMux * mux, GstBuffer ** buf)
825 {
826   g_return_val_if_fail (buf, FALSE);
827
828   if (G_UNLIKELY (!mux->alloc_func))
829     return FALSE;
830
831   mux->alloc_func (buf, mux->alloc_func_data);
832
833   if (!*buf)
834     return FALSE;
835
836   g_assert (gst_buffer_get_size (*buf) == TSMUX_PACKET_LENGTH);
837   return TRUE;
838 }
839
840 static gboolean
841 tsmux_packet_out (TsMux * mux, GstBuffer * buf, gint64 pcr)
842 {
843   g_return_val_if_fail (buf, FALSE);
844
845   if (G_UNLIKELY (mux->write_func == NULL)) {
846     gst_buffer_unref (buf);
847     return TRUE;
848   }
849
850   if (mux->bitrate) {
851     GST_BUFFER_PTS (buf) =
852         gst_util_uint64_scale (mux->n_bytes * 8, GST_SECOND, mux->bitrate);
853
854     /* Check and insert a PCR observation for each program if needed,
855      * but only for programs that have written their SI at least once,
856      * so the stream starts with PAT/PMT */
857     if (mux->first_pcr_ts != G_MININT64) {
858       GList *cur;
859
860       for (cur = mux->programs; cur; cur = cur->next) {
861         TsMuxProgram *program = (TsMuxProgram *) cur->data;
862         TsMuxStream *stream = program->pcr_stream;
863         gint64 cur_pcr, next_pcr, new_pcr;
864
865         if (!program->wrote_si)
866           continue;
867
868         cur_pcr = get_current_pcr (mux, 0);
869         next_pcr = get_next_pcr (mux, 0);
870         new_pcr = write_new_pcr (mux, stream, cur_pcr, next_pcr);
871
872         if (new_pcr != -1) {
873           GstBuffer *pcr_buf = NULL;
874           GstMapInfo map;
875
876           if (!tsmux_get_buffer (mux, &pcr_buf)) {
877             goto error;
878           }
879
880           gst_buffer_map (pcr_buf, &map, GST_MAP_WRITE);
881           tsmux_write_ts_header (mux, map.data, &stream->pi, 0, NULL, NULL);
882           gst_buffer_unmap (pcr_buf, &map);
883
884           stream->pi.flags &= TSMUX_PACKET_FLAG_PES_FULL_HEADER;
885           if (!tsmux_packet_out (mux, pcr_buf, new_pcr))
886             goto error;
887         }
888       }
889     }
890   }
891
892   mux->n_bytes += gst_buffer_get_size (buf);
893
894   return mux->write_func (buf, mux->write_func_data, pcr);
895
896 error:
897   gst_buffer_unref (buf);
898   return FALSE;
899 }
900
901 /*
902  * adaptation_field() {
903  *   adaptation_field_length                              8 uimsbf
904  *   if(adaptation_field_length >0) {
905  *     discontinuity_indicator                            1 bslbf
906  *     random_access_indicator                            1 bslbf
907  *     elementary_stream_priority_indicator               1 bslbf
908  *     PCR_flag                                           1 bslbf
909  *     OPCR_flag                                          1 bslbf
910  *     splicing_point_flag                                1 bslbf
911  *     transport_private_data_flag                        1 bslbf
912  *     adaptation_field_extension_flag                    1 bslbf
913  *     if(PCR_flag == '1') {
914  *       program_clock_reference_base                    33 uimsbf
915  *       reserved                                         6 bslbf
916  *       program_clock_reference_extension                9 uimsbf
917  *     }
918  *     if(OPCR_flag == '1') {
919  *       original_program_clock_reference_base           33 uimsbf
920  *       reserved                                         6 bslbf
921  *       original_program_clock_reference_extension       9 uimsbf
922  *     }
923  *     if (splicing_point_flag == '1') {
924  *       splice_countdown                                 8 tcimsbf
925  *     }
926  *     if(transport_private_data_flag == '1') {
927  *       transport_private_data_length                    8 uimsbf
928  *       for (i=0; i<transport_private_data_length;i++){
929  *         private_data_byte                              8 bslbf
930  *       }
931  *     }
932  *     if (adaptation_field_extension_flag == '1' ) {
933  *       adaptation_field_extension_length                8 uimsbf
934  *       ltw_flag                                         1 bslbf
935  *       piecewise_rate_flag                              1 bslbf
936  *       seamless_splice_flag                             1 bslbf
937  *       reserved                                         5 bslbf
938  *       if (ltw_flag == '1') {
939  *         ltw_valid_flag                                 1 bslbf
940  *         ltw_offset                                    15 uimsbf
941  *       }
942  *       if (piecewise_rate_flag == '1') {
943  *         reserved                                       2 bslbf
944  *         piecewise_rate                                22 uimsbf
945  *       }
946  *       if (seamless_splice_flag == '1'){
947  *         splice_type                                    4 bslbf
948  *         DTS_next_AU[32..30]                            3 bslbf
949  *         marker_bit                                     1 bslbf
950  *         DTS_next_AU[29..15]                           15 bslbf
951  *         marker_bit                                     1 bslbf
952  *         DTS_next_AU[14..0]                            15 bslbf
953  *         marker_bit                                     1 bslbf
954  *       }
955  *       for ( i=0;i<N;i++) {
956  *         reserved                                       8 bslbf
957  *       }
958  *     }
959  *     for (i=0;i<N;i++){
960  *       stuffing_byte                                    8 bslbf
961  *     }
962  *   }
963  * }
964  */
965 static gboolean
966 tsmux_write_adaptation_field (guint8 * buf,
967     TsMuxPacketInfo * pi, guint8 min_length, guint8 * written)
968 {
969   guint8 pos = 2;
970   guint8 flags = 0;
971
972   g_assert (min_length <= TSMUX_PAYLOAD_LENGTH);
973
974   /* Write out all the fields from the packet info only if the
975    * user set the flag to request the adaptation field - if the flag
976    * isn't set, we're just supposed to write stuffing bytes */
977   if (pi->flags & TSMUX_PACKET_FLAG_ADAPTATION) {
978     TS_DEBUG ("writing adaptation fields");
979     if (pi->flags & TSMUX_PACKET_FLAG_DISCONT)
980       flags |= 0x80;
981     if (pi->flags & TSMUX_PACKET_FLAG_RANDOM_ACCESS)
982       flags |= 0x40;
983     if (pi->flags & TSMUX_PACKET_FLAG_PRIORITY)
984       flags |= 0x20;
985     if (pi->flags & TSMUX_PACKET_FLAG_WRITE_PCR) {
986       guint64 pcr_base;
987       guint32 pcr_ext;
988
989       pcr_base = (pi->pcr / 300);
990       pcr_ext = (pi->pcr % 300);
991
992       flags |= 0x10;
993       TS_DEBUG ("Writing PCR %" G_GUINT64_FORMAT " + ext %u", pcr_base,
994           pcr_ext);
995       buf[pos++] = (pcr_base >> 25) & 0xff;
996       buf[pos++] = (pcr_base >> 17) & 0xff;
997       buf[pos++] = (pcr_base >> 9) & 0xff;
998       buf[pos++] = (pcr_base >> 1) & 0xff;
999       buf[pos++] = ((pcr_base << 7) & 0x80) | 0x7e | ((pcr_ext >> 8) & 0x01);   /* set 6 reserve bits to 1 */
1000       buf[pos++] = (pcr_ext) & 0xff;
1001     }
1002     if (pi->flags & TSMUX_PACKET_FLAG_WRITE_OPCR) {
1003       guint64 opcr_base;
1004       guint32 opcr_ext;
1005
1006       opcr_base = (pi->opcr / 300);
1007       opcr_ext = (pi->opcr % 300);
1008
1009       flags |= 0x08;
1010       TS_DEBUG ("Writing OPCR");
1011       buf[pos++] = (opcr_base >> 25) & 0xff;
1012       buf[pos++] = (opcr_base >> 17) & 0xff;
1013       buf[pos++] = (opcr_base >> 9) & 0xff;
1014       buf[pos++] = (opcr_base >> 1) & 0xff;
1015       buf[pos++] = ((opcr_base << 7) & 0x80) | 0x7e | ((opcr_ext >> 8) & 0x01); /* set 6 reserve bits to 1 */
1016       buf[pos++] = (opcr_ext) & 0xff;
1017     }
1018     if (pi->flags & TSMUX_PACKET_FLAG_WRITE_SPLICE) {
1019       flags |= 0x04;
1020       buf[pos++] = pi->splice_countdown;
1021     }
1022     if (pi->private_data_len > 0) {
1023       flags |= 0x02;
1024       /* Private data to write, ensure we have enough room */
1025       if ((1 + pi->private_data_len) > (TSMUX_PAYLOAD_LENGTH - pos))
1026         return FALSE;
1027       buf[pos++] = pi->private_data_len;
1028       memcpy (&(buf[pos]), pi->private_data, pi->private_data_len);
1029       pos += pi->private_data_len;
1030       TS_DEBUG ("%u bytes of private data", pi->private_data_len);
1031     }
1032     if (pi->flags & TSMUX_PACKET_FLAG_WRITE_ADAPT_EXT) {
1033       flags |= 0x01;
1034       TS_DEBUG ("FIXME: write Adaptation extension");
1035       /* Write an empty extension for now */
1036       buf[pos++] = 1;
1037       buf[pos++] = 0x1f;        /* lower 5 bits are reserved, and should be all 1 */
1038     }
1039   }
1040   /* Write the flags at the start */
1041   buf[1] = flags;
1042
1043   /* Stuffing bytes if needed */
1044   while (pos < min_length)
1045     buf[pos++] = 0xff;
1046
1047   /* Write the adaptation field length, which doesn't include its own byte */
1048   buf[0] = pos - 1;
1049
1050   if (written)
1051     *written = pos;
1052
1053   return TRUE;
1054 }
1055
1056 static gboolean
1057 tsmux_write_ts_header (TsMux * mux, guint8 * buf, TsMuxPacketInfo * pi,
1058     guint stream_avail, guint * payload_len_out, guint * payload_offset_out)
1059 {
1060   guint8 *tmp;
1061   guint8 adaptation_flag = 0;
1062   guint8 adapt_min_length = 0;
1063   guint8 adapt_len = 0;
1064   guint payload_len;
1065   gboolean write_adapt = FALSE;
1066
1067   /* Sync byte */
1068   buf[0] = TSMUX_SYNC_BYTE;
1069
1070   TS_DEBUG ("PID 0x%04x, counter = 0x%01x, %u bytes avail", pi->pid,
1071       mux->pid_packet_counts[pi->pid] & 0x0f, stream_avail);
1072
1073   /* 3 bits:
1074    *   transport_error_indicator
1075    *   payload_unit_start_indicator
1076    *   transport_priority: (00)
1077    * 13 bits: PID
1078    */
1079   tmp = buf + 1;
1080   if (pi->packet_start_unit_indicator) {
1081     tsmux_put16 (&tmp, 0x4000 | pi->pid);
1082   } else
1083     tsmux_put16 (&tmp, pi->pid);
1084
1085   /* 2 bits: scrambling_control (NOT SUPPORTED) (00)
1086    * 2 bits: adaptation field control (1x has_adaptation_field | x1 has_payload)
1087    * 4 bits: continuity counter (xxxx)
1088    */
1089
1090   if (pi->flags & TSMUX_PACKET_FLAG_ADAPTATION) {
1091     write_adapt = TRUE;
1092   }
1093
1094   if (stream_avail < TSMUX_PAYLOAD_LENGTH) {
1095     /* Need an adaptation field regardless for stuffing */
1096     adapt_min_length = TSMUX_PAYLOAD_LENGTH - stream_avail;
1097     write_adapt = TRUE;
1098   }
1099
1100   if (write_adapt) {
1101     gboolean res;
1102
1103     /* Flag the adaptation field presence */
1104     adaptation_flag |= 0x20;
1105     res = tsmux_write_adaptation_field (buf + TSMUX_HEADER_LENGTH,
1106         pi, adapt_min_length, &adapt_len);
1107     if (G_UNLIKELY (res == FALSE))
1108       return FALSE;
1109
1110     /* Should have written at least the number of bytes we requested */
1111     g_assert (adapt_len >= adapt_min_length);
1112   }
1113
1114   /* The amount of packet data we wrote is the remaining space after
1115    * the adaptation field */
1116   payload_len = TSMUX_PAYLOAD_LENGTH - adapt_len;
1117
1118   if (payload_len_out)
1119     *payload_len_out = payload_len;
1120   else
1121     g_assert (payload_len == 0);
1122
1123   if (payload_offset_out)
1124     *payload_offset_out = TSMUX_HEADER_LENGTH + adapt_len;
1125
1126   /* Now if we are going to write out some payload, flag that fact */
1127   if (payload_len > 0 && stream_avail > 0) {
1128     /* Flag the presence of a payload */
1129     adaptation_flag |= 0x10;
1130
1131     /* We must have enough data to fill the payload, or some calculation
1132      * went wrong */
1133     g_assert (payload_len <= stream_avail);
1134
1135     /* Packet with payload, increment the continuity counter */
1136     mux->pid_packet_counts[pi->pid]++;
1137   }
1138
1139   adaptation_flag |= mux->pid_packet_counts[pi->pid] & 0x0f;
1140
1141   /* Write the byte of transport_scrambling_control, adaptation_field_control
1142    * + continuity counter out */
1143   buf[3] = adaptation_flag;
1144
1145
1146   if (write_adapt) {
1147     TS_DEBUG ("Adaptation field of size >= %d + %d bytes payload",
1148         adapt_len, payload_len);
1149   } else {
1150     TS_DEBUG ("Payload of %d bytes only", payload_len);
1151   }
1152
1153   return TRUE;
1154 }
1155
1156 static gboolean
1157 tsmux_section_write_packet (TsMux * mux, TsMuxSection * section)
1158 {
1159   guint8 *data;
1160   gsize data_size;
1161   guint payload_written = 0;
1162   gboolean ret = FALSE;
1163
1164   g_return_val_if_fail (section != NULL, FALSE);
1165   g_return_val_if_fail (mux != NULL, FALSE);
1166
1167   data = gst_mpegts_section_packetize (section->section, &data_size);
1168   if (!data) {
1169     GST_WARNING ("Could not packetize section");
1170     return FALSE;
1171   }
1172
1173   /* Mark the start of new PES unit */
1174   section->pi.packet_start_unit_indicator = TRUE;
1175
1176   /* Mark payload data size */
1177   section->pi.stream_avail = data_size;
1178
1179   while (section->pi.stream_avail > 0) {
1180     GstBuffer *buf;
1181     GstMapInfo map;
1182     guint len, offset;
1183
1184     if (!tsmux_get_buffer (mux, &buf))
1185       goto done;
1186
1187     if (!gst_buffer_map (buf, &map, GST_MAP_WRITE)) {
1188       gst_buffer_unref (buf);
1189       goto done;
1190     }
1191
1192     if (section->pi.packet_start_unit_indicator) {
1193       /* We need room for a pointer byte */
1194       if (!tsmux_write_ts_header (mux, map.data, &section->pi,
1195               section->pi.stream_avail + 1, &len, &offset)) {
1196         gst_buffer_unmap (buf, &map);
1197         gst_buffer_unref (buf);
1198         goto done;
1199       }
1200
1201       /* Write the pointer byte */
1202       map.data[offset++] = 0x00;
1203       len--;
1204     } else if (!tsmux_write_ts_header (mux, map.data, &section->pi,
1205             section->pi.stream_avail, &len, &offset)) {
1206       gst_buffer_unmap (buf, &map);
1207       gst_buffer_unref (buf);
1208       goto done;
1209     }
1210
1211     GST_DEBUG ("Creating section packet for offset %u with length %u; %u bytes"
1212         " remaining", payload_written, len, section->pi.stream_avail - len);
1213
1214     memcpy (map.data + offset, data + payload_written, len);
1215     gst_buffer_unmap (buf, &map);
1216
1217     /* Push the packet without PCR */
1218     if (G_UNLIKELY (!tsmux_packet_out (mux, buf, -1)))
1219       goto done;
1220
1221     section->pi.stream_avail -= len;
1222     payload_written += len;
1223     section->pi.packet_start_unit_indicator = FALSE;
1224   }
1225
1226   ret = TRUE;
1227
1228 done:
1229   return ret;
1230 }
1231
1232 /**
1233  * tsmux_send_section:
1234  * @mux: a #TsMux
1235  * @section: (transfer full): a #GstMpegtsSection to add
1236  *
1237  * Send a @section immediately on the stream.
1238  *
1239  * Returns: %TRUE on success, %FALSE otherwise
1240  */
1241 gboolean
1242 tsmux_send_section (TsMux * mux, GstMpegtsSection * section)
1243 {
1244   gboolean ret;
1245   TsMuxSection tsmux_section;
1246
1247   g_return_val_if_fail (mux != NULL, FALSE);
1248   g_return_val_if_fail (section != NULL, FALSE);
1249
1250   memset (&tsmux_section, 0, sizeof (tsmux_section));
1251
1252   GST_DEBUG ("Sending mpegts section with type %d to mux",
1253       section->section_type);
1254
1255   tsmux_section.section = section;
1256   tsmux_section.pi.pid = section->pid;
1257
1258   ret = tsmux_section_write_packet (mux, &tsmux_section);
1259   gst_mpegts_section_unref (section);
1260
1261   return ret;
1262 }
1263
1264 static void
1265 tsmux_write_si_foreach (gpointer key, gpointer value, gpointer user_data)
1266 {
1267   GstMpegtsSectionType section_type = GPOINTER_TO_INT (key);
1268   TsMuxSection *section = value;
1269   TsMux *mux = user_data;
1270
1271   if (!tsmux_section_write_packet (mux, section))
1272     GST_WARNING ("Failed to send SI section (type %d)", section_type);
1273 }
1274
1275 static gboolean
1276 tsmux_write_si (TsMux * mux)
1277 {
1278   g_hash_table_foreach (mux->si_sections, tsmux_write_si_foreach, mux);
1279   mux->si_changed = FALSE;
1280   return TRUE;
1281 }
1282
1283 static void
1284 tsmux_write_null_ts_header (guint8 * buf)
1285 {
1286   *buf++ = TSMUX_SYNC_BYTE;
1287   *buf++ = 0x1f;
1288   *buf++ = 0xff;
1289   *buf++ = 0x10;
1290 }
1291
1292 static gint64
1293 ts_to_pcr (gint64 ts)
1294 {
1295   if (ts == G_MININT64) {
1296     return 0;
1297   }
1298
1299   return (ts - TSMUX_PCR_OFFSET) * (TSMUX_SYS_CLOCK_FREQ / TSMUX_CLOCK_FREQ);
1300 }
1301
1302 /* Calculate the PCR to write into the current packet */
1303 static gint64
1304 get_current_pcr (TsMux * mux, gint64 cur_ts)
1305 {
1306   if (!mux->bitrate)
1307     return ts_to_pcr (cur_ts);
1308
1309   if (mux->first_pcr_ts == G_MININT64) {
1310     g_assert (cur_ts != G_MININT64);
1311     mux->first_pcr_ts = cur_ts;
1312     GST_DEBUG ("First PCR offset is %" G_GUINT64_FORMAT, cur_ts);
1313   }
1314
1315   return ts_to_pcr (mux->first_pcr_ts) +
1316       gst_util_uint64_scale ((mux->n_bytes + PCR_BYTE_OFFSET) * 8,
1317       TSMUX_SYS_CLOCK_FREQ, mux->bitrate);
1318 }
1319
1320 /* Predict the PCR at the next packet if possible */
1321 static gint64
1322 get_next_pcr (TsMux * mux, gint64 cur_ts)
1323 {
1324   if (!mux->bitrate)
1325     return ts_to_pcr (cur_ts);
1326
1327   if (mux->first_pcr_ts == G_MININT64) {
1328     g_assert (cur_ts != G_MININT64);
1329     mux->first_pcr_ts = cur_ts;
1330     GST_DEBUG ("First PCR offset is %" G_GUINT64_FORMAT, cur_ts);
1331   }
1332
1333   return ts_to_pcr (mux->first_pcr_ts) +
1334       gst_util_uint64_scale ((mux->n_bytes + TSMUX_PACKET_LENGTH +
1335           PCR_BYTE_OFFSET) * 8, TSMUX_SYS_CLOCK_FREQ, mux->bitrate);
1336 }
1337
1338 static gint64
1339 write_new_pcr (TsMux * mux, TsMuxStream * stream, gint64 cur_pcr,
1340     gint64 next_pcr)
1341 {
1342   if (stream->next_pcr == -1 || next_pcr > stream->next_pcr) {
1343     stream->pi.flags |=
1344         TSMUX_PACKET_FLAG_ADAPTATION | TSMUX_PACKET_FLAG_WRITE_PCR;
1345     stream->pi.pcr = cur_pcr;
1346
1347     if (mux->bitrate && stream->next_pcr != -1 && cur_pcr >= stream->next_pcr) {
1348       GST_WARNING ("Writing PCR %" G_GUINT64_FORMAT " missed the target %"
1349           G_GUINT64_FORMAT " by %f ms", cur_pcr, stream->next_pcr,
1350           (double) (cur_pcr - stream->next_pcr) / 27000.0);
1351     }
1352     /* Next PCR deadline is now plus the scheduled interval */
1353     stream->next_pcr = cur_pcr + mux->pcr_interval * 300;
1354   } else {
1355     cur_pcr = -1;
1356   }
1357
1358   return cur_pcr;
1359 }
1360
1361 static gboolean
1362 rewrite_si (TsMux * mux, gint64 cur_ts)
1363 {
1364   gboolean write_pat;
1365   gboolean write_si;
1366   GList *cur;
1367   gint64 next_pcr;
1368
1369   next_pcr = get_next_pcr (mux, cur_ts);
1370
1371   /* check if we need to rewrite pat */
1372   if (mux->next_pat_pcr == -1 || mux->pat_changed)
1373     write_pat = TRUE;
1374   else if (next_pcr > mux->next_pat_pcr)
1375     write_pat = TRUE;
1376   else
1377     write_pat = FALSE;
1378
1379   if (write_pat) {
1380     if (mux->next_pat_pcr == -1)
1381       mux->next_pat_pcr = next_pcr + mux->pat_interval * 300;
1382     else
1383       mux->next_pat_pcr += mux->pat_interval * 300;
1384
1385     if (!tsmux_write_pat (mux))
1386       return FALSE;
1387
1388     next_pcr = get_next_pcr (mux, cur_ts);
1389   }
1390
1391   /* check if we need to rewrite sit */
1392   if (mux->next_si_pcr == -1 || mux->si_changed)
1393     write_si = TRUE;
1394   else if (next_pcr > mux->next_si_pcr)
1395     write_si = TRUE;
1396   else
1397     write_si = FALSE;
1398
1399   if (write_si) {
1400     if (mux->next_si_pcr == -1)
1401       mux->next_si_pcr = next_pcr + mux->si_interval * 300;
1402     else
1403       mux->next_si_pcr += mux->si_interval * 300;
1404
1405     if (!tsmux_write_si (mux))
1406       return FALSE;
1407
1408     next_pcr = get_current_pcr (mux, cur_ts);
1409   }
1410
1411   /* check if we need to rewrite any of the current pmts */
1412   for (cur = mux->programs; cur; cur = cur->next) {
1413     TsMuxProgram *program = (TsMuxProgram *) cur->data;
1414     gboolean write_pmt;
1415
1416     if (program->next_pmt_pcr == -1 || program->pmt_changed)
1417       write_pmt = TRUE;
1418     else if (next_pcr > program->next_pmt_pcr)
1419       write_pmt = TRUE;
1420     else
1421       write_pmt = FALSE;
1422
1423     if (write_pmt) {
1424       if (program->next_pmt_pcr == -1)
1425         program->next_pmt_pcr = next_pcr + program->pmt_interval * 300;
1426       else
1427         program->next_pmt_pcr += program->pmt_interval * 300;
1428
1429       if (!tsmux_write_pmt (mux, program))
1430         return FALSE;
1431
1432       next_pcr = get_current_pcr (mux, cur_ts);
1433     }
1434
1435     if (program->scte35_pid != 0) {
1436       gboolean write_scte_null = FALSE;
1437       if (program->next_scte35_pcr == -1)
1438         write_scte_null = TRUE;
1439       else if (next_pcr > program->next_scte35_pcr)
1440         write_scte_null = TRUE;
1441
1442       if (write_scte_null) {
1443         GST_DEBUG ("next scte35 pcr %" G_GINT64_FORMAT,
1444             program->next_scte35_pcr);
1445         if (program->next_scte35_pcr == -1)
1446           program->next_scte35_pcr =
1447               next_pcr + program->scte35_null_interval * 300;
1448         else
1449           program->next_scte35_pcr += program->scte35_null_interval * 300;
1450         GST_DEBUG ("next scte35 NOW pcr %" G_GINT64_FORMAT,
1451             program->next_scte35_pcr);
1452
1453         if (!tsmux_write_scte_null (mux, program))
1454           return FALSE;
1455
1456         next_pcr = get_current_pcr (mux, cur_ts);
1457       }
1458     }
1459
1460     program->wrote_si = TRUE;
1461   }
1462
1463   return TRUE;
1464 }
1465
1466 static gboolean
1467 pad_stream (TsMux * mux, TsMuxStream * stream, gint64 cur_ts)
1468 {
1469   guint64 bitrate;
1470   GstBuffer *buf = NULL;
1471   GstMapInfo map;
1472   gboolean ret = TRUE;
1473   GstClockTimeDiff diff;
1474   guint64 start_n_bytes;
1475
1476   if (!mux->bitrate)
1477     goto done;
1478
1479   if (!GST_CLOCK_STIME_IS_VALID (cur_ts))
1480     goto done;
1481
1482   if (!GST_CLOCK_STIME_IS_VALID (stream->first_ts))
1483     stream->first_ts = cur_ts;
1484
1485   diff = GST_CLOCK_DIFF (stream->first_ts, cur_ts);
1486   if (diff == 0)
1487     goto done;
1488
1489   ret = FALSE;
1490   start_n_bytes = mux->n_bytes;
1491   do {
1492     GST_LOG ("Transport stream bitrate: %" G_GUINT64_FORMAT " over %"
1493         G_GUINT64_FORMAT " bytes, duration %" GST_TIME_FORMAT,
1494         gst_util_uint64_scale (mux->n_bytes * 8, TSMUX_CLOCK_FREQ, diff),
1495         mux->n_bytes, GST_TIME_ARGS (diff * GST_SECOND / TSMUX_CLOCK_FREQ));
1496
1497     /* calculate what the overall bitrate will be if we add 1 more packet */
1498     bitrate =
1499         gst_util_uint64_scale ((mux->n_bytes + TSMUX_PACKET_LENGTH) * 8,
1500         TSMUX_CLOCK_FREQ, diff);
1501
1502     if (bitrate <= mux->bitrate) {
1503       gint64 new_pcr;
1504
1505       if (!tsmux_get_buffer (mux, &buf))
1506         goto done;
1507
1508       if (!gst_buffer_map (buf, &map, GST_MAP_WRITE)) {
1509         gst_buffer_unref (buf);
1510         goto done;
1511       }
1512
1513       new_pcr = write_new_pcr (mux, stream, get_current_pcr (mux, cur_ts),
1514           get_next_pcr (mux, cur_ts));
1515       if (new_pcr != -1) {
1516         GST_LOG ("Writing PCR-only packet on PID 0x%04x", stream->pi.pid);
1517         tsmux_write_ts_header (mux, map.data, &stream->pi, 0, NULL, NULL);
1518       } else {
1519         GST_LOG ("Writing null stuffing packet");
1520         if (!rewrite_si (mux, cur_ts)) {
1521           gst_buffer_unmap (buf, &map);
1522           gst_buffer_unref (buf);
1523           goto done;
1524         }
1525         tsmux_write_null_ts_header (map.data);
1526         memset (map.data + TSMUX_HEADER_LENGTH, 0xFF, TSMUX_PAYLOAD_LENGTH);
1527       }
1528
1529       gst_buffer_unmap (buf, &map);
1530
1531       stream->pi.flags &= TSMUX_PACKET_FLAG_PES_FULL_HEADER;
1532       if (!tsmux_packet_out (mux, buf, new_pcr))
1533         goto done;
1534     }
1535   } while (bitrate < mux->bitrate);
1536
1537   if (mux->n_bytes != start_n_bytes) {
1538     GST_LOG ("Finished padding the mux");
1539   }
1540
1541   ret = TRUE;
1542
1543 done:
1544   return ret;
1545 }
1546
1547 /**
1548  * tsmux_write_stream_packet:
1549  * @mux: a #TsMux
1550  * @stream: a #TsMuxStream
1551  *
1552  * Write a packet of @stream.
1553  *
1554  * Returns: TRUE if the packet could be written.
1555  */
1556 gboolean
1557 tsmux_write_stream_packet (TsMux * mux, TsMuxStream * stream)
1558 {
1559   guint payload_len, payload_offs;
1560   TsMuxPacketInfo *pi = &stream->pi;
1561   gboolean res;
1562   gint64 new_pcr = -1;
1563   GstBuffer *buf = NULL;
1564   GstMapInfo map;
1565
1566   g_return_val_if_fail (mux != NULL, FALSE);
1567   g_return_val_if_fail (stream != NULL, FALSE);
1568
1569   if (tsmux_stream_is_pcr (stream)) {
1570     gint64 cur_ts = CLOCK_BASE;
1571     if (tsmux_stream_get_dts (stream) != G_MININT64)
1572       cur_ts += tsmux_stream_get_dts (stream);
1573     else
1574       cur_ts += tsmux_stream_get_pts (stream);
1575
1576     if (!rewrite_si (mux, cur_ts))
1577       goto fail;
1578
1579     if (!pad_stream (mux, stream, cur_ts))
1580       goto fail;
1581
1582     new_pcr =
1583         write_new_pcr (mux, stream, get_current_pcr (mux, cur_ts),
1584         get_next_pcr (mux, cur_ts));
1585   }
1586
1587   pi->packet_start_unit_indicator = tsmux_stream_at_pes_start (stream);
1588   if (pi->packet_start_unit_indicator) {
1589     tsmux_stream_initialize_pes_packet (stream);
1590     if (stream->dts != G_MININT64)
1591       stream->dts += CLOCK_BASE;
1592     if (stream->pts != G_MININT64)
1593       stream->pts += CLOCK_BASE;
1594   }
1595   pi->stream_avail = tsmux_stream_bytes_avail (stream);
1596
1597   /* obtain buffer */
1598   if (!tsmux_get_buffer (mux, &buf))
1599     return FALSE;
1600
1601   gst_buffer_map (buf, &map, GST_MAP_WRITE);
1602
1603   if (!tsmux_write_ts_header (mux, map.data, pi, pi->stream_avail, &payload_len,
1604           &payload_offs))
1605     goto fail;
1606
1607
1608   if (!tsmux_stream_get_data (stream, map.data + payload_offs, payload_len))
1609     goto fail;
1610
1611   gst_buffer_unmap (buf, &map);
1612
1613   GST_DEBUG ("Writing PES of size %d", (int) gst_buffer_get_size (buf));
1614   res = tsmux_packet_out (mux, buf, new_pcr);
1615
1616   /* Reset all dynamic flags */
1617   stream->pi.flags &= TSMUX_PACKET_FLAG_PES_FULL_HEADER;
1618
1619   return res;
1620
1621   /* ERRORS */
1622 fail:
1623   {
1624     if (buf) {
1625       gst_buffer_unmap (buf, &map);
1626       gst_buffer_unref (buf);
1627     }
1628     return FALSE;
1629   }
1630 }
1631
1632 /**
1633  * tsmux_program_free:
1634  * @program: a #TsMuxProgram
1635  *
1636  * Free the resources of @program. After this call @program can not be used
1637  * anymore.
1638  */
1639 void
1640 tsmux_program_free (TsMuxProgram * program)
1641 {
1642   g_return_if_fail (program != NULL);
1643
1644   /* Free PMT section */
1645   if (program->pmt.section)
1646     gst_mpegts_section_unref (program->pmt.section);
1647   if (program->scte35_null_section)
1648     tsmux_section_free (program->scte35_null_section);
1649
1650   g_ptr_array_free (program->streams, TRUE);
1651   g_slice_free (TsMuxProgram, program);
1652 }
1653
1654 /**
1655  * tsmux_program_set_pmt_pid:
1656  * @program: A #TsmuxProgram
1657  * @pmt_pid: PID to write PMT for this program
1658  */
1659 void
1660 tsmux_program_set_pmt_pid (TsMuxProgram * program, guint16 pmt_pid)
1661 {
1662   program->pmt_pid = pmt_pid;
1663 }
1664
1665 static gint
1666 compare_program_number (gconstpointer a, gconstpointer b)
1667 {
1668   const GstMpegtsPatProgram *pgm1 = *(const GstMpegtsPatProgram * const *) a;
1669   const GstMpegtsPatProgram *pgm2 = *(const GstMpegtsPatProgram * const *) b;
1670   gint num1 = pgm1->program_number, num2 = pgm2->program_number;
1671
1672   return num1 - num2;
1673 }
1674
1675 static gboolean
1676 tsmux_write_pat (TsMux * mux)
1677 {
1678
1679   if (mux->pat_changed) {
1680     /* program_association_section ()
1681      * for (i = 0; i < N; i++) {
1682      *    program_number                         16   uimsbf
1683      *    reserved                                3   bslbf
1684      *    network_PID_or_program_map_PID         13   uimbsf
1685      * }
1686      * CRC_32                                    32   rbchof
1687      */
1688     GList *cur;
1689     GPtrArray *pat;
1690
1691     pat = gst_mpegts_pat_new ();
1692
1693     for (cur = mux->programs; cur; cur = cur->next) {
1694       GstMpegtsPatProgram *pat_pgm;
1695       TsMuxProgram *program = (TsMuxProgram *) cur->data;
1696
1697       pat_pgm = gst_mpegts_pat_program_new ();
1698       pat_pgm->program_number = program->pgm_number;
1699       pat_pgm->network_or_program_map_PID = program->pmt_pid;
1700
1701       g_ptr_array_add (pat, pat_pgm);
1702     }
1703
1704     g_ptr_array_sort (pat, compare_program_number);
1705
1706     if (mux->pat.section)
1707       gst_mpegts_section_unref (mux->pat.section);
1708
1709     mux->pat.section = gst_mpegts_section_from_pat (pat, mux->transport_id);
1710
1711     mux->pat.section->version_number = mux->pat_version++;
1712
1713     TS_DEBUG ("PAT has %d programs", mux->nb_programs);
1714     mux->pat_changed = FALSE;
1715   }
1716
1717   return tsmux_section_write_packet (mux, &mux->pat);
1718 }
1719
1720 static gboolean
1721 tsmux_write_pmt (TsMux * mux, TsMuxProgram * program)
1722 {
1723
1724   if (program->pmt_changed) {
1725     /* program_association_section ()
1726      * reserved                                   3   bslbf
1727      * PCR_PID                                   13   uimsbf
1728      * reserved                                   4   bslbf
1729      * program_info_length                       12   uimsbf
1730      * for (i = 0; i < N; i++)
1731      *   descriptor ()
1732      *
1733      * for (i = 0; i < N1; i++) {
1734      *    stream_type                             8   uimsbf
1735      *    reserved                                3   bslbf
1736      *    elementary_PID                         13   uimbsf
1737      *    reserved                                4   bslbf
1738      *    ES_info_length                         12   uimbsf
1739      *    for (i = 0; i < N1; i++) {
1740      *      descriptor ();
1741      *    }
1742      * }
1743      */
1744     GstMpegtsDescriptor *descriptor;
1745     GstMpegtsPMT *pmt;
1746 #if 0
1747     /* See note about bluray descriptors below */
1748     guint8 desc[] = { 0x0F, 0xFF, 0xFC, 0xFC };
1749 #endif
1750     guint i;
1751
1752     pmt = gst_mpegts_pmt_new ();
1753
1754     if (program->pcr_stream == NULL)
1755       pmt->pcr_pid = 0x1FFF;
1756     else
1757       pmt->pcr_pid = tsmux_stream_get_pid (program->pcr_stream);
1758
1759 #if 0
1760     /* FIXME : These two descriptors should not be added in all PMT
1761      * but only in "bluray-compatible" mpeg-ts output. I even have my
1762      * doubt whether the DTCP descriptor is even needed */
1763     descriptor = gst_mpegts_descriptor_from_registration ("HDMV", NULL, 0);
1764     g_ptr_array_add (pmt->descriptors, descriptor);
1765
1766     /* DTCP descriptor, see
1767      * http://www.dtcp.com/documents/dtcp/info-20150204-dtcp-v1-rev%201-71.pdf */
1768     descriptor = gst_mpegts_descriptor_from_custom (0x88, desc, 4);
1769     g_ptr_array_add (pmt->descriptors, descriptor);
1770 #endif
1771
1772     /* Will SCTE-35 be potentially used ? */
1773     if (program->scte35_pid != 0) {
1774       descriptor = gst_mpegts_descriptor_from_registration ("CUEI", NULL, 0);
1775       g_ptr_array_add (pmt->descriptors, descriptor);
1776     }
1777
1778     /* Write out the entries */
1779     for (i = 0; i < program->streams->len; i++) {
1780       GstMpegtsPMTStream *pmt_stream;
1781       TsMuxStream *stream = g_ptr_array_index (program->streams, i);
1782
1783       pmt_stream = gst_mpegts_pmt_stream_new ();
1784
1785       /* FIXME: Use API to retrieve this from the stream */
1786       pmt_stream->stream_type = stream->stream_type;
1787       pmt_stream->pid = tsmux_stream_get_pid (stream);
1788
1789       /* Write any ES descriptors needed */
1790       tsmux_stream_get_es_descrs (stream, pmt_stream);
1791       g_ptr_array_add (pmt->streams, pmt_stream);
1792     }
1793
1794     /* Will SCTE-35 be potentially used ? */
1795     if (program->scte35_pid != 0) {
1796       GstMpegtsPMTStream *pmt_stream = gst_mpegts_pmt_stream_new ();
1797       pmt_stream->stream_type = GST_MPEGTS_STREAM_TYPE_SCTE_SIT;
1798       pmt_stream->pid = program->scte35_pid;
1799       g_ptr_array_add (pmt->streams, pmt_stream);
1800     }
1801
1802     TS_DEBUG ("PMT for program %d has %d streams",
1803         program->pgm_number, program->streams->len);
1804
1805     pmt->program_number = program->pgm_number;
1806
1807     program->pmt.pi.pid = program->pmt_pid;
1808     program->pmt_changed = FALSE;
1809
1810     if (program->pmt.section)
1811       gst_mpegts_section_unref (program->pmt.section);
1812
1813     program->pmt.section = gst_mpegts_section_from_pmt (pmt, program->pmt_pid);
1814     program->pmt.section->version_number = program->pmt_version++;
1815   }
1816
1817   return tsmux_section_write_packet (mux, &program->pmt);
1818 }
1819
1820 static gboolean
1821 tsmux_write_scte_null (TsMux * mux, TsMuxProgram * program)
1822 {
1823   /* SCTE-35 NULL section is created when PID is set */
1824   GST_LOG ("Writing SCTE NULL packet");
1825   return tsmux_section_write_packet (mux, program->scte35_null_section);
1826 }
1827
1828 void
1829 tsmux_set_bitrate (TsMux * mux, guint64 bitrate)
1830 {
1831   mux->bitrate = bitrate;
1832 }