3 * Copyright (C) 2009 Zaheer Abbas Merali
5 * Copyright (C) 2011, Hewlett-Packard Development Company, L.P.
6 * Author: Youness Alaoui <youness.alaoui@collabora.co.uk>, Collabora Ltd.
7 * Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd.
8 * Author: Edward Hervey <bilboed@bilboed.com>, Collabora Ltd.
11 * Zaheer Abbas Merali <zaheerabbas at merali dot org>
12 * Edward Hervey <edward.hervey@collabora.co.uk>
14 * This library is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU Library General Public
16 * License as published by the Free Software Foundation; either
17 * version 2 of the License, or (at your option) any later version.
19 * This library is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * Library General Public License for more details.
24 * You should have received a copy of the GNU Library General Public
25 * License along with this library; if not, write to the
26 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
27 * Boston, MA 02110-1301, USA.
38 #include <gst/tag/tag.h>
40 #include "mpegtsbase.h"
42 #include "gstmpegdesc.h"
43 #include "gstmpegdefs.h"
44 #include "mpegtspacketizer.h"
50 * See TODO for explanations on improvements needed
53 /* latency in mseconds */
54 #define TS_LATENCY 700
56 #define TABLE_ID_UNSET 0xFF
58 #define CONTINUITY_UNSET 255
59 #define MAX_CONTINUITY 15
61 #define PCR_WRAP_SIZE_128KBPS (((gint64)1490)*(1024*1024))
62 /* small PCR for wrap detection */
63 #define PCR_SMALL 17775000
64 /* maximal PCR time */
65 #define PCR_MAX_VALUE (((((guint64)1)<<33) * 300) + 298)
66 #define PTS_DTS_MAX_VALUE (((guint64)1) << 33)
68 /* Seeking/Scanning related variables */
70 /* seek to SEEK_TIMESTAMP_OFFSET before the desired offset and search then
71 * either accurately or for the next timestamp
73 #define SEEK_TIMESTAMP_OFFSET (500 * GST_MSECOND)
75 #define SEGMENT_FORMAT "[format:%s, rate:%f, start:%" \
76 GST_TIME_FORMAT", stop:%"GST_TIME_FORMAT", time:%"GST_TIME_FORMAT \
77 ", base:%"GST_TIME_FORMAT", position:%"GST_TIME_FORMAT \
78 ", duration:%"GST_TIME_FORMAT"]"
80 #define SEGMENT_ARGS(a) gst_format_get_name((a).format), (a).rate, \
81 GST_TIME_ARGS((a).start), GST_TIME_ARGS((a).stop), \
82 GST_TIME_ARGS((a).time), GST_TIME_ARGS((a).base), \
83 GST_TIME_ARGS((a).position), GST_TIME_ARGS((a).duration)
86 GST_DEBUG_CATEGORY_STATIC (ts_demux_debug);
87 #define GST_CAT_DEFAULT ts_demux_debug
89 #define ABSDIFF(a,b) (((a) > (b)) ? ((a) - (b)) : ((b) - (a)))
91 static GQuark QUARK_TSDEMUX;
92 static GQuark QUARK_PID;
93 static GQuark QUARK_PCR;
94 static GQuark QUARK_OPCR;
95 static GQuark QUARK_PTS;
96 static GQuark QUARK_DTS;
97 static GQuark QUARK_OFFSET;
101 PENDING_PACKET_EMPTY = 0, /* No pending packet/buffer
102 * Push incoming buffers to the array */
103 PENDING_PACKET_HEADER, /* PES header needs to be parsed
104 * Push incoming buffers to the array */
105 PENDING_PACKET_BUFFER, /* Currently filling up output buffer
106 * Push incoming buffers to the bufferlist */
107 PENDING_PACKET_DISCONT /* Discontinuity in incoming packets
108 * Drop all incoming buffers */
109 } PendingPacketState;
111 typedef struct _TSDemuxStream TSDemuxStream;
113 struct _TSDemuxStream
115 MpegTSBaseStream stream;
118 /* Whether the pad was added or not */
121 /* the return of the latest push */
122 GstFlowReturn flow_return;
125 PendingPacketState state;
127 /* Data to push (allocated) */
130 /* Size of data to push (if known) */
133 /* Size of currently queued data */
135 guint allocated_size;
137 /* Current PTS/DTS for this stream */
140 /* Raw value of current PTS/DTS */
143 /* PTS/DTS with rollover fixed */
146 /* Number of rollover seen for PTS/DTS (default:0) */
147 guint nb_pts_rollover;
148 guint nb_dts_rollover;
150 /* Whether this stream needs to send a newsegment */
151 gboolean need_newsegment;
155 gint continuity_counter;
161 "mpegversion = (int) { 1, 2, 4 }, " \
162 "systemstream = (boolean) FALSE; " \
163 "video/x-h264,stream-format=(string)byte-stream," \
164 "alignment=(string)nal;" \
167 "wmvversion = (int) 3, " \
168 "format = (string) WVC1" \
174 "mpegversion = (int) 1;" \
176 "mpegversion = (int) 2, " \
177 "stream-format = (string) adts; " \
179 "mpegversion = (int) 4, " \
180 "stream-format = (string) loas; " \
182 "width = (int) { 16, 20, 24 }, " \
183 "rate = (int) { 48000, 96000 }, " \
184 "channels = (int) [ 1, 8 ], " \
185 "dynamic_range = (int) [ 0, 255 ], " \
186 "emphasis = (boolean) { FALSE, TRUE }, " \
187 "mute = (boolean) { FALSE, TRUE }; " \
188 "audio/x-ac3; audio/x-eac3;" \
190 "audio/x-private-ts-lpcm" \
193 /* Can also use the subpicture pads for text subtitles? */
194 #define SUBPICTURE_CAPS \
195 GST_STATIC_CAPS ("subpicture/x-pgs; subpicture/x-dvd")
197 static GstStaticPadTemplate video_template =
198 GST_STATIC_PAD_TEMPLATE ("video_%04x", GST_PAD_SRC,
202 static GstStaticPadTemplate audio_template =
203 GST_STATIC_PAD_TEMPLATE ("audio_%04x",
208 static GstStaticPadTemplate subpicture_template =
209 GST_STATIC_PAD_TEMPLATE ("subpicture_%04x",
214 static GstStaticPadTemplate private_template =
215 GST_STATIC_PAD_TEMPLATE ("private_%04x",
218 GST_STATIC_CAPS_ANY);
231 /* mpegtsbase methods */
233 gst_ts_demux_program_started (MpegTSBase * base, MpegTSBaseProgram * program);
235 gst_ts_demux_program_stopped (MpegTSBase * base, MpegTSBaseProgram * program);
236 static void gst_ts_demux_reset (MpegTSBase * base);
238 gst_ts_demux_push (MpegTSBase * base, MpegTSPacketizerPacket * packet,
239 MpegTSPacketizerSection * section);
240 static void gst_ts_demux_flush (MpegTSBase * base);
242 gst_ts_demux_stream_added (MpegTSBase * base, MpegTSBaseStream * stream,
243 MpegTSBaseProgram * program);
245 gst_ts_demux_stream_removed (MpegTSBase * base, MpegTSBaseStream * stream);
246 static GstFlowReturn gst_ts_demux_do_seek (MpegTSBase * base, GstEvent * event);
247 static void gst_ts_demux_set_property (GObject * object, guint prop_id,
248 const GValue * value, GParamSpec * pspec);
249 static void gst_ts_demux_get_property (GObject * object, guint prop_id,
250 GValue * value, GParamSpec * pspec);
251 static void gst_ts_demux_flush_streams (GstTSDemux * tsdemux);
253 gst_ts_demux_push_pending_data (GstTSDemux * demux, TSDemuxStream * stream);
254 static void gst_ts_demux_stream_flush (TSDemuxStream * stream);
256 static gboolean push_event (MpegTSBase * base, GstEvent * event);
261 QUARK_TSDEMUX = g_quark_from_string ("tsdemux");
262 QUARK_PID = g_quark_from_string ("pid");
263 QUARK_PCR = g_quark_from_string ("pcr");
264 QUARK_OPCR = g_quark_from_string ("opcr");
265 QUARK_PTS = g_quark_from_string ("pts");
266 QUARK_DTS = g_quark_from_string ("dts");
267 QUARK_OFFSET = g_quark_from_string ("offset");
270 #define gst_ts_demux_parent_class parent_class
271 G_DEFINE_TYPE_WITH_CODE (GstTSDemux, gst_ts_demux, GST_TYPE_MPEGTS_BASE,
275 gst_ts_demux_class_init (GstTSDemuxClass * klass)
277 GObjectClass *gobject_class;
278 GstElementClass *element_class;
279 MpegTSBaseClass *ts_class;
281 gobject_class = G_OBJECT_CLASS (klass);
282 gobject_class->set_property = gst_ts_demux_set_property;
283 gobject_class->get_property = gst_ts_demux_get_property;
285 g_object_class_install_property (gobject_class, PROP_PROGRAM_NUMBER,
286 g_param_spec_int ("program-number", "Program number",
287 "Program Number to demux for (-1 to ignore)", -1, G_MAXINT,
288 -1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
290 g_object_class_install_property (gobject_class, PROP_EMIT_STATS,
291 g_param_spec_boolean ("emit-stats", "Emit statistics",
292 "Emit messages for every pcr/opcr/pts/dts", FALSE,
293 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
295 element_class = GST_ELEMENT_CLASS (klass);
296 gst_element_class_add_pad_template (element_class,
297 gst_static_pad_template_get (&video_template));
298 gst_element_class_add_pad_template (element_class,
299 gst_static_pad_template_get (&audio_template));
300 gst_element_class_add_pad_template (element_class,
301 gst_static_pad_template_get (&subpicture_template));
302 gst_element_class_add_pad_template (element_class,
303 gst_static_pad_template_get (&private_template));
305 gst_element_class_set_static_metadata (element_class,
306 "MPEG transport stream demuxer",
308 "Demuxes MPEG2 transport streams",
309 "Zaheer Abbas Merali <zaheerabbas at merali dot org>\n"
310 "Edward Hervey <edward.hervey@collabora.co.uk>");
312 ts_class = GST_MPEGTS_BASE_CLASS (klass);
313 ts_class->reset = GST_DEBUG_FUNCPTR (gst_ts_demux_reset);
314 ts_class->push = GST_DEBUG_FUNCPTR (gst_ts_demux_push);
315 ts_class->push_event = GST_DEBUG_FUNCPTR (push_event);
316 ts_class->program_started = GST_DEBUG_FUNCPTR (gst_ts_demux_program_started);
317 ts_class->program_stopped = GST_DEBUG_FUNCPTR (gst_ts_demux_program_stopped);
318 ts_class->stream_added = gst_ts_demux_stream_added;
319 ts_class->stream_removed = gst_ts_demux_stream_removed;
320 ts_class->seek = GST_DEBUG_FUNCPTR (gst_ts_demux_do_seek);
321 ts_class->flush = GST_DEBUG_FUNCPTR (gst_ts_demux_flush);
325 gst_ts_demux_reset (MpegTSBase * base)
327 GstTSDemux *demux = (GstTSDemux *) base;
329 demux->program_number = -1;
330 demux->calculate_update_segment = FALSE;
332 gst_segment_init (&demux->segment, GST_FORMAT_UNDEFINED);
333 if (demux->segment_event) {
334 gst_event_unref (demux->segment_event);
335 demux->segment_event = NULL;
338 if (demux->update_segment) {
339 gst_event_unref (demux->update_segment);
340 demux->update_segment = NULL;
345 gst_ts_demux_init (GstTSDemux * demux)
347 GST_MPEGTS_BASE (demux)->stream_size = sizeof (TSDemuxStream);
349 gst_ts_demux_reset ((MpegTSBase *) demux);
354 gst_ts_demux_set_property (GObject * object, guint prop_id,
355 const GValue * value, GParamSpec * pspec)
357 GstTSDemux *demux = GST_TS_DEMUX (object);
360 case PROP_PROGRAM_NUMBER:
361 /* FIXME: do something if program is switched as opposed to set at
363 demux->program_number = g_value_get_int (value);
365 case PROP_EMIT_STATS:
366 demux->emit_statistics = g_value_get_boolean (value);
369 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
374 gst_ts_demux_get_property (GObject * object, guint prop_id,
375 GValue * value, GParamSpec * pspec)
377 GstTSDemux *demux = GST_TS_DEMUX (object);
380 case PROP_PROGRAM_NUMBER:
381 g_value_set_int (value, demux->program_number);
383 case PROP_EMIT_STATS:
384 g_value_set_boolean (value, demux->emit_statistics);
387 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
392 gst_ts_demux_srcpad_query (GstPad * pad, GstObject * parent, GstQuery * query)
399 demux = GST_TS_DEMUX (parent);
400 base = GST_MPEGTS_BASE (demux);
402 switch (GST_QUERY_TYPE (query)) {
403 case GST_QUERY_DURATION:
405 GST_DEBUG ("query duration");
406 gst_query_parse_duration (query, &format, NULL);
407 if (format == GST_FORMAT_TIME) {
408 if (!gst_pad_peer_query (base->sinkpad, query)) {
411 format = GST_FORMAT_BYTES;
412 if (!gst_pad_peer_query_duration (base->sinkpad, format, &val))
416 mpegts_packetizer_offset_to_ts (base->packetizer, val,
417 demux->program->pcr_pid);
418 if (GST_CLOCK_TIME_IS_VALID (dur))
419 gst_query_set_duration (query, GST_FORMAT_TIME, dur);
425 GST_DEBUG_OBJECT (demux, "only query duration on TIME is supported");
430 case GST_QUERY_LATENCY:
432 GST_DEBUG ("query latency");
433 res = gst_pad_peer_query (base->sinkpad, query);
434 if (res && base->upstream_live) {
435 GstClockTime min_lat, max_lat;
438 /* According to H.222.0
439 Annex D.0.3 (System Time Clock recovery in the decoder)
440 and D.0.2 (Audio and video presentation synchronization)
442 We can end up with an interval of up to 700ms between valid
443 PCR/SCR. We therefore allow a latency of 700ms for that.
445 gst_query_parse_latency (query, &live, &min_lat, &max_lat);
447 min_lat += 700 * GST_MSECOND;
449 max_lat += 700 * GST_MSECOND;
450 gst_query_set_latency (query, live, min_lat, max_lat);
454 case GST_QUERY_SEEKING:
456 GST_DEBUG ("query seeking");
457 gst_query_parse_seeking (query, &format, NULL, NULL, NULL);
458 if (format == GST_FORMAT_TIME) {
459 gboolean seekable = FALSE;
461 if (gst_pad_peer_query (base->sinkpad, query))
462 gst_query_parse_seeking (query, NULL, &seekable, NULL, NULL);
464 /* If upstream is not seekable in TIME format we use
465 * our own values here */
467 gst_query_set_seeking (query, GST_FORMAT_TIME,
468 demux->parent.mode != BASE_MODE_PUSHING, 0,
469 demux->segment.duration);
471 GST_DEBUG_OBJECT (demux, "only TIME is supported for query seeking");
477 res = gst_pad_query_default (pad, parent, query);
485 gst_ts_demux_do_seek (MpegTSBase * base, GstEvent * event)
487 GstTSDemux *demux = (GstTSDemux *) base;
488 GstFlowReturn res = GST_FLOW_ERROR;
492 GstSeekType start_type, stop_type;
494 GstSegment seeksegment;
496 guint64 start_offset;
498 gst_event_parse_seek (event, &rate, &format, &flags, &start_type, &start,
501 if (format != GST_FORMAT_TIME) {
505 GST_DEBUG ("seek event, rate: %f start: %" GST_TIME_FORMAT
506 " stop: %" GST_TIME_FORMAT, rate, GST_TIME_ARGS (start),
507 GST_TIME_ARGS (stop));
509 if (flags & (GST_SEEK_FLAG_SEGMENT | GST_SEEK_FLAG_SKIP)) {
510 GST_WARNING ("seek flags 0x%x are not supported", (int) flags);
514 /* copy segment, we need this because we still need the old
515 * segment when we close the current segment. */
516 memcpy (&seeksegment, &demux->segment, sizeof (GstSegment));
517 if (demux->segment_event) {
518 gst_event_unref (demux->segment_event);
519 demux->segment_event = NULL;
521 /* configure the segment with the seek variables */
522 GST_DEBUG_OBJECT (demux, "configuring seek");
523 GST_DEBUG ("seeksegment before set_seek " SEGMENT_FORMAT,
524 SEGMENT_ARGS (seeksegment));
526 gst_segment_do_seek (&seeksegment, rate, format, flags, start_type, start,
527 stop_type, stop, &update);
529 GST_DEBUG ("seeksegment after set_seek " SEGMENT_FORMAT,
530 SEGMENT_ARGS (seeksegment));
532 /* Convert start/stop to offset */
534 mpegts_packetizer_ts_to_offset (base->packetizer, MAX (0,
535 start - SEEK_TIMESTAMP_OFFSET), demux->program->pcr_pid);
537 if (G_UNLIKELY (start_offset == -1)) {
538 GST_WARNING ("Couldn't convert start position to an offset");
543 base->seek_offset = start_offset;
546 /* commit the new segment */
547 memcpy (&demux->segment, &seeksegment, sizeof (GstSegment));
549 if (demux->segment.flags & GST_SEEK_FLAG_SEGMENT) {
550 gst_element_post_message (GST_ELEMENT_CAST (demux),
551 gst_message_new_segment_start (GST_OBJECT_CAST (demux),
552 demux->segment.format, demux->segment.stop));
560 gst_ts_demux_srcpad_event (GstPad * pad, GstObject * parent, GstEvent * event)
563 GstTSDemux *demux = GST_TS_DEMUX (parent);
565 GST_DEBUG_OBJECT (pad, "Got event %s",
566 gst_event_type_get_name (GST_EVENT_TYPE (event)));
568 switch (GST_EVENT_TYPE (event)) {
570 res = mpegts_base_handle_seek_event ((MpegTSBase *) demux, pad, event);
572 GST_WARNING ("seeking failed");
573 gst_event_unref (event);
576 res = gst_pad_event_default (pad, parent, event);
583 push_event (MpegTSBase * base, GstEvent * event)
585 GstTSDemux *demux = (GstTSDemux *) base;
588 if (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT) {
589 GST_DEBUG_OBJECT (base, "Ignoring segment event (recreated later)");
590 gst_event_unref (event);
594 if (G_UNLIKELY (demux->program == NULL)) {
595 gst_event_unref (event);
599 for (tmp = demux->program->stream_list; tmp; tmp = tmp->next) {
600 TSDemuxStream *stream = (TSDemuxStream *) tmp->data;
602 gst_event_ref (event);
603 gst_pad_push_event (stream->pad, event);
607 gst_event_unref (event);
613 tsdemux_combine_flows (GstTSDemux * demux, TSDemuxStream * stream,
618 /* Store the value */
619 stream->flow_return = ret;
621 /* any other error that is not-linked can be returned right away */
622 if (ret != GST_FLOW_NOT_LINKED)
625 /* Only return NOT_LINKED if all other pads returned NOT_LINKED */
626 for (tmp = demux->program->stream_list; tmp; tmp = tmp->next) {
627 stream = (TSDemuxStream *) tmp->data;
629 ret = stream->flow_return;
630 /* some other return value (must be SUCCESS but we can return
631 * other values as well) */
632 if (ret != GST_FLOW_NOT_LINKED)
635 /* if we get here, all other pads were unlinked and we return
644 gst_ts_demux_create_tags (TSDemuxStream * stream)
649 desc = mpegts_get_descriptor_from_stream ((MpegTSBaseStream *) stream,
650 DESC_ISO_639_LANGUAGE);
653 desc = mpegts_get_descriptor_from_stream ((MpegTSBaseStream *) stream,
654 DESC_DVB_SUBTITLING);
658 if (!stream->taglist)
659 stream->taglist = gst_tag_list_new_empty ();
661 for (i = 0; i < DESC_ISO_639_LANGUAGE_codes_n (desc); i++) {
666 language_n = (gchar *)
667 DESC_ISO_639_LANGUAGE_language_code_nth (desc, i);
669 /* Language codes should be 3 character long, we allow
670 * a bit more flexibility by allowing 2 characters. */
671 if (!language_n[0] || !language_n[1])
674 GST_LOG ("Add language code for stream: %s", language_n);
676 lang_code[0] = language_n[0];
677 lang_code[1] = language_n[1];
678 lang_code[2] = language_n[2];
681 /* descriptor contains ISO 639-2 code, we want the ISO 639-1 code */
682 lc = gst_tag_get_language_code (lang_code);
683 gst_tag_list_add (stream->taglist, GST_TAG_MERGE_REPLACE,
684 GST_TAG_LANGUAGE_CODE, (lc) ? lc : lang_code, NULL);
692 create_pad_for_stream (MpegTSBase * base, MpegTSBaseStream * bstream,
693 MpegTSBaseProgram * program)
695 TSDemuxStream *stream = (TSDemuxStream *) bstream;
697 GstCaps *caps = NULL;
698 GstPadTemplate *template = NULL;
702 gst_ts_demux_create_tags (stream);
704 GST_LOG ("Attempting to create pad for stream 0x%04x with stream_type %d",
705 bstream->pid, bstream->stream_type);
707 /* First handle BluRay-specific stream types since there is some overlap
708 * between BluRay and non-BluRay streay type identifiers */
709 desc = mpegts_get_descriptor_from_program (program, DESC_REGISTRATION);
711 if (DESC_REGISTRATION_format_identifier (desc) == DRF_ID_HDMV) {
712 switch (bstream->stream_type) {
713 case ST_BD_AUDIO_AC3:
717 /* ATSC ac3 audio descriptor */
719 mpegts_get_descriptor_from_stream ((MpegTSBaseStream *) stream,
720 DESC_AC3_AUDIO_STREAM);
721 if (ac3_desc && DESC_AC_AUDIO_STREAM_bsid (ac3_desc) != 16) {
722 GST_LOG ("ac3 audio");
723 template = gst_static_pad_template_get (&audio_template);
724 name = g_strdup_printf ("audio_%04x", bstream->pid);
725 caps = gst_caps_new_empty_simple ("audio/x-ac3");
729 template = gst_static_pad_template_get (&audio_template);
730 name = g_strdup_printf ("audio_%04x", bstream->pid);
731 caps = gst_caps_new_empty_simple ("audio/x-eac3");
735 case ST_BD_AUDIO_EAC3:
736 template = gst_static_pad_template_get (&audio_template);
737 name = g_strdup_printf ("audio_%04x", bstream->pid);
738 caps = gst_caps_new_empty_simple ("audio/x-eac3");
740 case ST_BD_AUDIO_AC3_TRUE_HD:
741 template = gst_static_pad_template_get (&audio_template);
742 name = g_strdup_printf ("audio_%04x", bstream->pid);
743 caps = gst_caps_new_empty_simple ("audio/x-true-hd");
745 case ST_BD_AUDIO_LPCM:
746 template = gst_static_pad_template_get (&audio_template);
747 name = g_strdup_printf ("audio_%04x", bstream->pid);
748 caps = gst_caps_new_empty_simple ("audio/x-private-ts-lpcm");
750 case ST_BD_PGS_SUBPICTURE:
751 template = gst_static_pad_template_get (&subpicture_template);
752 name = g_strdup_printf ("subpicture_%04x", bstream->pid);
753 caps = gst_caps_new_empty_simple ("subpicture/x-pgs");
759 if (template && name && caps)
762 /* Handle non-BluRay stream types */
763 switch (bstream->stream_type) {
766 case ST_PS_VIDEO_MPEG2_DCII:
767 GST_LOG ("mpeg video");
768 template = gst_static_pad_template_get (&video_template);
769 name = g_strdup_printf ("video_%04x", bstream->pid);
770 caps = gst_caps_new_simple ("video/mpeg",
771 "mpegversion", G_TYPE_INT,
772 bstream->stream_type == ST_VIDEO_MPEG1 ? 1 : 2, "systemstream",
773 G_TYPE_BOOLEAN, FALSE, NULL);
778 GST_LOG ("mpeg audio");
779 template = gst_static_pad_template_get (&audio_template);
780 name = g_strdup_printf ("audio_%04x", bstream->pid);
782 gst_caps_new_simple ("audio/mpeg", "mpegversion", G_TYPE_INT, 1,
785 case ST_PRIVATE_DATA:
786 GST_LOG ("private data");
787 desc = mpegts_get_descriptor_from_stream ((MpegTSBaseStream *) stream,
790 GST_LOG ("ac3 audio");
791 template = gst_static_pad_template_get (&audio_template);
792 name = g_strdup_printf ("audio_%04x", bstream->pid);
793 caps = gst_caps_new_empty_simple ("audio/x-ac3");
798 desc = mpegts_get_descriptor_from_stream ((MpegTSBaseStream *) stream,
799 DESC_DVB_ENHANCED_AC3);
801 GST_LOG ("ac3 audio");
802 template = gst_static_pad_template_get (&audio_template);
803 name = g_strdup_printf ("audio_%04x", bstream->pid);
804 caps = gst_caps_new_empty_simple ("audio/x-eac3");
808 desc = mpegts_get_descriptor_from_stream ((MpegTSBaseStream *) stream,
811 GST_LOG ("teletext");
812 template = gst_static_pad_template_get (&private_template);
813 name = g_strdup_printf ("private_%04x", bstream->pid);
814 caps = gst_caps_new_empty_simple ("private/teletext");
819 mpegts_get_descriptor_from_stream ((MpegTSBaseStream *) stream,
820 DESC_DVB_SUBTITLING);
822 GST_LOG ("subtitling");
823 template = gst_static_pad_template_get (&private_template);
824 name = g_strdup_printf ("private_%04x", bstream->pid);
825 caps = gst_caps_new_empty_simple ("subpicture/x-dvb");
830 desc = mpegts_get_descriptor_from_stream ((MpegTSBaseStream *) stream,
833 switch (DESC_REGISTRATION_format_identifier (desc)) {
837 /* SMPTE registered DTS */
838 GST_LOG ("subtitling");
839 template = gst_static_pad_template_get (&private_template);
840 name = g_strdup_printf ("private_%04x", bstream->pid);
841 caps = gst_caps_new_empty_simple ("audio/x-dts");
844 template = gst_static_pad_template_get (&audio_template);
845 name = g_strdup_printf ("audio_%04x", bstream->pid);
846 caps = gst_caps_new_empty_simple ("audio/x-smpte-302m");
854 /* hack for itv hd (sid 10510, video pid 3401 */
855 if (program->program_number == 10510 && bstream->pid == 3401) {
856 template = gst_static_pad_template_get (&video_template);
857 name = g_strdup_printf ("video_%04x", bstream->pid);
858 caps = gst_caps_new_simple ("video/x-h264",
859 "stream-format", G_TYPE_STRING, "byte-stream",
860 "alignment", G_TYPE_STRING, "nal", NULL);
864 /* We don't expose those streams since they're only helper streams */
865 /* template = gst_static_pad_template_get (&private_template); */
866 /* name = g_strdup_printf ("private_%04x", bstream->pid); */
867 /* caps = gst_caps_new_simple ("hdv/aux-v", NULL); */
870 /* We don't expose those streams since they're only helper streams */
871 /* template = gst_static_pad_template_get (&private_template); */
872 /* name = g_strdup_printf ("private_%04x", bstream->pid); */
873 /* caps = gst_caps_new_simple ("hdv/aux-a", NULL); */
875 case ST_PRIVATE_SECTIONS:
882 MPEGTS_BIT_UNSET (base->is_pes, bstream->pid);
884 case ST_AUDIO_AAC_ADTS:
885 template = gst_static_pad_template_get (&audio_template);
886 name = g_strdup_printf ("audio_%04x", bstream->pid);
887 caps = gst_caps_new_simple ("audio/mpeg",
888 "mpegversion", G_TYPE_INT, 2,
889 "stream-format", G_TYPE_STRING, "adts", NULL);
891 case ST_AUDIO_AAC_LATM:
892 template = gst_static_pad_template_get (&audio_template);
893 name = g_strdup_printf ("audio_%04x", bstream->pid);
894 caps = gst_caps_new_simple ("audio/mpeg",
895 "mpegversion", G_TYPE_INT, 4,
896 "stream-format", G_TYPE_STRING, "loas", NULL);
899 template = gst_static_pad_template_get (&video_template);
900 name = g_strdup_printf ("video_%04x", bstream->pid);
901 caps = gst_caps_new_simple ("video/mpeg",
902 "mpegversion", G_TYPE_INT, 4,
903 "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
906 template = gst_static_pad_template_get (&video_template);
907 name = g_strdup_printf ("video_%04x", bstream->pid);
908 caps = gst_caps_new_simple ("video/x-h264",
909 "stream-format", G_TYPE_STRING, "byte-stream",
910 "alignment", G_TYPE_STRING, "nal", NULL);
914 mpegts_get_descriptor_from_stream ((MpegTSBaseStream *) stream,
917 if (DESC_LENGTH (desc) >= 4) {
918 if (DESC_REGISTRATION_format_identifier (desc) == 0x64726163) {
921 template = gst_static_pad_template_get (&video_template);
922 name = g_strdup_printf ("video_%04x", bstream->pid);
923 caps = gst_caps_new_empty_simple ("video/x-dirac");
929 case ST_PRIVATE_EA: /* Try to detect a VC1 stream */
931 gboolean is_vc1 = FALSE;
933 mpegts_get_descriptor_from_stream ((MpegTSBaseStream *) stream,
936 if (DESC_LENGTH (desc) >= 4) {
937 if (DESC_REGISTRATION_format_identifier (desc) == DRF_ID_VC1) {
944 GST_WARNING ("0xea private stream type found but no descriptor "
945 "for VC1. Assuming plain VC1.");
948 template = gst_static_pad_template_get (&video_template);
949 name = g_strdup_printf ("video_%04x", bstream->pid);
950 caps = gst_caps_new_simple ("video/x-wmv",
951 "wmvversion", G_TYPE_INT, 3, "format", G_TYPE_STRING, "WVC1", NULL);
955 case ST_PS_AUDIO_AC3:
956 /* DVB_ENHANCED_AC3 */
957 desc = mpegts_get_descriptor_from_stream ((MpegTSBaseStream *) stream,
958 DESC_DVB_ENHANCED_AC3);
960 template = gst_static_pad_template_get (&audio_template);
961 name = g_strdup_printf ("audio_%04x", bstream->pid);
962 caps = gst_caps_new_empty_simple ("audio/x-eac3");
969 mpegts_get_descriptor_from_stream ((MpegTSBaseStream *) stream,
972 GST_WARNING ("AC3 stream type found but no corresponding "
973 "descriptor to differentiate between AC3 and EAC3. "
974 "Assuming plain AC3.");
977 template = gst_static_pad_template_get (&audio_template);
978 name = g_strdup_printf ("audio_%04x", bstream->pid);
979 caps = gst_caps_new_empty_simple ("audio/x-ac3");
981 case ST_PS_AUDIO_DTS:
982 template = gst_static_pad_template_get (&audio_template);
983 name = g_strdup_printf ("audio_%04x", bstream->pid);
984 caps = gst_caps_new_empty_simple ("audio/x-dts");
986 case ST_PS_AUDIO_LPCM:
987 template = gst_static_pad_template_get (&audio_template);
988 name = g_strdup_printf ("audio_%04x", bstream->pid);
989 caps = gst_caps_new_empty_simple ("audio/x-lpcm");
991 case ST_PS_DVD_SUBPICTURE:
992 template = gst_static_pad_template_get (&subpicture_template);
993 name = g_strdup_printf ("subpicture_%04x", bstream->pid);
994 caps = gst_caps_new_empty_simple ("subpicture/x-dvd");
997 GST_WARNING ("Non-media stream (stream_type:0x%x). Not creating pad",
998 bstream->stream_type);
1003 if (template && name && caps) {
1006 GST_LOG ("stream:%p creating pad with name %s and caps %s", stream, name,
1007 gst_caps_to_string (caps));
1008 pad = gst_pad_new_from_template (template, name);
1009 gst_pad_set_active (pad, TRUE);
1010 gst_pad_use_fixed_caps (pad);
1012 gst_pad_create_stream_id_printf (pad, GST_ELEMENT_CAST (base), "%08x",
1014 gst_pad_push_event (pad, gst_event_new_stream_start (stream_id));
1016 gst_pad_set_caps (pad, caps);
1017 gst_pad_set_query_function (pad, gst_ts_demux_srcpad_query);
1018 gst_pad_set_event_function (pad, gst_ts_demux_srcpad_event);
1024 gst_object_unref (template);
1026 gst_caps_unref (caps);
1032 gst_ts_demux_stream_added (MpegTSBase * base, MpegTSBaseStream * bstream,
1033 MpegTSBaseProgram * program)
1035 TSDemuxStream *stream = (TSDemuxStream *) bstream;
1038 /* Create the pad */
1039 if (bstream->stream_type != 0xff)
1040 stream->pad = create_pad_for_stream (base, bstream, program);
1041 stream->active = FALSE;
1043 stream->need_newsegment = TRUE;
1044 stream->pts = GST_CLOCK_TIME_NONE;
1045 stream->dts = GST_CLOCK_TIME_NONE;
1046 stream->raw_pts = 0;
1047 stream->raw_dts = 0;
1048 stream->fixed_pts = 0;
1049 stream->fixed_dts = 0;
1050 stream->nb_pts_rollover = 0;
1051 stream->nb_dts_rollover = 0;
1052 stream->continuity_counter = CONTINUITY_UNSET;
1054 stream->flow_return = GST_FLOW_OK;
1058 gst_ts_demux_stream_removed (MpegTSBase * base, MpegTSBaseStream * bstream)
1060 TSDemuxStream *stream = (TSDemuxStream *) bstream;
1063 if (stream->active && gst_pad_is_active (stream->pad)) {
1064 /* Flush out all data */
1065 GST_DEBUG_OBJECT (stream->pad, "Flushing out pending data");
1066 gst_ts_demux_push_pending_data ((GstTSDemux *) base, stream);
1068 GST_DEBUG_OBJECT (stream->pad, "Pushing out EOS");
1069 gst_pad_push_event (stream->pad, gst_event_new_eos ());
1070 GST_DEBUG_OBJECT (stream->pad, "Deactivating and removing pad");
1071 gst_pad_set_active (stream->pad, FALSE);
1072 gst_element_remove_pad (GST_ELEMENT_CAST (base), stream->pad);
1073 stream->active = FALSE;
1077 gst_ts_demux_stream_flush (stream);
1078 stream->flow_return = GST_FLOW_NOT_LINKED;
1082 activate_pad_for_stream (GstTSDemux * tsdemux, TSDemuxStream * stream)
1085 gboolean alldone = TRUE;
1088 GST_DEBUG_OBJECT (tsdemux, "Activating pad %s:%s for stream %p",
1089 GST_DEBUG_PAD_NAME (stream->pad), stream);
1090 gst_element_add_pad ((GstElement *) tsdemux, stream->pad);
1091 stream->active = TRUE;
1092 GST_DEBUG_OBJECT (stream->pad, "done adding pad");
1094 /* Check if all pads were activated, and if so emit no-more-pads */
1095 for (tmp = tsdemux->program->stream_list; tmp; tmp = tmp->next) {
1096 stream = (TSDemuxStream *) tmp->data;
1097 if (stream->pad && !stream->active)
1101 GST_DEBUG_OBJECT (tsdemux, "All pads were activated, emit no-more-pads");
1102 gst_element_no_more_pads ((GstElement *) tsdemux);
1105 GST_WARNING_OBJECT (tsdemux,
1106 "stream %p (pid 0x%04x, type:0x%03x) has no pad", stream,
1107 ((MpegTSBaseStream *) stream)->pid,
1108 ((MpegTSBaseStream *) stream)->stream_type);
1112 gst_ts_demux_stream_flush (TSDemuxStream * stream)
1114 stream->pts = GST_CLOCK_TIME_NONE;
1116 GST_DEBUG ("flushing stream %p", stream);
1119 g_free (stream->data);
1120 stream->data = NULL;
1121 stream->state = PENDING_PACKET_EMPTY;
1122 stream->expected_size = 0;
1123 stream->allocated_size = 0;
1124 stream->current_size = 0;
1125 stream->need_newsegment = TRUE;
1126 stream->pts = GST_CLOCK_TIME_NONE;
1127 stream->dts = GST_CLOCK_TIME_NONE;
1128 stream->raw_pts = 0;
1129 stream->raw_dts = 0;
1130 stream->fixed_pts = 0;
1131 stream->fixed_dts = 0;
1132 stream->nb_pts_rollover = 0;
1133 stream->nb_dts_rollover = 0;
1134 if (stream->flow_return == GST_FLOW_FLUSHING) {
1135 stream->flow_return = GST_FLOW_OK;
1137 stream->continuity_counter = CONTINUITY_UNSET;
1141 gst_ts_demux_flush_streams (GstTSDemux * demux)
1143 g_list_foreach (demux->program->stream_list,
1144 (GFunc) gst_ts_demux_stream_flush, NULL);
1148 gst_ts_demux_program_started (MpegTSBase * base, MpegTSBaseProgram * program)
1150 GstTSDemux *demux = GST_TS_DEMUX (base);
1152 GST_DEBUG ("Current program %d, new program %d",
1153 demux->program_number, program->program_number);
1155 if (demux->program_number == -1 ||
1156 demux->program_number == program->program_number) {
1158 GST_LOG ("program %d started", program->program_number);
1159 demux->program_number = program->program_number;
1160 demux->program = program;
1162 /* If this is not the initial program, we need to calculate
1163 * an update newsegment */
1164 demux->calculate_update_segment = !program->initial_program;
1166 /* FIXME : When do we emit no_more_pads ? */
1171 gst_ts_demux_program_stopped (MpegTSBase * base, MpegTSBaseProgram * program)
1173 GstTSDemux *demux = GST_TS_DEMUX (base);
1175 if (demux->program == program) {
1176 demux->program = NULL;
1177 demux->program_number = -1;
1183 gst_ts_demux_record_pts (GstTSDemux * demux, TSDemuxStream * stream,
1184 guint64 pts, guint64 offset)
1186 MpegTSBaseStream *bs = (MpegTSBaseStream *) stream;
1189 stream->pts = GST_CLOCK_TIME_NONE;
1193 GST_LOG ("pid 0x%04x pts:%" G_GUINT64_FORMAT " at offset %"
1194 G_GUINT64_FORMAT, bs->pid, pts, offset);
1196 if (G_UNLIKELY (GST_CLOCK_TIME_IS_VALID (stream->pts) &&
1197 ABSDIFF (stream->raw_pts, pts) > 900000)) {
1198 /* Detect rollover if diff > 10s */
1199 GST_LOG ("Detected rollover (previous:%" G_GUINT64_FORMAT " new:%"
1200 G_GUINT64_FORMAT ")", stream->raw_pts, pts);
1201 if (pts < stream->raw_pts) {
1202 /* Forward rollover */
1203 GST_LOG ("Forward rollover, incrementing nb_pts_rollover");
1204 stream->nb_pts_rollover++;
1206 /* Reverse rollover */
1207 GST_LOG ("Reverse rollover, decrementing nb_pts_rollover");
1208 stream->nb_pts_rollover--;
1212 /* Compute PTS in GstClockTime */
1213 stream->raw_pts = pts;
1214 stream->fixed_pts = pts + stream->nb_pts_rollover * PTS_DTS_MAX_VALUE;
1215 stream->pts = MPEGTIME_TO_GSTTIME (stream->fixed_pts);
1217 GST_LOG ("pid 0x%04x Stored PTS %" G_GUINT64_FORMAT " (%" GST_TIME_FORMAT ")",
1218 bs->pid, stream->raw_pts, GST_TIME_ARGS (stream->pts));
1221 if (G_UNLIKELY (demux->emit_statistics)) {
1223 st = gst_structure_new_id_empty (QUARK_TSDEMUX);
1224 gst_structure_id_set (st,
1225 QUARK_PID, G_TYPE_UINT, bs->pid,
1226 QUARK_OFFSET, G_TYPE_UINT64, offset, QUARK_PTS, G_TYPE_UINT64, pts,
1228 gst_element_post_message (GST_ELEMENT_CAST (demux),
1229 gst_message_new_element (GST_OBJECT (demux), st));
1234 gst_ts_demux_record_dts (GstTSDemux * demux, TSDemuxStream * stream,
1235 guint64 dts, guint64 offset)
1237 MpegTSBaseStream *bs = (MpegTSBaseStream *) stream;
1240 stream->dts = GST_CLOCK_TIME_NONE;
1244 GST_LOG ("pid 0x%04x dts:%" G_GUINT64_FORMAT " at offset %"
1245 G_GUINT64_FORMAT, bs->pid, dts, offset);
1247 if (G_UNLIKELY (GST_CLOCK_TIME_IS_VALID (stream->dts) &&
1248 ABSDIFF (stream->raw_dts, dts) > 900000)) {
1249 /* Detect rollover if diff > 10s */
1250 GST_LOG ("Detected rollover (previous:%" G_GUINT64_FORMAT " new:%"
1251 G_GUINT64_FORMAT ")", stream->raw_dts, dts);
1252 if (dts < stream->raw_dts) {
1253 /* Forward rollover */
1254 GST_LOG ("Forward rollover, incrementing nb_dts_rollover");
1255 stream->nb_dts_rollover++;
1257 /* Reverse rollover */
1258 GST_LOG ("Reverse rollover, decrementing nb_dts_rollover");
1259 stream->nb_dts_rollover--;
1263 /* Compute DTS in GstClockTime */
1264 stream->raw_dts = dts;
1265 stream->fixed_dts = dts + stream->nb_dts_rollover * PTS_DTS_MAX_VALUE;
1266 stream->dts = MPEGTIME_TO_GSTTIME (stream->fixed_dts);
1268 GST_LOG ("pid 0x%04x Stored DTS %" G_GUINT64_FORMAT " (%" GST_TIME_FORMAT ")",
1269 bs->pid, stream->raw_dts, GST_TIME_ARGS (stream->dts));
1271 if (G_UNLIKELY (demux->emit_statistics)) {
1273 st = gst_structure_new_id_empty (QUARK_TSDEMUX);
1274 gst_structure_id_set (st,
1275 QUARK_PID, G_TYPE_UINT, bs->pid,
1276 QUARK_OFFSET, G_TYPE_UINT64, offset, QUARK_DTS, G_TYPE_UINT64, dts,
1278 gst_element_post_message (GST_ELEMENT_CAST (demux),
1279 gst_message_new_element (GST_OBJECT (demux), st));
1284 gst_ts_demux_parse_pes_header (GstTSDemux * demux, TSDemuxStream * stream,
1285 guint8 * data, guint32 length, guint64 bufferoffset)
1287 MpegTSBase *base = (MpegTSBase *) demux;
1290 PESParsingResult parseres;
1292 GST_MEMDUMP ("Header buffer", data, MIN (length, 32));
1294 parseres = mpegts_parse_pes_header (data, length, &header, &offset);
1295 if (G_UNLIKELY (parseres == PES_PARSING_NEED_MORE))
1297 if (G_UNLIKELY (parseres == PES_PARSING_BAD)) {
1298 GST_WARNING ("Error parsing PES header. pid: 0x%x stream_type: 0x%x",
1299 stream->stream.pid, stream->stream.stream_type);
1303 gst_ts_demux_record_dts (demux, stream, header.DTS, bufferoffset);
1304 gst_ts_demux_record_pts (demux, stream, header.PTS, bufferoffset);
1306 GST_DEBUG_OBJECT (base,
1307 "stream PTS %" GST_TIME_FORMAT " DTS %" GST_TIME_FORMAT,
1308 GST_TIME_ARGS (stream->pts), GST_TIME_ARGS (stream->dts));
1310 /* Remove PES headers */
1311 GST_DEBUG ("Moving data forward by %d bytes (packet_size:%d, have:%d)",
1312 header.header_size, header.packet_length, length);
1313 stream->expected_size = header.packet_length;
1314 if (stream->expected_size) {
1315 if (G_LIKELY (stream->expected_size > header.header_size)) {
1316 stream->expected_size -= header.header_size;
1318 /* next packet will have to complete this one */
1319 GST_ERROR ("invalid header and packet size combination");
1320 stream->expected_size = 0;
1323 data += header.header_size;
1324 length -= header.header_size;
1326 /* Create the output buffer */
1327 if (stream->expected_size)
1328 stream->allocated_size = stream->expected_size;
1330 stream->allocated_size = 8192;
1331 g_assert (stream->data == NULL);
1332 stream->data = g_malloc (stream->allocated_size);
1333 memcpy (stream->data, data, length);
1334 stream->current_size = length;
1336 stream->state = PENDING_PACKET_BUFFER;
1341 stream->state = PENDING_PACKET_DISCONT;
1346 * * WITH packet->payload != NULL
1347 * * WITH pending/current flushed out if beginning of new PES packet
1350 gst_ts_demux_queue_data (GstTSDemux * demux, TSDemuxStream * stream,
1351 MpegTSPacketizerPacket * packet)
1356 GST_DEBUG ("pid: 0x%04x state:%d", stream->stream.pid, stream->state);
1358 size = packet->data_end - packet->payload;
1359 data = packet->payload;
1361 if (stream->continuity_counter == CONTINUITY_UNSET) {
1362 GST_DEBUG ("CONTINUITY: Initialize to %d", packet->continuity_counter);
1363 } else if ((packet->continuity_counter == stream->continuity_counter + 1 ||
1364 (stream->continuity_counter == MAX_CONTINUITY &&
1365 packet->continuity_counter == 0))) {
1366 GST_LOG ("CONTINUITY: Got expected %d", packet->continuity_counter);
1368 GST_ERROR ("CONTINUITY: Mismatch packet %d, stream %d",
1369 packet->continuity_counter, stream->continuity_counter);
1370 stream->state = PENDING_PACKET_DISCONT;
1372 stream->continuity_counter = packet->continuity_counter;
1374 if (stream->state == PENDING_PACKET_EMPTY) {
1375 if (G_UNLIKELY (!packet->payload_unit_start_indicator)) {
1376 stream->state = PENDING_PACKET_DISCONT;
1377 GST_WARNING ("Didn't get the first packet of this PES");
1379 GST_LOG ("EMPTY=>HEADER");
1380 stream->state = PENDING_PACKET_HEADER;
1384 switch (stream->state) {
1385 case PENDING_PACKET_HEADER:
1387 GST_LOG ("HEADER: Parsing PES header");
1389 /* parse the header */
1390 gst_ts_demux_parse_pes_header (demux, stream, data, size, packet->offset);
1393 case PENDING_PACKET_BUFFER:
1395 GST_LOG ("BUFFER: appending data");
1396 if (G_UNLIKELY (stream->current_size + size > stream->allocated_size)) {
1397 GST_LOG ("resizing buffer");
1398 stream->allocated_size = stream->allocated_size * 2;
1399 stream->data = g_realloc (stream->data, stream->allocated_size);
1401 memcpy (stream->data + stream->current_size, data, size);
1402 stream->current_size += size;
1405 case PENDING_PACKET_DISCONT:
1407 GST_LOG ("DISCONT: not storing/pushing");
1408 if (G_UNLIKELY (stream->data)) {
1409 g_free (stream->data);
1410 stream->data = NULL;
1412 stream->continuity_counter = CONTINUITY_UNSET;
1423 calculate_and_push_newsegment (GstTSDemux * demux, TSDemuxStream * stream)
1425 MpegTSBase *base = (MpegTSBase *) demux;
1426 GstClockTime lowest_pts = GST_CLOCK_TIME_NONE;
1427 GstClockTime firstts = 0;
1430 GST_DEBUG ("Creating new newsegment for stream %p", stream);
1432 /* 0) If we don't have a time segment yet try to recover segment info from
1433 * base when it's in time otherwise just initialize segment with
1435 * It will happen only if it's first program or after flushes. */
1436 if (demux->segment.format == GST_FORMAT_UNDEFINED) {
1437 if (base->segment.format == GST_FORMAT_TIME) {
1438 demux->segment = base->segment;
1439 /* We can shortcut and create the segment event directly */
1440 demux->segment_event = gst_event_new_segment (&demux->segment);
1442 gst_segment_init (&demux->segment, GST_FORMAT_TIME);
1446 /* 1) If we need to calculate an update newsegment, do it
1447 * 2) If we need to calculate a new newsegment, do it
1448 * 3) If an update_segment is valid, push it
1449 * 4) If a newsegment is valid, push it */
1451 /* Speedup : if we don't need to calculate anything, go straight to pushing */
1452 if (!demux->calculate_update_segment && demux->segment_event)
1453 goto push_new_segment;
1455 /* Calculate the 'new_start' value, used for both updates and newsegment */
1456 for (tmp = demux->program->stream_list; tmp; tmp = tmp->next) {
1457 TSDemuxStream *pstream = (TSDemuxStream *) tmp->data;
1459 if (GST_CLOCK_TIME_IS_VALID (pstream->pts)) {
1460 if (!GST_CLOCK_TIME_IS_VALID (lowest_pts) || pstream->pts < lowest_pts)
1461 lowest_pts = pstream->pts;
1463 if (GST_CLOCK_TIME_IS_VALID (pstream->dts)) {
1464 if (!GST_CLOCK_TIME_IS_VALID (lowest_pts) || pstream->dts < lowest_pts)
1465 lowest_pts = pstream->dts;
1468 if (GST_CLOCK_TIME_IS_VALID (lowest_pts))
1470 mpegts_packetizer_pts_to_ts (base->packetizer, lowest_pts,
1471 demux->program->pcr_pid);
1472 GST_DEBUG ("lowest_pts %" G_GUINT64_FORMAT " => clocktime %" GST_TIME_FORMAT,
1473 lowest_pts, GST_TIME_ARGS (firstts));
1475 if (demux->calculate_update_segment) {
1476 GST_DEBUG ("Calculating update segment");
1477 /* If we have a valid segment, create an update of that */
1478 if (demux->segment.format == GST_FORMAT_TIME) {
1479 GstSegment update_segment;
1480 GST_DEBUG ("Re-using segment " SEGMENT_FORMAT,
1481 SEGMENT_ARGS (demux->segment));
1482 gst_segment_copy_into (&demux->segment, &update_segment);
1483 update_segment.stop = firstts;
1484 demux->update_segment = gst_event_new_segment (&update_segment);
1486 demux->calculate_update_segment = FALSE;
1489 if (!demux->segment_event) {
1490 GstSegment new_segment;
1492 GST_DEBUG ("Calculating actual segment");
1494 gst_segment_copy_into (&demux->segment, &new_segment);
1495 if (new_segment.format != GST_FORMAT_TIME) {
1496 /* Start from the first ts/pts */
1497 new_segment.start = firstts;
1498 new_segment.stop = GST_CLOCK_TIME_NONE;
1499 new_segment.position = firstts;
1502 demux->segment_event = gst_event_new_segment (&new_segment);
1506 if (demux->update_segment) {
1507 GST_DEBUG_OBJECT (stream->pad, "Pushing update segment");
1508 gst_event_ref (demux->update_segment);
1509 gst_pad_push_event (stream->pad, demux->update_segment);
1512 if (demux->segment_event) {
1513 GST_DEBUG_OBJECT (stream->pad, "Pushing newsegment event");
1514 gst_event_ref (demux->segment_event);
1515 gst_pad_push_event (stream->pad, demux->segment_event);
1518 /* Push pending tags */
1519 if (stream->taglist) {
1520 GST_DEBUG_OBJECT (stream->pad, "Sending tags %" GST_PTR_FORMAT,
1522 gst_pad_push_event (stream->pad, gst_event_new_tag (stream->taglist));
1523 stream->taglist = NULL;
1526 stream->need_newsegment = FALSE;
1529 static GstFlowReturn
1530 gst_ts_demux_push_pending_data (GstTSDemux * demux, TSDemuxStream * stream)
1532 GstFlowReturn res = GST_FLOW_OK;
1533 MpegTSBaseStream *bs = (MpegTSBaseStream *) stream;
1534 GstBuffer *buffer = NULL;
1535 MpegTSPacketizer2 *packetizer = MPEG_TS_BASE_PACKETIZER (demux);
1537 GST_DEBUG_OBJECT (stream->pad,
1538 "stream:%p, pid:0x%04x stream_type:%d state:%d", stream, bs->pid,
1539 bs->stream_type, stream->state);
1541 if (G_UNLIKELY (stream->data == NULL)) {
1542 GST_LOG ("stream->data == NULL");
1546 if (G_UNLIKELY (stream->state == PENDING_PACKET_EMPTY)) {
1547 GST_LOG ("EMPTY: returning");
1551 if (G_UNLIKELY (stream->state != PENDING_PACKET_BUFFER)) {
1552 GST_LOG ("state:%d, returning", stream->state);
1556 if (G_UNLIKELY (!stream->active))
1557 activate_pad_for_stream (demux, stream);
1559 if (G_UNLIKELY (stream->pad == NULL)) {
1560 g_free (stream->data);
1564 if (G_UNLIKELY (demux->program == NULL)) {
1565 GST_LOG_OBJECT (demux, "No program");
1566 g_free (stream->data);
1570 if (G_UNLIKELY (stream->need_newsegment))
1571 calculate_and_push_newsegment (demux, stream);
1573 buffer = gst_buffer_new_wrapped (stream->data, stream->current_size);
1575 GST_DEBUG_OBJECT (stream->pad, "stream->pts %" GST_TIME_FORMAT,
1576 GST_TIME_ARGS (stream->pts));
1577 if (GST_CLOCK_TIME_IS_VALID (stream->pts))
1578 GST_BUFFER_PTS (buffer) =
1579 mpegts_packetizer_pts_to_ts (packetizer, stream->pts,
1580 demux->program->pcr_pid);
1581 if (GST_CLOCK_TIME_IS_VALID (stream->dts))
1582 GST_BUFFER_DTS (buffer) =
1583 mpegts_packetizer_pts_to_ts (packetizer, stream->dts,
1584 demux->program->pcr_pid);
1586 GST_DEBUG_OBJECT (stream->pad,
1587 "Pushing buffer with PTS: %" GST_TIME_FORMAT " , DTS: %" GST_TIME_FORMAT,
1588 GST_TIME_ARGS (GST_BUFFER_PTS (buffer)),
1589 GST_TIME_ARGS (GST_BUFFER_DTS (buffer)));
1591 res = gst_pad_push (stream->pad, buffer);
1592 GST_DEBUG_OBJECT (stream->pad, "Returned %s", gst_flow_get_name (res));
1593 res = tsdemux_combine_flows (demux, stream, res);
1594 GST_DEBUG_OBJECT (stream->pad, "combined %s", gst_flow_get_name (res));
1597 /* Reset everything */
1598 GST_LOG ("Resetting to EMPTY, returning %s", gst_flow_get_name (res));
1599 stream->state = PENDING_PACKET_EMPTY;
1600 stream->data = NULL;
1601 stream->expected_size = 0;
1602 stream->current_size = 0;
1607 static GstFlowReturn
1608 gst_ts_demux_handle_packet (GstTSDemux * demux, TSDemuxStream * stream,
1609 MpegTSPacketizerPacket * packet, MpegTSPacketizerSection * section)
1611 GstFlowReturn res = GST_FLOW_OK;
1613 GST_DEBUG ("data:%p", packet->data);
1614 GST_LOG ("pid 0x%04x pusi:%d, afc:%d, cont:%d, payload:%p", packet->pid,
1615 packet->payload_unit_start_indicator, packet->adaptation_field_control,
1616 packet->continuity_counter, packet->payload);
1619 GST_DEBUG ("section complete:%d, buffer size %d",
1620 section->complete, section->section_length);
1624 if (G_UNLIKELY (packet->payload_unit_start_indicator) &&
1625 packet->adaptation_field_control & 0x1)
1626 /* Flush previous data */
1627 res = gst_ts_demux_push_pending_data (demux, stream);
1629 if (packet->payload && (res == GST_FLOW_OK || res == GST_FLOW_NOT_LINKED)
1631 gst_ts_demux_queue_data (demux, stream, packet);
1632 GST_DEBUG ("current_size:%d, expected_size:%d",
1633 stream->current_size, stream->expected_size);
1634 /* Finally check if the data we queued completes a packet */
1635 if (stream->expected_size && stream->current_size == stream->expected_size) {
1636 GST_LOG ("pushing complete packet");
1637 res = gst_ts_demux_push_pending_data (demux, stream);
1645 gst_ts_demux_flush (MpegTSBase * base)
1647 GstTSDemux *demux = GST_TS_DEMUX_CAST (base);
1649 gst_ts_demux_flush_streams (demux);
1651 if (demux->segment_event) {
1652 gst_event_unref (demux->segment_event);
1653 demux->segment_event = NULL;
1655 demux->calculate_update_segment = FALSE;
1656 gst_segment_init (&demux->segment, GST_FORMAT_UNDEFINED);
1659 static GstFlowReturn
1660 gst_ts_demux_push (MpegTSBase * base, MpegTSPacketizerPacket * packet,
1661 MpegTSPacketizerSection * section)
1663 GstTSDemux *demux = GST_TS_DEMUX_CAST (base);
1664 TSDemuxStream *stream = NULL;
1665 GstFlowReturn res = GST_FLOW_OK;
1667 if (G_LIKELY (demux->program)) {
1668 stream = (TSDemuxStream *) demux->program->streams[packet->pid];
1671 res = gst_ts_demux_handle_packet (demux, stream, packet, section);
1678 gst_ts_demux_plugin_init (GstPlugin * plugin)
1680 GST_DEBUG_CATEGORY_INIT (ts_demux_debug, "tsdemux", 0,
1681 "MPEG transport stream demuxer");
1684 return gst_element_register (plugin, "tsdemux",
1685 GST_RANK_PRIMARY, GST_TYPE_TS_DEMUX);