2e5fa2d6806c052aade9cef8b70bc1342fe9e869
[platform/upstream/gstreamer.git] / gst / mpegtsmux / tsmux / tsmuxstream.c
1 /*
2  * Copyright 2006 BBC and Fluendo S.A.
3  *
4  * This library is licensed under 4 different licenses and you
5  * can choose to use it under the terms of any one of them. The
6  * four licenses are the MPL 1.1, the LGPL, the GPL and the MIT
7  * license.
8  *
9  * MPL:
10  *
11  * The contents of this file are subject to the Mozilla Public License
12  * Version 1.1 (the "License"); you may not use this file except in
13  * compliance with the License. You may obtain a copy of the License at
14  * http://www.mozilla.org/MPL/.
15  *
16  * Software distributed under the License is distributed on an "AS IS"
17  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
18  * License for the specific language governing rights and limitations
19  * under the License.
20  *
21  * LGPL:
22  *
23  * This library is free software; you can redistribute it and/or
24  * modify it under the terms of the GNU Library General Public
25  * License as published by the Free Software Foundation; either
26  * version 2 of the License, or (at your option) any later version.
27  *
28  * This library is distributed in the hope that it will be useful,
29  * but WITHOUT ANY WARRANTY; without even the implied warranty of
30  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
31  * Library General Public License for more details.
32  *
33  * You should have received a copy of the GNU Library General Public
34  * License along with this library; if not, write to the
35  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
36  * Boston, MA 02110-1301, USA.
37  *
38  * GPL:
39  *
40  * This program is free software; you can redistribute it and/or modify
41  * it under the terms of the GNU General Public License as published by
42  * the Free Software Foundation; either version 2 of the License, or
43  * (at your option) any later version.
44  *
45  * This program is distributed in the hope that it will be useful,
46  * but WITHOUT ANY WARRANTY; without even the implied warranty of
47  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
48  * GNU General Public License for more details.
49  *
50  * You should have received a copy of the GNU General Public License
51  * along with this program; if not, write to the Free Software
52  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
53  *
54  * MIT:
55  *
56  * Unless otherwise indicated, Source Code is licensed under MIT license.
57  * See further explanation attached in License Statement (distributed in the file
58  * LICENSE).
59  *
60  * Permission is hereby granted, free of charge, to any person obtaining a copy of
61  * this software and associated documentation files (the "Software"), to deal in
62  * the Software without restriction, including without limitation the rights to
63  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
64  * of the Software, and to permit persons to whom the Software is furnished to do
65  * so, subject to the following conditions:
66  *
67  * The above copyright notice and this permission notice shall be included in all
68  * copies or substantial portions of the Software.
69  *
70  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
71  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
72  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
73  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
74  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
75  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
76  * SOFTWARE.
77  *
78  */
79
80 #ifdef HAVE_CONFIG_H
81 #include "config.h"
82 #endif
83
84 #include <string.h>
85
86 #include <gst/mpegts/mpegts.h>
87 #include <gst/base/gstbytewriter.h>
88
89 #include "tsmuxcommon.h"
90 #include "tsmuxstream.h"
91
92 #define GST_CAT_DEFAULT gst_base_ts_mux_debug
93
94 static guint8 tsmux_stream_pes_header_length (TsMuxStream * stream);
95 static void tsmux_stream_write_pes_header (TsMuxStream * stream, guint8 * data);
96 static void tsmux_stream_find_pts_dts_within (TsMuxStream * stream, guint bound,
97     gint64 * pts, gint64 * dts);
98
99 struct TsMuxStreamBuffer
100 {
101   guint8 *data;
102   guint32 size;
103
104   /* PTS & DTS associated with the contents of this buffer */
105   gint64 pts;
106   gint64 dts;
107
108   /* data represents random access point */
109   gboolean random_access;
110
111   /* user_data for release function */
112   void *user_data;
113 };
114
115 /**
116  * tsmux_stream_new:
117  * @pid: a PID
118  * @stream_type: the stream type
119  *
120  * Create a new stream with PID of @pid and @stream_type.
121  *
122  * Returns: a new #TsMuxStream.
123  */
124 TsMuxStream *
125 tsmux_stream_new (guint16 pid, guint stream_type)
126 {
127   TsMuxStream *stream = g_slice_new0 (TsMuxStream);
128
129   stream->state = TSMUX_STREAM_STATE_HEADER;
130   stream->pi.pid = pid;
131   stream->stream_type = stream_type;
132
133   stream->pes_payload_size = 0;
134   stream->cur_pes_payload_size = 0;
135   stream->pes_bytes_written = 0;
136
137   switch (stream_type) {
138     case TSMUX_ST_VIDEO_MPEG1:
139     case TSMUX_ST_VIDEO_MPEG2:
140     case TSMUX_ST_VIDEO_MPEG4:
141     case TSMUX_ST_VIDEO_H264:
142     case TSMUX_ST_VIDEO_HEVC:
143       /* FIXME: Assign sequential IDs? */
144       stream->id = 0xE0;
145       stream->pi.flags |= TSMUX_PACKET_FLAG_PES_FULL_HEADER;
146       stream->is_video_stream = TRUE;
147       break;
148     case TSMUX_ST_VIDEO_JP2K:
149       stream->id = 0xBD;
150       stream->pi.flags |= TSMUX_PACKET_FLAG_PES_FULL_HEADER;
151       stream->is_video_stream = TRUE;
152       break;
153     case TSMUX_ST_AUDIO_AAC:
154     case TSMUX_ST_AUDIO_MPEG1:
155     case TSMUX_ST_AUDIO_MPEG2:
156       /* FIXME: Assign sequential IDs? */
157       stream->is_audio = TRUE;
158       stream->id = 0xC0;
159       stream->pi.flags |= TSMUX_PACKET_FLAG_PES_FULL_HEADER;
160       break;
161     case TSMUX_ST_VIDEO_DIRAC:
162     case TSMUX_ST_PS_AUDIO_LPCM:
163     case TSMUX_ST_PS_AUDIO_AC3:
164     case TSMUX_ST_PS_AUDIO_DTS:
165       stream->id = 0xFD;
166       /* FIXME: assign sequential extended IDs? */
167       switch (stream_type) {
168         case TSMUX_ST_VIDEO_DIRAC:
169           stream->id_extended = 0x60;
170           stream->is_video_stream = TRUE;
171           break;
172         case TSMUX_ST_PS_AUDIO_LPCM:
173           stream->is_audio = TRUE;
174           stream->id_extended = 0x80;
175           break;
176         case TSMUX_ST_PS_AUDIO_AC3:
177           stream->is_audio = TRUE;
178           stream->id_extended = 0x71;
179           break;
180         case TSMUX_ST_PS_AUDIO_DTS:
181           stream->is_audio = TRUE;
182           stream->id_extended = 0x82;
183           break;
184         default:
185           break;
186       }
187       stream->pi.flags |=
188           TSMUX_PACKET_FLAG_PES_FULL_HEADER |
189           TSMUX_PACKET_FLAG_PES_EXT_STREAMID;
190       break;
191     case TSMUX_ST_PS_TELETEXT:
192       /* needs fixes PES header length */
193       stream->pi.pes_header_length = 36;
194       /* fall through */
195     case TSMUX_ST_PS_DVB_SUBPICTURE:
196       /* private stream 1 */
197       stream->id = 0xBD;
198       stream->is_dvb_sub = TRUE;
199       stream->stream_type = TSMUX_ST_PRIVATE_DATA;
200       stream->pi.flags |=
201           TSMUX_PACKET_FLAG_PES_FULL_HEADER |
202           TSMUX_PACKET_FLAG_PES_DATA_ALIGNMENT;
203
204       break;
205     case TSMUX_ST_PS_KLV:
206       /* FIXME: assign sequential extended IDs? */
207       stream->id = 0xBD;
208       stream->stream_type = TSMUX_ST_PRIVATE_DATA;
209       stream->is_meta = TRUE;
210       stream->pi.flags |=
211           TSMUX_PACKET_FLAG_PES_FULL_HEADER |
212           TSMUX_PACKET_FLAG_PES_DATA_ALIGNMENT;
213       break;
214     case TSMUX_ST_PS_OPUS:
215       /* FIXME: assign sequential extended IDs? */
216       stream->id = 0xBD;
217       stream->is_audio = TRUE;
218       stream->stream_type = TSMUX_ST_PRIVATE_DATA;
219       stream->is_opus = TRUE;
220       stream->pi.flags |= TSMUX_PACKET_FLAG_PES_FULL_HEADER;
221       break;
222     default:
223       /* Might be a custom stream type implemented by a subclass */
224       break;
225   }
226
227   stream->first_ts = GST_CLOCK_STIME_NONE;
228
229   stream->last_pts = GST_CLOCK_STIME_NONE;
230   stream->last_dts = GST_CLOCK_STIME_NONE;
231
232   stream->pcr_ref = 0;
233   stream->next_pcr = -1;
234
235   stream->get_es_descrs =
236       (TsMuxStreamGetESDescriptorsFunc) tsmux_stream_default_get_es_descrs;
237   stream->get_es_descrs_data = NULL;
238
239   return stream;
240 }
241
242 /**
243  * tsmux_stream_get_pid:
244  * @stream: a #TsMuxStream
245  *
246  * Get the PID of @stream.
247  *
248  * Returns: The PID of @stream. 0xffff on error.
249  */
250 guint16
251 tsmux_stream_get_pid (TsMuxStream * stream)
252 {
253   g_return_val_if_fail (stream != NULL, G_MAXUINT16);
254
255   return stream->pi.pid;
256 }
257
258 /**
259  * tsmux_stream_free:
260  * @stream: a #TsMuxStream
261  *
262  * Free the resources of @stream.
263  */
264 void
265 tsmux_stream_free (TsMuxStream * stream)
266 {
267   GList *cur;
268
269   g_return_if_fail (stream != NULL);
270
271   /* free buffers */
272   for (cur = stream->buffers; cur; cur = cur->next) {
273     TsMuxStreamBuffer *tmbuf = (TsMuxStreamBuffer *) cur->data;
274
275     if (stream->buffer_release)
276       stream->buffer_release (tmbuf->data, tmbuf->user_data);
277     g_slice_free (TsMuxStreamBuffer, tmbuf);
278   }
279   g_list_free (stream->buffers);
280
281   g_slice_free (TsMuxStream, stream);
282 }
283
284 /**
285  * tsmux_stream_set_buffer_release_func:
286  * @stream: a #TsMuxStream
287  * @func: the new #TsMuxStreamBufferReleaseFunc
288  *
289  * Set the function that will be called when a a piece of data fed to @stream
290  * with tsmux_stream_add_data() can be freed. @func will be called with user
291  * data as provided with the call to tsmux_stream_add_data().
292  */
293 void
294 tsmux_stream_set_buffer_release_func (TsMuxStream * stream,
295     TsMuxStreamBufferReleaseFunc func)
296 {
297   g_return_if_fail (stream != NULL);
298
299   stream->buffer_release = func;
300 }
301
302 /**
303  * tsmux_stream_set_get_es_descriptors_func:
304  * @stream: a #TsMuxStream
305  * @func: a user callback function
306  * @user_data: user data passed to @func
307  *
308  * Set the callback function and user data to be called when @stream has
309  * to create Elementary Stream Descriptors.
310  */
311 void
312 tsmux_stream_set_get_es_descriptors_func (TsMuxStream * stream,
313     TsMuxStreamGetESDescriptorsFunc func, void *user_data)
314 {
315   g_return_if_fail (stream != NULL);
316
317   stream->get_es_descrs = func;
318   stream->get_es_descrs_data = user_data;
319 }
320
321 /* Advance the current packet stream position by len bytes.
322  * Mustn't consume more than available in the current packet */
323 static void
324 tsmux_stream_consume (TsMuxStream * stream, guint len)
325 {
326   g_assert (stream->cur_buffer != NULL);
327   g_assert (len <= stream->cur_buffer->size - stream->cur_buffer_consumed);
328
329   stream->cur_buffer_consumed += len;
330   stream->bytes_avail -= len;
331
332   if (stream->cur_buffer_consumed == 0 && stream->cur_buffer->size != 0)
333     return;
334
335   if (GST_CLOCK_STIME_IS_VALID (stream->cur_buffer->pts))
336     stream->last_pts = stream->cur_buffer->pts;
337   if (GST_CLOCK_STIME_IS_VALID (stream->cur_buffer->dts))
338     stream->last_dts = stream->cur_buffer->dts;
339
340   if (stream->cur_buffer_consumed == stream->cur_buffer->size) {
341     /* Current packet is completed, move along */
342     stream->buffers = g_list_delete_link (stream->buffers, stream->buffers);
343
344     if (stream->buffer_release) {
345       stream->buffer_release (stream->cur_buffer->data,
346           stream->cur_buffer->user_data);
347     }
348
349     g_slice_free (TsMuxStreamBuffer, stream->cur_buffer);
350     stream->cur_buffer = NULL;
351     /* FIXME: As a hack, for unbounded streams, start a new PES packet for each
352      * incoming packet we receive. This assumes that incoming data is
353      * packetised sensibly - ie, every video frame */
354     if (stream->cur_pes_payload_size == 0) {
355       stream->state = TSMUX_STREAM_STATE_HEADER;
356       stream->pes_bytes_written = 0;
357     }
358   }
359 }
360
361 /**
362  * tsmux_stream_at_pes_start:
363  * @stream: a #TsMuxStream
364  *
365  * Check if @stream is at the start of a PES packet.
366  *
367  * Returns: TRUE if @stream is at a PES header packet.
368  */
369 gboolean
370 tsmux_stream_at_pes_start (TsMuxStream * stream)
371 {
372   g_return_val_if_fail (stream != NULL, FALSE);
373
374   return stream->state == TSMUX_STREAM_STATE_HEADER;
375 }
376
377 /**
378  * tsmux_stream_bytes_avail:
379  * @stream: a #TsMuxStream
380  *
381  * Calculate how much bytes are available.
382  *
383  * Returns: The number of bytes available.
384  */
385 static inline gint
386 _tsmux_stream_bytes_avail (TsMuxStream * stream)
387 {
388   gint bytes_avail;
389
390   g_return_val_if_fail (stream != NULL, 0);
391
392   if (stream->cur_pes_payload_size != 0)
393     bytes_avail = stream->cur_pes_payload_size - stream->pes_bytes_written;
394   else
395     bytes_avail = stream->bytes_avail;
396
397   bytes_avail = MIN (bytes_avail, stream->bytes_avail);
398
399   /* Calculate the number of bytes available in the current PES */
400   if (stream->state == TSMUX_STREAM_STATE_HEADER)
401     bytes_avail += tsmux_stream_pes_header_length (stream);
402
403   return bytes_avail;
404 }
405
406 gint
407 tsmux_stream_bytes_avail (TsMuxStream * stream)
408 {
409   g_return_val_if_fail (stream != NULL, 0);
410
411   return _tsmux_stream_bytes_avail (stream);
412 }
413
414 /**
415  * tsmux_stream_bytes_in_buffer:
416  * @stream: a #TsMuxStream
417  *
418  * Calculate how much bytes are in the buffer.
419  *
420  * Returns: The number of bytes in the buffer.
421  */
422 gint
423 tsmux_stream_bytes_in_buffer (TsMuxStream * stream)
424 {
425   g_return_val_if_fail (stream != NULL, 0);
426
427   return stream->bytes_avail;
428 }
429
430 /**
431  * tsmux_stream_initialize_pes_packet:
432  * @stream: a #TsMuxStream
433  *
434  * Initializes the PES packet.
435  *
436  * Returns: TRUE if we the packet was initialized.
437  */
438 gboolean
439 tsmux_stream_initialize_pes_packet (TsMuxStream * stream)
440 {
441   if (stream->state != TSMUX_STREAM_STATE_HEADER)
442     return TRUE;
443
444   if (stream->pes_payload_size != 0) {
445     /* Use prescribed fixed PES payload size */
446     stream->cur_pes_payload_size = stream->pes_payload_size;
447     tsmux_stream_find_pts_dts_within (stream, stream->cur_pes_payload_size,
448         &stream->pts, &stream->dts);
449   } else {
450     /* Output a PES packet of all currently available bytes otherwise */
451     stream->cur_pes_payload_size = stream->bytes_avail;
452     tsmux_stream_find_pts_dts_within (stream, stream->cur_pes_payload_size,
453         &stream->pts, &stream->dts);
454   }
455
456   stream->pi.flags &= ~(TSMUX_PACKET_FLAG_PES_WRITE_PTS_DTS |
457       TSMUX_PACKET_FLAG_PES_WRITE_PTS);
458
459   if (GST_CLOCK_STIME_IS_VALID (stream->pts)
460       && GST_CLOCK_STIME_IS_VALID (stream->dts)
461       && stream->pts != stream->dts)
462     stream->pi.flags |= TSMUX_PACKET_FLAG_PES_WRITE_PTS_DTS;
463   else {
464     if (GST_CLOCK_STIME_IS_VALID (stream->pts))
465       stream->pi.flags |= TSMUX_PACKET_FLAG_PES_WRITE_PTS;
466   }
467
468   if (stream->buffers) {
469     TsMuxStreamBuffer *buf = (TsMuxStreamBuffer *) (stream->buffers->data);
470     if (buf->random_access) {
471       stream->pi.flags |= TSMUX_PACKET_FLAG_RANDOM_ACCESS;
472       stream->pi.flags |= TSMUX_PACKET_FLAG_ADAPTATION;
473     }
474   }
475
476   if (stream->is_video_stream) {
477     guint8 hdr_len;
478
479     hdr_len = tsmux_stream_pes_header_length (stream);
480
481     /* Unbounded for video streams if pes packet length is over 16 bit */
482     if ((stream->cur_pes_payload_size + hdr_len - 6) > G_MAXUINT16)
483       stream->cur_pes_payload_size = 0;
484   }
485
486   return TRUE;
487 }
488
489 /**
490  * tsmux_stream_get_data:
491  * @stream: a #TsMuxStream
492  * @buf: a buffer to hold the result
493  * @len: the length of @buf
494  *
495  * Copy up to @len available data in @stream into the buffer @buf.
496  *
497  * Returns: TRUE if @len bytes could be retrieved.
498  */
499 gboolean
500 tsmux_stream_get_data (TsMuxStream * stream, guint8 * buf, guint len)
501 {
502   g_return_val_if_fail (stream != NULL, FALSE);
503   g_return_val_if_fail (buf != NULL, FALSE);
504
505   if (stream->state == TSMUX_STREAM_STATE_HEADER) {
506     guint8 pes_hdr_length;
507
508     pes_hdr_length = tsmux_stream_pes_header_length (stream);
509
510     /* Submitted buffer must be at least as large as the PES header */
511     if (len < pes_hdr_length)
512       return FALSE;
513
514     TS_DEBUG ("Writing PES header of length %u and payload %d",
515         pes_hdr_length, stream->cur_pes_payload_size);
516     tsmux_stream_write_pes_header (stream, buf);
517
518     len -= pes_hdr_length;
519     buf += pes_hdr_length;
520
521     stream->state = TSMUX_STREAM_STATE_PACKET;
522   }
523
524   if (len > (guint) _tsmux_stream_bytes_avail (stream))
525     return FALSE;
526
527   stream->pes_bytes_written += len;
528
529   if (stream->cur_pes_payload_size != 0 &&
530       stream->pes_bytes_written == stream->cur_pes_payload_size) {
531     TS_DEBUG ("Finished PES packet");
532     stream->state = TSMUX_STREAM_STATE_HEADER;
533     stream->pes_bytes_written = 0;
534   }
535
536   while (len > 0) {
537     guint32 avail;
538     guint8 *cur;
539
540     if (stream->cur_buffer == NULL) {
541       /* Start next packet */
542       if (stream->buffers == NULL)
543         return FALSE;
544       stream->cur_buffer = (TsMuxStreamBuffer *) (stream->buffers->data);
545       stream->cur_buffer_consumed = 0;
546     }
547
548     /* Take as much as we can from the current buffer */
549     avail = stream->cur_buffer->size - stream->cur_buffer_consumed;
550     cur = stream->cur_buffer->data + stream->cur_buffer_consumed;
551     if (avail < len) {
552       memcpy (buf, cur, avail);
553       tsmux_stream_consume (stream, avail);
554
555       buf += avail;
556       len -= avail;
557     } else {
558       memcpy (buf, cur, len);
559       tsmux_stream_consume (stream, len);
560
561       len = 0;
562     }
563   }
564
565   return TRUE;
566 }
567
568 static guint8
569 tsmux_stream_pes_header_length (TsMuxStream * stream)
570 {
571   guint8 packet_len;
572
573   /* Calculate the length of the header for this stream */
574
575   /* start_code prefix + stream_id + pes_packet_length = 6 bytes */
576   packet_len = 6;
577
578   if (stream->pi.flags & TSMUX_PACKET_FLAG_PES_FULL_HEADER) {
579     /* For a PES 'full header' we have at least 3 more bytes,
580      * and then more based on flags */
581     packet_len += 3;
582     if (stream->pi.flags & TSMUX_PACKET_FLAG_PES_WRITE_PTS_DTS) {
583       packet_len += 10;
584     } else if (stream->pi.flags & TSMUX_PACKET_FLAG_PES_WRITE_PTS) {
585       packet_len += 5;
586     }
587     if (stream->pi.flags & TSMUX_PACKET_FLAG_PES_EXT_STREAMID) {
588       /* Need basic extension flags (1 byte), plus 2 more bytes for the
589        * length + extended stream id */
590       packet_len += 3;
591     }
592     if (stream->pi.pes_header_length) {
593       /* check for consistency, then we can add stuffing */
594       g_assert (packet_len <= stream->pi.pes_header_length + 6 + 3);
595       packet_len = stream->pi.pes_header_length + 6 + 3;
596     }
597   }
598
599   return packet_len;
600 }
601
602 /* Find a PTS/DTS to write into the pes header within the next bound bytes
603  * of the data */
604 static void
605 tsmux_stream_find_pts_dts_within (TsMuxStream * stream, guint bound,
606     gint64 * pts, gint64 * dts)
607 {
608   GList *cur;
609
610   *pts = GST_CLOCK_STIME_NONE;
611   *dts = GST_CLOCK_STIME_NONE;
612
613   for (cur = stream->buffers; cur; cur = cur->next) {
614     TsMuxStreamBuffer *curbuf = cur->data;
615
616     /* FIXME: This isn't quite correct - if the 'bound' is within this
617      * buffer, we don't know if the timestamp is before or after the split
618      * so we shouldn't return it */
619     if (bound <= curbuf->size) {
620       *pts = curbuf->pts;
621       *dts = curbuf->dts;
622       return;
623     }
624
625     /* Have we found a buffer with pts/dts set? */
626     if (GST_CLOCK_STIME_IS_VALID (curbuf->pts)
627         || GST_CLOCK_STIME_IS_VALID (curbuf->dts)) {
628       *pts = curbuf->pts;
629       *dts = curbuf->dts;
630       return;
631     }
632
633     bound -= curbuf->size;
634   }
635 }
636
637 static void
638 tsmux_stream_write_pes_header (TsMuxStream * stream, guint8 * data)
639 {
640   guint16 length_to_write;
641   guint8 hdr_len = tsmux_stream_pes_header_length (stream);
642   guint8 *orig_data = data;
643
644   /* start_code prefix + stream_id + pes_packet_length = 6 bytes */
645   data[0] = 0x00;
646   data[1] = 0x00;
647   data[2] = 0x01;
648   data[3] = stream->id;
649   data += 4;
650
651   /* Write 2 byte PES packet length here. 0 (unbounded) is only
652    * valid for video packets */
653   if (stream->cur_pes_payload_size != 0) {
654     length_to_write = hdr_len + stream->cur_pes_payload_size - 6;
655   } else {
656     length_to_write = 0;
657   }
658
659   tsmux_put16 (&data, length_to_write);
660
661   if (stream->pi.flags & TSMUX_PACKET_FLAG_PES_FULL_HEADER) {
662     guint8 flags = 0;
663
664     /* Not scrambled, original, not-copyrighted, data_alignment not specified */
665     flags = 0x81;
666     if (stream->pi.flags & TSMUX_PACKET_FLAG_PES_DATA_ALIGNMENT)
667       flags |= 0x4;
668     *data++ = flags;
669     flags = 0;
670
671     /* Flags */
672     if (stream->pi.flags & TSMUX_PACKET_FLAG_PES_WRITE_PTS_DTS)
673       flags |= 0xC0;
674     else if (stream->pi.flags & TSMUX_PACKET_FLAG_PES_WRITE_PTS)
675       flags |= 0x80;
676     if (stream->pi.flags & TSMUX_PACKET_FLAG_PES_EXT_STREAMID)
677       flags |= 0x01;            /* Enable PES_extension_flag */
678     *data++ = flags;
679
680     /* Header length is the total pes length,
681      * minus the 9 bytes of start codes, flags + hdr_len */
682     g_return_if_fail (hdr_len >= 9);
683     *data++ = (hdr_len - 9);
684
685     if (stream->pi.flags & TSMUX_PACKET_FLAG_PES_WRITE_PTS_DTS) {
686       tsmux_put_ts (&data, 0x3, stream->pts);
687       tsmux_put_ts (&data, 0x1, stream->dts);
688     } else if (stream->pi.flags & TSMUX_PACKET_FLAG_PES_WRITE_PTS) {
689       tsmux_put_ts (&data, 0x2, stream->pts);
690     }
691     if (stream->pi.flags & TSMUX_PACKET_FLAG_PES_EXT_STREAMID) {
692       guint8 ext_len;
693
694       flags = 0x0f;             /* (reserved bits) | PES_extension_flag_2 */
695       *data++ = flags;
696
697       ext_len = 1;              /* Only writing 1 byte into the extended fields */
698       *data++ = 0x80 | ext_len;
699       /* Write the extended streamID */
700       *data++ = stream->id_extended;
701     }
702     /* write stuffing bytes if fixed PES header length requested */
703     if (stream->pi.pes_header_length)
704       while (data < orig_data + stream->pi.pes_header_length + 9)
705         *data++ = 0xff;
706   }
707 }
708
709 /**
710  * tsmux_stream_add_data:
711  * @stream: a #TsMuxStream
712  * @data: data to add
713  * @len: length of @data
714  * @user_data: user data to pass to release func
715  * @pts: PTS of access unit in @data
716  * @dts: DTS of access unit in @data
717  * @random_access: TRUE if random access point (keyframe)
718  *
719  * Submit @len bytes of @data into @stream. @pts and @dts can be set to the
720  * timestamp (against a 90Hz clock) of the first access unit in @data. A
721  * timestamp of GST_CLOCK_STIME_NNOE for @pts or @dts means unknown.
722  *
723  * @user_data will be passed to the release function as set with
724  * tsmux_stream_set_buffer_release_func() when @data can be freed.
725  */
726 void
727 tsmux_stream_add_data (TsMuxStream * stream, guint8 * data, guint len,
728     void *user_data, gint64 pts, gint64 dts, gboolean random_access)
729 {
730   TsMuxStreamBuffer *packet;
731
732   g_return_if_fail (stream != NULL);
733
734   packet = g_slice_new (TsMuxStreamBuffer);
735   packet->data = data;
736   packet->size = len;
737   packet->user_data = user_data;
738   packet->random_access = random_access;
739
740   packet->pts = pts;
741   packet->dts = dts;
742
743   if (stream->bytes_avail == 0) {
744     stream->last_pts = pts;
745     stream->last_dts = dts;
746   }
747
748   stream->bytes_avail += len;
749   stream->buffers = g_list_append (stream->buffers, packet);
750 }
751
752 /**
753  * tsmux_stream_default_get_es_descrs:
754  * @stream: a #TsMuxStream
755  * @buf: a buffer to hold the ES descriptor
756  * @len: the length used in @buf
757  *
758  * Write an Elementary Stream Descriptor for @stream into @buf. the number of
759  * bytes consumed in @buf will be updated in @len.
760  *
761  * @buf and @len must be at least #TSMUX_MIN_ES_DESC_LEN.
762  */
763 void
764 tsmux_stream_default_get_es_descrs (TsMuxStream * stream,
765     GstMpegtsPMTStream * pmt_stream)
766 {
767   GstMpegtsDescriptor *descriptor;
768
769   g_return_if_fail (stream != NULL);
770   g_return_if_fail (pmt_stream != NULL);
771
772   if (stream->is_audio && stream->language[0] != '\0') {
773     descriptor = gst_mpegts_descriptor_from_iso_639_language (stream->language);
774     g_ptr_array_add (pmt_stream->descriptors, descriptor);
775     descriptor = NULL;
776   }
777
778   /* Based on the stream type, write out any descriptors to go in the
779    * PMT ES_info field */
780   /* tag (registration_descriptor), length, format_identifier */
781   switch (stream->stream_type) {
782     case TSMUX_ST_AUDIO_AAC:
783       /* FIXME */
784       break;
785     case TSMUX_ST_VIDEO_MPEG4:
786       /* FIXME */
787       break;
788     case TSMUX_ST_VIDEO_H264:
789     {
790       /* FIXME : Not sure about this additional_identification_info */
791       guint8 add_info[] = { 0xFF, 0x1B, 0x44, 0x3F };
792
793       descriptor = gst_mpegts_descriptor_from_registration ("HDMV",
794           add_info, 4);
795
796       g_ptr_array_add (pmt_stream->descriptors, descriptor);
797       break;
798     }
799     case TSMUX_ST_VIDEO_DIRAC:
800       descriptor = gst_mpegts_descriptor_from_registration ("drac", NULL, 0);
801       g_ptr_array_add (pmt_stream->descriptors, descriptor);
802       break;
803     case TSMUX_ST_VIDEO_JP2K:
804     {
805       /* J2K video descriptor
806        * descriptor_tag             8 uimsbf
807        * descriptor_length          8 uimsbf
808        * profile_and_level         16 uimsbf
809        * horizontal_size           32 uimsbf
810        * vertical_size             32 uimsbf
811        * max_bit_rate              32 uimsbf
812        * max_buffer_size           32 uimsbf
813        * DEN_frame_rate            16 uimsbf
814        * NUM_frame_rate            16 uimsbf
815        * color_specification        8 bslbf
816        * still_mode                 1 bslbf
817        * interlace_video            1 bslbf
818        * reserved                   6 bslbf
819        * private_data_byte          8 bslbf
820        */
821       gint8 still_interlace_reserved = 0x00;
822       int wr_size = 0;
823       guint8 *add_info = NULL;
824       guint8 level = stream->profile_and_level & 0xF;
825       guint32 max_buffer_size = 0;
826       GstByteWriter writer;
827       gst_byte_writer_init_with_size (&writer, 32, FALSE);
828
829       switch (level) {
830         case 1:
831         case 2:
832         case 3:
833           max_buffer_size = 1250000;
834           break;
835         case 4:
836           max_buffer_size = 2500000;
837           break;
838         case 5:
839           max_buffer_size = 5000000;
840           break;
841         case 6:
842           max_buffer_size = 10000000;
843           break;
844         default:
845           break;
846       }
847
848       gst_byte_writer_put_uint16_be (&writer, stream->profile_and_level);
849       gst_byte_writer_put_uint32_be (&writer, stream->horizontal_size);
850       gst_byte_writer_put_uint32_be (&writer, stream->vertical_size);
851       gst_byte_writer_put_uint32_be (&writer, max_buffer_size);
852       gst_byte_writer_put_uint32_be (&writer, stream->max_bitrate);
853       gst_byte_writer_put_uint16_be (&writer, stream->den);
854       gst_byte_writer_put_uint16_be (&writer, stream->num);
855       gst_byte_writer_put_uint8 (&writer, stream->color_spec);
856
857       if (stream->interlace_mode)
858         still_interlace_reserved |= 0x40;
859
860       gst_byte_writer_put_uint8 (&writer, still_interlace_reserved);
861       gst_byte_writer_put_uint8 (&writer, 0x00);        /* private data byte */
862
863       wr_size = gst_byte_writer_get_size (&writer);
864       add_info = gst_byte_writer_reset_and_get_data (&writer);
865
866       descriptor =
867           gst_mpegts_descriptor_from_custom (GST_MTS_DESC_J2K_VIDEO, add_info,
868           wr_size);
869       g_ptr_array_add (pmt_stream->descriptors, descriptor);
870     }
871       break;
872     case TSMUX_ST_PS_AUDIO_AC3:
873     {
874       guint8 add_info[6];
875       guint8 *pos;
876
877       pos = add_info;
878
879       /* audio_stream_descriptor () | ATSC A/52-2001 Annex A
880        *
881        * descriptor_tag       8 uimsbf
882        * descriptor_length    8 uimsbf
883        * sample_rate_code     3 bslbf
884        * bsid                 5 bslbf
885        * bit_rate_code        6 bslbf
886        * surround_mode        2 bslbf
887        * bsmod                3 bslbf
888        * num_channels         4 bslbf
889        * full_svc             1 bslbf
890        * langcod              8 bslbf
891        * [...]
892        */
893       *pos++ = 0x81;
894       *pos++ = 0x04;
895
896       /* 3 bits sample_rate_code, 5 bits hardcoded bsid (default ver 8) */
897       switch (stream->audio_sampling) {
898         case 48000:
899           *pos++ = 0x08;
900           break;
901         case 44100:
902           *pos++ = 0x28;
903           break;
904         case 32000:
905           *pos++ = 0x48;
906           break;
907         default:
908           *pos++ = 0xE8;
909           break;                /* 48, 44.1 or 32 Khz */
910       }
911
912       /* 1 bit bit_rate_limit, 5 bits bit_rate_code, 2 bits suround_mode */
913       switch (stream->audio_bitrate) {
914         case 32:
915           *pos++ = 0x00 << 2;
916           break;
917         case 40:
918           *pos++ = 0x01 << 2;
919           break;
920         case 48:
921           *pos++ = 0x02 << 2;
922           break;
923         case 56:
924           *pos++ = 0x03 << 2;
925           break;
926         case 64:
927           *pos++ = 0x04 << 2;
928           break;
929         case 80:
930           *pos++ = 0x05 << 2;
931           break;
932         case 96:
933           *pos++ = 0x06 << 2;
934           break;
935         case 112:
936           *pos++ = 0x07 << 2;
937           break;
938         case 128:
939           *pos++ = 0x08 << 2;
940           break;
941         case 160:
942           *pos++ = 0x09 << 2;
943           break;
944         case 192:
945           *pos++ = 0x0A << 2;
946           break;
947         case 224:
948           *pos++ = 0x0B << 2;
949           break;
950         case 256:
951           *pos++ = 0x0C << 2;
952           break;
953         case 320:
954           *pos++ = 0x0D << 2;
955           break;
956         case 384:
957           *pos++ = 0x0E << 2;
958           break;
959         case 448:
960           *pos++ = 0x0F << 2;
961           break;
962         case 512:
963           *pos++ = 0x10 << 2;
964           break;
965         case 576:
966           *pos++ = 0x11 << 2;
967           break;
968         case 640:
969           *pos++ = 0x12 << 2;
970           break;
971         default:
972           *pos++ = 0x32 << 2;
973           break;                /* 640 Kb/s upper limit */
974       }
975
976       /* 3 bits bsmod, 4 bits num_channels, 1 bit full_svc */
977       switch (stream->audio_channels) {
978         case 1:
979           *pos++ = 0x01 << 1;
980           break;                /* 1/0 */
981         case 2:
982           *pos++ = 0x02 << 1;
983           break;                /* 2/0 */
984         case 3:
985           *pos++ = 0x0A << 1;
986           break;                /* <= 3 */
987         case 4:
988           *pos++ = 0x0B << 1;
989           break;                /* <= 4 */
990         case 5:
991           *pos++ = 0x0C << 1;
992           break;                /* <= 5 */
993         case 6:
994         default:
995           *pos++ = 0x0D << 1;
996           break;                /* <= 6 */
997       }
998
999       *pos++ = 0x00;
1000
1001       descriptor = gst_mpegts_descriptor_from_registration ("AC-3",
1002           add_info, 6);
1003       g_ptr_array_add (pmt_stream->descriptors, descriptor);
1004
1005       descriptor =
1006           gst_mpegts_descriptor_from_custom (GST_MTS_DESC_AC3_AUDIO_STREAM,
1007           add_info, 6);
1008       g_ptr_array_add (pmt_stream->descriptors, descriptor);
1009
1010       break;
1011     }
1012     case TSMUX_ST_PS_AUDIO_DTS:
1013       /* FIXME */
1014       break;
1015     case TSMUX_ST_PS_AUDIO_LPCM:
1016       /* FIXME */
1017       break;
1018     case TSMUX_ST_PS_TELETEXT:
1019       /* FIXME empty descriptor for now;
1020        * should be provided by upstream in event or so ? */
1021       descriptor =
1022           gst_mpegts_descriptor_from_custom (GST_MTS_DESC_DVB_TELETEXT, 0, 1);
1023
1024       g_ptr_array_add (pmt_stream->descriptors, descriptor);
1025       break;
1026     case TSMUX_ST_PS_DVB_SUBPICTURE:
1027       /* falltrough ...
1028        * that should never happen anyway as
1029        * dvb subtitles are private data */
1030     case TSMUX_ST_PRIVATE_DATA:
1031       if (stream->is_dvb_sub) {
1032         GST_DEBUG ("Stream language %s", stream->language);
1033         /* Simple DVB subtitles with no monitor aspect ratio critical
1034            FIXME, how do we make it settable? */
1035         /* Default composition page ID */
1036         /* Default ancillary_page_id */
1037         descriptor =
1038             gst_mpegts_descriptor_from_dvb_subtitling (stream->language, 0x10,
1039             0x0001, 0x0152);
1040
1041         g_ptr_array_add (pmt_stream->descriptors, descriptor);
1042         break;
1043       }
1044       if (stream->is_opus) {
1045         descriptor = gst_mpegts_descriptor_from_registration ("Opus", NULL, 0);
1046         g_ptr_array_add (pmt_stream->descriptors, descriptor);
1047
1048         descriptor =
1049             gst_mpegts_descriptor_from_custom_with_extension
1050             (GST_MTS_DESC_DVB_EXTENSION, 0x80,
1051             &stream->opus_channel_config_code, 1);
1052
1053         g_ptr_array_add (pmt_stream->descriptors, descriptor);
1054       }
1055       if (stream->is_meta) {
1056         descriptor = gst_mpegts_descriptor_from_registration ("KLVA", NULL, 0);
1057         GST_DEBUG ("adding KLVA registration descriptor");
1058         g_ptr_array_add (pmt_stream->descriptors, descriptor);
1059       }
1060     default:
1061       break;
1062   }
1063 }
1064
1065 /**
1066  * tsmux_stream_get_es_descrs:
1067  * @stream: a #TsMuxStream
1068  * @buf: a buffer to hold the ES descriptor
1069  * @len: the length used in @buf
1070  *
1071  * Write an Elementary Stream Descriptor for @stream into @buf. the number of
1072  * bytes consumed in @buf will be updated in @len.
1073  *
1074  * @buf and @len must be at least #TSMUX_MIN_ES_DESC_LEN.
1075  */
1076 void
1077 tsmux_stream_get_es_descrs (TsMuxStream * stream,
1078     GstMpegtsPMTStream * pmt_stream)
1079 {
1080   g_return_if_fail (stream->get_es_descrs != NULL);
1081
1082   stream->get_es_descrs (stream, pmt_stream, stream->get_es_descrs_data);
1083 }
1084
1085 /**
1086  * tsmux_stream_pcr_ref:
1087  * @stream: a #TsMuxStream
1088  *
1089  * Mark the stream as being used as the PCR for some program.
1090  */
1091 void
1092 tsmux_stream_pcr_ref (TsMuxStream * stream)
1093 {
1094   g_return_if_fail (stream != NULL);
1095
1096   stream->pcr_ref++;
1097 }
1098
1099 /**
1100  * tsmux_stream_pcr_unref:
1101  * @stream: a #TsMuxStream
1102  *
1103  * Mark the stream as no longer being used as the PCR for some program.
1104  */
1105 void
1106 tsmux_stream_pcr_unref (TsMuxStream * stream)
1107 {
1108   g_return_if_fail (stream != NULL);
1109
1110   stream->pcr_ref--;
1111 }
1112
1113 /**
1114  * tsmux_stream_is_pcr:
1115  * @stream: a #TsMuxStream
1116  *
1117  * Check if @stream is used as the PCR for some program.
1118  *
1119  * Returns: TRUE if the stream is in use as the PCR for some program.
1120  */
1121 gboolean
1122 tsmux_stream_is_pcr (TsMuxStream * stream)
1123 {
1124   return stream->pcr_ref != 0;
1125 }
1126
1127 /**
1128  * tsmux_stream_get_pts:
1129  * @stream: a #TsMuxStream
1130  *
1131  * Return the PTS of the last buffer that has had bytes written and
1132  * which _had_ a PTS in @stream.
1133  *
1134  * Returns: the PTS of the last buffer in @stream.
1135  */
1136 gint64
1137 tsmux_stream_get_pts (TsMuxStream * stream)
1138 {
1139   g_return_val_if_fail (stream != NULL, GST_CLOCK_STIME_NONE);
1140
1141   return stream->last_pts;
1142 }
1143
1144 /**
1145  * tsmux_stream_get_dts:
1146  * @stream: a #TsMuxStream
1147  *
1148  * Return the DTS of the last buffer that has had bytes written and
1149  * which _had_ a DTS in @stream.
1150  *
1151  * Returns: the DTS of the last buffer in @stream.
1152  */
1153 gint64
1154 tsmux_stream_get_dts (TsMuxStream * stream)
1155 {
1156   g_return_val_if_fail (stream != NULL, GST_CLOCK_STIME_NONE);
1157
1158   return stream->last_dts;
1159 }