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>
39 #include <gst/pbutils/pbutils.h>
40 #include <gst/base/base.h>
41 #include <gst/audio/audio.h>
43 #include "mpegtsbase.h"
45 #include "gstmpegdesc.h"
46 #include "gstmpegdefs.h"
47 #include "mpegtspacketizer.h"
49 #include <gst/codecparsers/gsth264parser.h>
50 #include <gst/codecparsers/gstmpegvideoparser.h>
51 #include <gst/video/video-color.h>
55 #define _gst_log2(x) (log(x)/log(2))
60 * See TODO for explanations on improvements needed
63 #define CONTINUITY_UNSET 255
64 #define MAX_CONTINUITY 15
66 /* Seeking/Scanning related variables */
68 /* seek to SEEK_TIMESTAMP_OFFSET before the desired offset and search then
69 * either accurately or for the next timestamp
71 #define SEEK_TIMESTAMP_OFFSET (2500 * GST_MSECOND)
73 #define GST_FLOW_REWINDING GST_FLOW_CUSTOM_ERROR
75 /* latency in msecs */
76 #define DEFAULT_LATENCY (700)
78 /* Limit PES packet collection to a maximum of 32MB
79 * which is more than large enough to support an H264 frame at
80 * maximum profile/level/bitrate at 30fps or above.
81 * PES bigger than this limit will be output in buffers of
83 #define MAX_PES_PAYLOAD (32 * 1024 * 1024)
85 GST_DEBUG_CATEGORY_STATIC (ts_demux_debug);
86 #define GST_CAT_DEFAULT ts_demux_debug
88 #define ABSDIFF(a,b) (((a) > (b)) ? ((a) - (b)) : ((b) - (a)))
90 static GQuark QUARK_TSDEMUX;
91 static GQuark QUARK_PID;
92 static GQuark QUARK_PCR;
93 static GQuark QUARK_OPCR;
94 static GQuark QUARK_PTS;
95 static GQuark QUARK_DTS;
96 static GQuark QUARK_OFFSET;
97 #ifdef TIZEN_FEATURE_HLS_WEBVTT
98 static GQuark QUARK_BUFFER_PTS;
103 PENDING_PACKET_EMPTY = 0, /* No pending packet/buffer
104 * Push incoming buffers to the array */
105 PENDING_PACKET_HEADER, /* PES header needs to be parsed
106 * Push incoming buffers to the array */
107 PENDING_PACKET_BUFFER, /* Currently filling up output buffer
108 * Push incoming buffers to the bufferlist */
109 PENDING_PACKET_DISCONT /* Discontinuity in incoming packets
110 * Drop all incoming buffers */
111 } PendingPacketState;
116 /* The fully reconstructed buffer */
119 /* Raw PTS/DTS (in 90kHz units) */
123 typedef struct _TSDemuxStream TSDemuxStream;
125 typedef struct _TSDemuxH264ParsingInfos TSDemuxH264ParsingInfos;
126 typedef struct _TSDemuxJP2KParsingInfos TSDemuxJP2KParsingInfos;
127 typedef struct _TSDemuxADTSParsingInfos TSDemuxADTSParsingInfos;
129 /* Returns TRUE if a keyframe was found */
130 typedef gboolean (*GstTsDemuxKeyFrameScanFunction) (TSDemuxStream * stream,
131 guint8 * data, const gsize data_size, const gsize max_frame_offset);
139 struct _TSDemuxH264ParsingInfos
141 /* H264 parsing data */
142 GstH264NalParser *parser;
146 SimpleBuffer framedata;
149 struct _TSDemuxJP2KParsingInfos
151 /* J2K parsing data */
155 struct _TSDemuxADTSParsingInfos
160 struct _TSDemuxStream
162 MpegTSBaseStream stream;
166 /* Whether the pad was added or not */
169 /* Whether this is a sparse stream (subtitles or metadata) */
172 /* TRUE if we are waiting for a valid timestamp */
176 PendingPacketState state;
178 /* PES header being reconstructed (optional, allocated) */
179 guint8 *pending_header_data;
180 guint pending_header_size;
182 /* Data being reconstructed (allocated) */
185 /* Size of data being reconstructed (if known, else 0) */
188 /* Amount of bytes in current ->data */
191 guint allocated_size;
193 /* Current PTS/DTS for this stream (in running time) */
197 /* Reference PTS used to detect gaps */
198 GstClockTime gap_ref_pts;
199 /* Number of outputted buffers */
200 guint32 nb_out_buffers;
201 /* Reference number of buffers for gaps */
202 guint32 gap_ref_buffers;
204 /* Current PTS/DTS for this stream (in 90kHz unit) */
205 guint64 raw_pts, raw_dts;
207 /* Whether this stream needs to send a newsegment */
208 gboolean need_newsegment;
210 /* Whether the next output buffer should be DISCONT */
213 /* The value to use when calculating the newsegment */
214 GstClockTime first_pts;
218 gint continuity_counter;
220 /* List of pending buffers */
223 /* if != 0, output only PES from that substream */
224 guint8 target_pes_substream;
225 gboolean needs_keyframe;
227 GstClockTime seeked_pts, seeked_dts;
229 GstTsDemuxKeyFrameScanFunction scan_function;
230 TSDemuxH264ParsingInfos h264infos;
231 TSDemuxJP2KParsingInfos jp2kInfos;
232 TSDemuxADTSParsingInfos atdsInfos;
238 "mpegversion = (int) { 1, 2, 4 }, " \
239 "systemstream = (boolean) FALSE; " \
240 "video/x-h264,stream-format=(string)byte-stream;" \
241 "video/x-h265,stream-format=(string)byte-stream;" \
245 "wmvversion = (int) 3, " \
246 "format = (string) WVC1;" \
253 "mpegversion = (int) 1;" \
255 "mpegversion = (int) { 2, 4 }, " \
256 "stream-format = (string) adts; " \
258 "mpegversion = (int) 4, " \
259 "stream-format = (string) loas; " \
261 "width = (int) { 16, 20, 24 }, " \
262 "rate = (int) { 48000, 96000 }, " \
263 "channels = (int) [ 1, 8 ], " \
264 "dynamic_range = (int) [ 0, 255 ], " \
265 "emphasis = (boolean) { FALSE, TRUE }, " \
266 "mute = (boolean) { FALSE, TRUE }; " \
267 "audio/x-ac3; audio/x-eac3;" \
271 "audio/x-private-ts-lpcm" \
274 /* Can also use the subpicture pads for text subtitles? */
275 #define SUBPICTURE_CAPS \
276 GST_STATIC_CAPS ("subpicture/x-pgs; subpicture/x-dvd; subpicture/x-dvb")
278 static GstStaticPadTemplate video_template =
279 GST_STATIC_PAD_TEMPLATE ("video_%01x_%05x", GST_PAD_SRC,
283 static GstStaticPadTemplate audio_template =
284 GST_STATIC_PAD_TEMPLATE ("audio_%01x_%05x",
289 static GstStaticPadTemplate subpicture_template =
290 GST_STATIC_PAD_TEMPLATE ("subpicture_%01x_%05x",
295 static GstStaticPadTemplate private_template =
296 GST_STATIC_PAD_TEMPLATE ("private_%01x_%05x",
299 GST_STATIC_CAPS_ANY);
307 PROP_SEND_SCTE35_EVENTS,
314 /* mpegtsbase methods */
316 gst_ts_demux_update_program (MpegTSBase * base, MpegTSBaseProgram * program);
318 gst_ts_demux_program_started (MpegTSBase * base, MpegTSBaseProgram * program);
320 gst_ts_demux_program_stopped (MpegTSBase * base, MpegTSBaseProgram * program);
322 gst_ts_demux_can_remove_program (MpegTSBase * base,
323 MpegTSBaseProgram * program);
324 static void gst_ts_demux_reset (MpegTSBase * base);
326 gst_ts_demux_push (MpegTSBase * base, MpegTSPacketizerPacket * packet,
327 GstMpegtsSection * section);
328 static void gst_ts_demux_flush (MpegTSBase * base, gboolean hard);
329 static GstFlowReturn gst_ts_demux_drain (MpegTSBase * base);
331 gst_ts_demux_stream_added (MpegTSBase * base, MpegTSBaseStream * stream,
332 MpegTSBaseProgram * program);
334 gst_ts_demux_stream_removed (MpegTSBase * base, MpegTSBaseStream * stream);
335 static GstFlowReturn gst_ts_demux_do_seek (MpegTSBase * base, GstEvent * event);
336 static void gst_ts_demux_set_property (GObject * object, guint prop_id,
337 const GValue * value, GParamSpec * pspec);
338 static void gst_ts_demux_get_property (GObject * object, guint prop_id,
339 GValue * value, GParamSpec * pspec);
340 static void gst_ts_demux_flush_streams (GstTSDemux * tsdemux, gboolean hard);
342 gst_ts_demux_push_pending_data (GstTSDemux * demux, TSDemuxStream * stream,
343 MpegTSBaseProgram * program);
344 static void gst_ts_demux_stream_flush (TSDemuxStream * stream,
345 GstTSDemux * demux, gboolean hard);
347 static gboolean push_event (MpegTSBase * base, GstEvent * event);
348 static gboolean sink_query (MpegTSBase * base, GstQuery * query);
349 static void gst_ts_demux_check_and_sync_streams (GstTSDemux * demux,
351 static void handle_psi (MpegTSBase * base, GstMpegtsSection * section);
356 QUARK_TSDEMUX = g_quark_from_string ("tsdemux");
357 QUARK_PID = g_quark_from_string ("pid");
358 QUARK_PCR = g_quark_from_string ("pcr");
359 QUARK_OPCR = g_quark_from_string ("opcr");
360 QUARK_PTS = g_quark_from_string ("pts");
361 QUARK_DTS = g_quark_from_string ("dts");
362 QUARK_OFFSET = g_quark_from_string ("offset");
363 #ifdef TIZEN_FEATURE_HLS_WEBVTT
364 QUARK_BUFFER_PTS = g_quark_from_string ("buffer_pts");
368 #define gst_ts_demux_parent_class parent_class
369 G_DEFINE_TYPE_WITH_CODE (GstTSDemux, gst_ts_demux, GST_TYPE_MPEGTS_BASE,
371 #define _do_element_init \
372 GST_DEBUG_CATEGORY_INIT (ts_demux_debug, "tsdemux", 0, \
373 "MPEG transport stream demuxer");\
375 GST_ELEMENT_REGISTER_DEFINE_WITH_CODE (tsdemux, "tsdemux",
376 GST_RANK_PRIMARY, GST_TYPE_TS_DEMUX, _do_element_init);
379 gst_ts_demux_dispose (GObject * object)
381 GstTSDemux *demux = GST_TS_DEMUX_CAST (object);
383 gst_flow_combiner_free (demux->flowcombiner);
385 GST_CALL_PARENT (G_OBJECT_CLASS, dispose, (object));
389 gst_ts_demux_finalize (GObject * object)
391 GstTSDemux *demux = GST_TS_DEMUX_CAST (object);
393 gst_event_replace (&demux->segment_event, NULL);
394 g_mutex_clear (&demux->lock);
396 GST_CALL_PARENT (G_OBJECT_CLASS, finalize, (object));
400 gst_ts_demux_class_init (GstTSDemuxClass * klass)
402 GObjectClass *gobject_class;
403 GstElementClass *element_class;
404 MpegTSBaseClass *ts_class;
406 gobject_class = G_OBJECT_CLASS (klass);
407 gobject_class->set_property = gst_ts_demux_set_property;
408 gobject_class->get_property = gst_ts_demux_get_property;
409 gobject_class->dispose = gst_ts_demux_dispose;
410 gobject_class->finalize = gst_ts_demux_finalize;
412 g_object_class_install_property (gobject_class, PROP_PROGRAM_NUMBER,
413 g_param_spec_int ("program-number", "Program number",
414 "Program Number to demux for (-1 to ignore)", -1, G_MAXINT,
415 -1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
417 g_object_class_install_property (gobject_class, PROP_EMIT_STATS,
418 g_param_spec_boolean ("emit-stats", "Emit statistics",
419 "Emit messages for every pcr/opcr/pts/dts", FALSE,
420 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
423 * tsdemux:send-scte35-events:
425 * Whether SCTE 35 sections should be forwarded as events.
427 * When forwarding those, potential splice times are converted
428 * to running time, and can be used by a downstream muxer to reinject
433 g_object_class_install_property (gobject_class, PROP_SEND_SCTE35_EVENTS,
434 g_param_spec_boolean ("send-scte35-events", "Send SCTE 35 events",
435 "Whether SCTE 35 sections should be forwarded as events", FALSE,
436 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
438 g_object_class_install_property (gobject_class, PROP_LATENCY,
439 g_param_spec_int ("latency", "Latency",
440 "Latency to add for smooth demuxing (in ms)", -1,
441 G_MAXINT, DEFAULT_LATENCY,
442 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
444 element_class = GST_ELEMENT_CLASS (klass);
445 gst_element_class_add_pad_template (element_class,
446 gst_static_pad_template_get (&video_template));
447 gst_element_class_add_pad_template (element_class,
448 gst_static_pad_template_get (&audio_template));
449 gst_element_class_add_pad_template (element_class,
450 gst_static_pad_template_get (&subpicture_template));
451 gst_element_class_add_pad_template (element_class,
452 gst_static_pad_template_get (&private_template));
454 gst_element_class_set_static_metadata (element_class,
455 "MPEG transport stream demuxer",
457 "Demuxes MPEG2 transport streams",
458 "Zaheer Abbas Merali <zaheerabbas at merali dot org>\n"
459 "Edward Hervey <edward.hervey@collabora.co.uk>");
461 ts_class = GST_MPEGTS_BASE_CLASS (klass);
462 ts_class->reset = GST_DEBUG_FUNCPTR (gst_ts_demux_reset);
463 ts_class->push = GST_DEBUG_FUNCPTR (gst_ts_demux_push);
464 ts_class->push_event = GST_DEBUG_FUNCPTR (push_event);
465 ts_class->handle_psi = GST_DEBUG_FUNCPTR (handle_psi);
466 ts_class->sink_query = GST_DEBUG_FUNCPTR (sink_query);
467 ts_class->program_started = GST_DEBUG_FUNCPTR (gst_ts_demux_program_started);
468 ts_class->program_stopped = GST_DEBUG_FUNCPTR (gst_ts_demux_program_stopped);
469 ts_class->update_program = GST_DEBUG_FUNCPTR (gst_ts_demux_update_program);
470 ts_class->can_remove_program = gst_ts_demux_can_remove_program;
471 ts_class->stream_added = gst_ts_demux_stream_added;
472 ts_class->stream_removed = gst_ts_demux_stream_removed;
473 ts_class->seek = GST_DEBUG_FUNCPTR (gst_ts_demux_do_seek);
474 ts_class->flush = GST_DEBUG_FUNCPTR (gst_ts_demux_flush);
475 ts_class->drain = GST_DEBUG_FUNCPTR (gst_ts_demux_drain);
479 gst_ts_demux_reset (MpegTSBase * base)
481 GstTSDemux *demux = (GstTSDemux *) base;
484 g_mutex_lock (&demux->lock);
485 gst_event_replace (&demux->segment_event, NULL);
486 g_mutex_unlock (&demux->lock);
488 if (demux->global_tags) {
489 gst_tag_list_unref (demux->global_tags);
490 demux->global_tags = NULL;
492 #ifdef TIZEN_FEATURE_TSDEMUX_LANG_TAG
493 if (demux->pending_custom_event) {
494 gst_event_unref (demux->pending_custom_event);
495 demux->pending_custom_event = NULL;
498 if (demux->pending_language_tag) {
499 gst_tag_list_unref (demux->pending_language_tag);
500 demux->pending_language_tag = NULL;
504 if (demux->previous_program) {
505 mpegts_base_deactivate_and_free_program (base, demux->previous_program);
506 demux->previous_program = NULL;
509 demux->have_group_id = FALSE;
510 demux->group_id = G_MAXUINT;
512 demux->last_seek_offset = -1;
513 demux->program_generation = 0;
515 demux->mpeg_pts_offset = 0;
519 gst_ts_demux_init (GstTSDemux * demux)
521 MpegTSBase *base = (MpegTSBase *) demux;
523 base->stream_size = sizeof (TSDemuxStream);
524 base->parse_private_sections = TRUE;
525 /* We are not interested in sections (all handled by mpegtsbase) */
526 base->push_section = FALSE;
528 demux->flowcombiner = gst_flow_combiner_new ();
529 demux->requested_program_number = -1;
530 demux->program_number = -1;
531 demux->latency = DEFAULT_LATENCY;
532 gst_ts_demux_reset (base);
534 g_mutex_init (&demux->lock);
539 gst_ts_demux_set_property (GObject * object, guint prop_id,
540 const GValue * value, GParamSpec * pspec)
542 GstTSDemux *demux = GST_TS_DEMUX (object);
545 case PROP_PROGRAM_NUMBER:
546 /* FIXME: do something if program is switched as opposed to set at
548 demux->requested_program_number = g_value_get_int (value);
550 case PROP_EMIT_STATS:
551 demux->emit_statistics = g_value_get_boolean (value);
553 case PROP_SEND_SCTE35_EVENTS:
554 demux->send_scte35_events = g_value_get_boolean (value);
557 demux->latency = g_value_get_int (value);
560 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
565 gst_ts_demux_get_property (GObject * object, guint prop_id,
566 GValue * value, GParamSpec * pspec)
568 GstTSDemux *demux = GST_TS_DEMUX (object);
571 case PROP_PROGRAM_NUMBER:
572 g_value_set_int (value, demux->requested_program_number);
574 case PROP_EMIT_STATS:
575 g_value_set_boolean (value, demux->emit_statistics);
577 case PROP_SEND_SCTE35_EVENTS:
578 g_value_set_boolean (value, demux->send_scte35_events);
581 g_value_set_int (value, demux->latency);
584 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
589 gst_ts_demux_get_duration (GstTSDemux * demux, GstClockTime * dur)
591 MpegTSBase *base = (MpegTSBase *) demux;
592 gboolean res = FALSE;
595 if (!demux->program) {
596 GST_DEBUG_OBJECT (demux, "No active program yet, can't provide duration");
600 /* Get total size in bytes */
601 if (gst_pad_peer_query_duration (base->sinkpad, GST_FORMAT_BYTES, &val)) {
602 /* Convert it to duration */
604 mpegts_packetizer_offset_to_ts (base->packetizer, val,
605 demux->program->pcr_pid);
606 if (GST_CLOCK_TIME_IS_VALID (*dur))
613 gst_ts_demux_srcpad_query (GstPad * pad, GstObject * parent, GstQuery * query)
620 demux = GST_TS_DEMUX (parent);
621 base = GST_MPEGTS_BASE (demux);
623 switch (GST_QUERY_TYPE (query)) {
624 case GST_QUERY_DURATION:
626 GST_DEBUG_OBJECT (pad, "query duration");
627 gst_query_parse_duration (query, &format, NULL);
628 if (format == GST_FORMAT_TIME) {
629 if (!gst_pad_peer_query (base->sinkpad, query)) {
631 if (gst_ts_demux_get_duration (demux, &dur))
632 gst_query_set_duration (query, GST_FORMAT_TIME, dur);
637 GST_DEBUG_OBJECT (demux, "only query duration on TIME is supported");
642 case GST_QUERY_LATENCY:
644 GST_DEBUG_OBJECT (pad, "query latency");
645 res = gst_pad_peer_query (base->sinkpad, query);
647 GstClockTime min_lat, max_lat;
651 /* According to H.222.0
652 Annex D.0.3 (System Time Clock recovery in the decoder)
653 and D.0.2 (Audio and video presentation synchronization)
655 We can end up with an interval of up to 700ms between valid
656 PTS/DTS. We therefore allow a latency of 700ms for that.
658 latency = demux->latency;
661 gst_query_parse_latency (query, &live, &min_lat, &max_lat);
662 min_lat += latency * GST_MSECOND;
663 if (GST_CLOCK_TIME_IS_VALID (max_lat))
664 max_lat += latency * GST_MSECOND;
665 gst_query_set_latency (query, live, min_lat, max_lat);
669 case GST_QUERY_SEEKING:
671 GST_DEBUG_OBJECT (pad, "query seeking");
672 gst_query_parse_seeking (query, &format, NULL, NULL, NULL);
673 GST_DEBUG_OBJECT (pad, "asked for format %s",
674 gst_format_get_name (format));
675 if (format == GST_FORMAT_TIME) {
676 gboolean seekable = FALSE;
678 if (gst_pad_peer_query (base->sinkpad, query))
679 gst_query_parse_seeking (query, NULL, &seekable, NULL, NULL);
681 /* If upstream is not seekable in TIME format we use
682 * our own values here */
685 if (gst_ts_demux_get_duration (demux, &dur)) {
686 gst_query_set_seeking (query, GST_FORMAT_TIME, TRUE, 0, dur);
687 GST_DEBUG_OBJECT (pad, "Gave duration: %" GST_TIME_FORMAT,
688 GST_TIME_ARGS (dur));
692 GST_DEBUG_OBJECT (demux, "only TIME is supported for query seeking");
697 case GST_QUERY_SEGMENT:{
701 format = base->out_segment.format;
704 gst_segment_to_stream_time (&base->out_segment, format,
705 base->out_segment.start);
706 if ((stop = base->out_segment.stop) == -1)
707 stop = base->out_segment.duration;
709 stop = gst_segment_to_stream_time (&base->out_segment, format, stop);
711 gst_query_set_segment (query, base->out_segment.rate, format, start,
717 res = gst_pad_query_default (pad, parent, query);
725 clear_simple_buffer (SimpleBuffer * sbuf)
736 scan_keyframe_h264 (TSDemuxStream * stream, const guint8 * data,
737 const gsize data_size, const gsize max_frame_offset)
740 GstH264NalUnit unit, frame_unit = { 0, };
741 GstH264ParserResult res = GST_H264_PARSER_OK;
742 TSDemuxH264ParsingInfos *h264infos = &stream->h264infos;
744 GstH264NalParser *parser = h264infos->parser;
746 if (G_UNLIKELY (parser == NULL)) {
747 parser = h264infos->parser = gst_h264_nal_parser_new ();
748 h264infos->sps = gst_byte_writer_new ();
749 h264infos->pps = gst_byte_writer_new ();
750 h264infos->sei = gst_byte_writer_new ();
753 while (res == GST_H264_PARSER_OK) {
755 gst_h264_parser_identify_nalu (parser, data, offset, data_size, &unit);
757 if (res != GST_H264_PARSER_OK && res != GST_H264_PARSER_NO_NAL_END) {
758 GST_INFO_OBJECT (stream->pad, "Error identifying nalu: %i", res);
762 res = gst_h264_parser_parse_nal (parser, &unit);
763 if (res != GST_H264_PARSER_OK) {
768 case GST_H264_NAL_SEI:
772 if (gst_byte_writer_put_data (h264infos->sei,
773 unit.data + unit.sc_offset,
774 unit.size + unit.offset - unit.sc_offset)) {
775 GST_DEBUG_OBJECT (stream->pad, "adding SEI %u",
776 unit.size + unit.offset - unit.sc_offset);
778 GST_WARNING_OBJECT (stream->pad, "Could not write SEI");
781 case GST_H264_NAL_PPS:
785 if (gst_byte_writer_put_data (h264infos->pps,
786 unit.data + unit.sc_offset,
787 unit.size + unit.offset - unit.sc_offset)) {
788 GST_DEBUG_OBJECT (stream->pad, "adding PPS %u",
789 unit.size + unit.offset - unit.sc_offset);
791 GST_WARNING_OBJECT (stream->pad, "Could not write PPS");
794 case GST_H264_NAL_SPS:
798 if (gst_byte_writer_put_data (h264infos->sps,
799 unit.data + unit.sc_offset,
800 unit.size + unit.offset - unit.sc_offset)) {
801 GST_DEBUG_OBJECT (stream->pad, "adding SPS %u",
802 unit.size + unit.offset - unit.sc_offset);
804 GST_WARNING_OBJECT (stream->pad, "Could not write SPS");
807 /* these units are considered keyframes in h264parse */
808 case GST_H264_NAL_SLICE:
809 case GST_H264_NAL_SLICE_DPA:
810 case GST_H264_NAL_SLICE_DPB:
811 case GST_H264_NAL_SLICE_DPC:
812 case GST_H264_NAL_SLICE_IDR:
814 GstH264SliceHdr slice;
816 if (h264infos->framedata.size)
819 res = gst_h264_parser_parse_slice_hdr (parser, &unit, &slice,
822 if (GST_H264_IS_I_SLICE (&slice) || GST_H264_IS_SI_SLICE (&slice)) {
823 if (*(unit.data + unit.offset + 1) & 0x80) {
824 /* means first_mb_in_slice == 0 */
825 /* real frame data */
826 GST_DEBUG_OBJECT (stream->pad, "Found keyframe at: %u",
838 if (offset == unit.sc_offset + unit.size)
841 offset = unit.sc_offset + unit.size;
844 /* We've got all the infos we need (SPS / PPS and a keyframe, plus
845 * and possibly SEI units. We can stop rewinding the stream
847 if (gst_byte_writer_get_size (h264infos->sps) &&
848 gst_byte_writer_get_size (h264infos->pps) &&
849 (h264infos->framedata.size || frame_unit.size)) {
852 gsize tmpsize = gst_byte_writer_get_size (h264infos->pps);
854 /* We know that the SPS is first so just put all our data in there */
855 data = gst_byte_writer_reset_and_get_data (h264infos->pps);
856 gst_byte_writer_put_data (h264infos->sps, data, tmpsize);
859 tmpsize = gst_byte_writer_get_size (h264infos->sei);
861 GST_DEBUG_OBJECT (stream->pad, "Adding SEI");
862 data = gst_byte_writer_reset_and_get_data (h264infos->sei);
863 gst_byte_writer_put_data (h264infos->sps, data, tmpsize);
867 if (frame_unit.size) { /* We found the everything in one go! */
868 GST_DEBUG_OBJECT (stream->pad, "Adding Keyframe");
869 gst_byte_writer_put_data (h264infos->sps,
870 frame_unit.data + frame_unit.sc_offset,
871 stream->current_size - frame_unit.sc_offset);
873 GST_DEBUG_OBJECT (stream->pad, "Adding Keyframe");
874 gst_byte_writer_put_data (h264infos->sps,
875 h264infos->framedata.data, h264infos->framedata.size);
876 clear_simple_buffer (&h264infos->framedata);
879 g_free (stream->data);
880 stream->current_size = gst_byte_writer_get_size (h264infos->sps);
881 stream->data = gst_byte_writer_reset_and_get_data (h264infos->sps);
882 gst_byte_writer_init (h264infos->sps);
883 gst_byte_writer_init (h264infos->pps);
884 gst_byte_writer_init (h264infos->sei);
889 if (frame_unit.size) {
890 GST_DEBUG_OBJECT (stream->pad, "Keep the keyframe as this is the one"
891 " we will push later");
893 h264infos->framedata.data =
894 g_memdup2 (frame_unit.data + frame_unit.sc_offset,
895 stream->current_size - frame_unit.sc_offset);
896 h264infos->framedata.size = stream->current_size - frame_unit.sc_offset;
902 /* We merge data from TS packets so that the scanning methods get a continuous chunk,
903 however the scanning method will return keyframe offset which needs to be translated
904 back to actual offset in file */
907 gint64 real_offset; /* offset of TS packet */
908 gint merged_offset; /* offset of merged data in buffer */
912 gst_ts_demux_adjust_seek_offset_for_keyframe (TSDemuxStream * stream,
913 guint8 * data, guint64 size)
917 if (!stream->scan_function)
920 scan_pid = ((MpegTSBaseStream *) stream)->pid;
922 if (scan_pid != -1) {
923 return stream->scan_function (stream, data, size, size);
930 gst_ts_demux_do_seek (MpegTSBase * base, GstEvent * event)
934 GstTSDemux *demux = (GstTSDemux *) base;
935 GstFlowReturn res = GST_FLOW_ERROR;
939 GstSeekType start_type, stop_type;
941 guint64 start_offset;
942 gboolean update = FALSE;
943 GstSegment seeksegment;
945 GST_DEBUG_OBJECT (demux, "seek event, %" GST_PTR_FORMAT, event);
947 if (base->out_segment.format == GST_FORMAT_UNDEFINED) {
948 GST_DEBUG_OBJECT (demux, "Cannot process seek event now, delaying");
949 gst_event_replace (&base->seek_event, event);
954 gst_event_parse_seek (event, &rate, &format, &flags, &start_type, &start,
958 GST_WARNING_OBJECT (demux, "Negative rate not supported");
962 if (flags & (GST_SEEK_FLAG_SEGMENT)) {
963 GST_WARNING_OBJECT (demux, "seek flags 0x%x are not supported",
968 /* configure the segment with the seek variables */
969 memcpy (&seeksegment, &base->out_segment, sizeof (GstSegment));
970 GST_LOG_OBJECT (demux, "Before seek, output segment %" GST_SEGMENT_FORMAT,
973 /* record offset and rate */
975 if (!gst_segment_do_seek (&seeksegment, rate, format, flags, start_type,
976 start, stop_type, stop, &update)) {
977 GST_DEBUG_OBJECT (demux, "Seek failed in gst_segment_do_seek()");
981 GST_DEBUG_OBJECT (demux,
982 "After seek, update %d output segment now %" GST_SEGMENT_FORMAT, update,
985 /* If the position actually changed, update == TRUE */
986 g_mutex_lock (&demux->lock);
988 GstClockTime target = seeksegment.start;
989 if (target >= SEEK_TIMESTAMP_OFFSET)
990 target -= SEEK_TIMESTAMP_OFFSET;
995 mpegts_packetizer_ts_to_offset (base->packetizer, target,
996 demux->program->pcr_pid);
997 if (G_UNLIKELY (start_offset == -1)) {
998 GST_WARNING_OBJECT (demux,
999 "Couldn't convert start position to an offset");
1000 g_mutex_unlock (&demux->lock);
1004 base->seek_offset = start_offset;
1005 demux->last_seek_offset = base->seek_offset;
1006 /* Reset segment if we're not doing an accurate seek */
1007 demux->reset_segment = (!(flags & GST_SEEK_FLAG_ACCURATE));
1009 /* Clear any existing segment - it will be recalculated after streaming recommences */
1010 gst_event_replace (&demux->segment_event, NULL);
1012 for (tmp = demux->program->stream_list; tmp; tmp = tmp->next) {
1013 TSDemuxStream *stream = tmp->data;
1015 if (flags & GST_SEEK_FLAG_ACCURATE)
1016 stream->needs_keyframe = TRUE;
1018 stream->seeked_pts = GST_CLOCK_TIME_NONE;
1019 stream->seeked_dts = GST_CLOCK_TIME_NONE;
1020 stream->first_pts = GST_CLOCK_TIME_NONE;
1021 stream->need_newsegment = TRUE;
1024 /* Position didn't change, just update the output segment based on
1026 gst_event_take (&demux->segment_event,
1027 gst_event_new_segment (&seeksegment));
1028 if (base->last_seek_seqnum)
1029 gst_event_set_seqnum (demux->segment_event, base->last_seek_seqnum);
1030 for (tmp = demux->program->stream_list; tmp; tmp = tmp->next) {
1031 TSDemuxStream *stream = tmp->data;
1032 stream->need_newsegment = TRUE;
1035 g_mutex_unlock (&demux->lock);
1037 /* Commit the new segment */
1038 memcpy (&base->out_segment, &seeksegment, sizeof (GstSegment));
1046 gst_ts_demux_srcpad_event (GstPad * pad, GstObject * parent, GstEvent * event)
1048 gboolean res = TRUE;
1049 GstTSDemux *demux = GST_TS_DEMUX (parent);
1051 GST_DEBUG_OBJECT (pad, "Got event %s",
1052 gst_event_type_get_name (GST_EVENT_TYPE (event)));
1054 switch (GST_EVENT_TYPE (event)) {
1055 case GST_EVENT_SEEK:
1056 res = mpegts_base_handle_seek_event ((MpegTSBase *) demux, pad, event);
1058 GST_WARNING_OBJECT (pad, "seeking failed");
1059 gst_event_unref (event);
1062 res = gst_pad_event_default (pad, parent, event);
1069 clean_global_taglist (GstTagList * taglist)
1071 gst_tag_list_remove_tag (taglist, GST_TAG_CONTAINER_FORMAT);
1072 gst_tag_list_remove_tag (taglist, GST_TAG_CODEC);
1076 push_event (MpegTSBase * base, GstEvent * event)
1078 GstTSDemux *demux = (GstTSDemux *) base;
1080 gboolean early_ret = FALSE;
1082 if (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT) {
1083 if (base->segment.format == GST_FORMAT_TIME && base->ignore_pcr) {
1084 /* Shift start/stop values by 2s */
1085 base->packetizer->extra_shift = 2 * GST_SECOND;
1086 if (GST_CLOCK_TIME_IS_VALID (base->segment.start))
1087 base->segment.start += 2 * GST_SECOND;
1088 if (GST_CLOCK_TIME_IS_VALID (base->segment.stop))
1089 base->segment.stop += 2 * GST_SECOND;
1090 if (GST_CLOCK_TIME_IS_VALID (base->segment.position))
1091 base->segment.position += 2 * GST_SECOND;
1093 GST_DEBUG_OBJECT (base, "Ignoring segment event (recreated later)");
1094 gst_event_unref (event);
1097 } else if (GST_EVENT_TYPE (event) == GST_EVENT_TAG) {
1098 /* In case we receive tags before data, store them to send later
1099 * If we already have the program, send it right away */
1100 GstTagList *taglist;
1102 gst_event_parse_tag (event, &taglist);
1104 if (demux->global_tags == NULL) {
1105 demux->global_tags = gst_tag_list_copy (taglist);
1107 /* Tags that are stream specific for the container should be considered
1108 * global for the container streams */
1109 if (gst_tag_list_get_scope (taglist) == GST_TAG_SCOPE_STREAM) {
1110 gst_tag_list_set_scope (demux->global_tags, GST_TAG_SCOPE_GLOBAL);
1113 demux->global_tags = gst_tag_list_make_writable (demux->global_tags);
1114 gst_tag_list_insert (demux->global_tags, taglist, GST_TAG_MERGE_REPLACE);
1116 clean_global_taglist (demux->global_tags);
1118 /* tags are stored to be used after if there are no streams yet,
1119 * so we should never reject */
1123 if (G_UNLIKELY (demux->program == NULL)) {
1124 #ifdef TIZEN_FEATURE_TSDEMUX_LANG_TAG
1125 if (demux->global_tags) {
1127 gst_tag_list_get_string (demux->global_tags, "language-code", &tag);
1129 demux->pending_language_tag =
1130 gst_tag_list_new (GST_TAG_LANGUAGE_CODE, tag, NULL);
1135 if (GST_EVENT_TYPE (event) == GST_EVENT_CUSTOM_DOWNSTREAM) {
1136 const GstStructure *st = gst_event_get_structure (event);
1137 if (gst_structure_has_name (st, "GstHLSMedia")) {
1138 if (demux->pending_custom_event)
1139 gst_event_unref (demux->pending_custom_event);
1140 demux->pending_custom_event = gst_event_ref (event);
1144 gst_event_unref (event);
1148 for (tmp = demux->program->stream_list; tmp; tmp = tmp->next) {
1149 TSDemuxStream *stream = (TSDemuxStream *) tmp->data;
1151 /* If we are pushing out EOS, flush out pending data first */
1152 if (GST_EVENT_TYPE (event) == GST_EVENT_EOS &&
1153 gst_pad_is_active (stream->pad))
1154 gst_ts_demux_push_pending_data (demux, stream, NULL);
1156 gst_event_ref (event);
1157 gst_pad_push_event (stream->pad, event);
1161 gst_event_unref (event);
1167 handle_psi (MpegTSBase * base, GstMpegtsSection * section)
1169 GstTSDemux *demux = (GstTSDemux *) base;
1171 if (section->section_type == GST_MPEGTS_SECTION_SCTE_SIT) {
1173 gboolean forward = FALSE;
1175 if (demux->send_scte35_events) {
1176 for (tmp = demux->program->stream_list; tmp; tmp = tmp->next) {
1177 TSDemuxStream *stream = (TSDemuxStream *) tmp->data;
1179 if (stream->stream.pid == section->pid) {
1186 /* Create a new section to travel through the pipeline, with splice
1187 * times translated from local time to running time */
1191 GstStructure *rtime_map;
1194 GstMpegtsSection *new_section =
1195 (GstMpegtsSection *) gst_mini_object_copy ((GstMiniObject *) section);
1196 GstMpegtsSCTESIT *sit =
1197 (GstMpegtsSCTESIT *) gst_mpegts_section_get_scte_sit (new_section);
1199 rtime_map = gst_structure_new_empty ("running-time-map");
1201 if (sit->fully_parsed) {
1202 if (sit->splice_time_specified) {
1204 mpegts_packetizer_pts_to_ts (base->packetizer,
1205 MPEGTIME_TO_GSTTIME (sit->splice_time +
1206 sit->pts_adjustment), demux->program->pcr_pid);
1207 gst_structure_set (rtime_map, "splice-time", G_TYPE_UINT64,
1208 gst_segment_to_running_time (&base->out_segment, GST_FORMAT_TIME,
1212 for (i = 0; i < sit->splices->len; i++) {
1214 GstMpegtsSCTESpliceEvent *sevent =
1215 g_ptr_array_index (sit->splices, i);
1217 if (sevent->program_splice_time_specified) {
1219 mpegts_packetizer_pts_to_ts_unchecked (base->packetizer,
1220 MPEGTIME_TO_GSTTIME (sevent->program_splice_time +
1221 sit->pts_adjustment), demux->program->pcr_pid);
1223 g_strdup_printf ("event-%u-splice-time",
1224 sevent->splice_event_id);
1225 gst_structure_set (rtime_map, field_name, G_TYPE_UINT64,
1226 gst_segment_to_running_time (&base->out_segment,
1227 GST_FORMAT_TIME, pts), NULL);
1228 g_free (field_name);
1233 event = gst_event_new_mpegts_section (new_section);
1234 gst_mpegts_section_unref (new_section);
1236 s = gst_event_writable_structure (event);
1237 gst_structure_set (s, "mpeg-pts-offset", G_TYPE_UINT64,
1238 demux->mpeg_pts_offset, "running-time-map", GST_TYPE_STRUCTURE,
1240 gst_structure_free (rtime_map);
1242 push_event (base, event);
1248 sink_query (MpegTSBase * base, GstQuery * query)
1250 GstTSDemux *demux = (GstTSDemux *) base;
1251 gboolean res = FALSE;
1253 switch (GST_QUERY_TYPE (query)) {
1254 case GST_QUERY_BITRATE:{
1256 GstClockTime duration;
1258 if (gst_pad_peer_query_duration (base->sinkpad, GST_FORMAT_BYTES,
1259 &size_bytes) && size_bytes > 0) {
1260 if (gst_ts_demux_get_duration (demux, &duration) && duration > 0
1261 && duration != GST_CLOCK_TIME_NONE) {
1263 gst_util_uint64_scale (8 * size_bytes, GST_SECOND, duration);
1265 GST_LOG_OBJECT (demux, "bitrate query byte length: %" G_GINT64_FORMAT
1266 " duration %" GST_TIME_FORMAT " resulting in a bitrate of %u",
1267 size_bytes, GST_TIME_ARGS (duration), bitrate);
1268 gst_query_set_bitrate (query, bitrate);
1275 res = GST_MPEGTS_BASE_CLASS (parent_class)->sink_query (base, query);
1283 add_iso639_language_to_tags (TSDemuxStream * stream, gchar * lang_code)
1287 GST_LOG_OBJECT (stream->pad, "Add language code for stream: '%s'", lang_code);
1289 if (!stream->taglist)
1290 stream->taglist = gst_tag_list_new_empty ();
1292 /* descriptor contains ISO 639-2 code, we want the ISO 639-1 code */
1293 lc = gst_tag_get_language_code (lang_code);
1295 /* Only set tag if we have a valid one */
1296 if (lc || (lang_code[0] && lang_code[1]))
1297 gst_tag_list_add (stream->taglist, GST_TAG_MERGE_REPLACE,
1298 GST_TAG_LANGUAGE_CODE, (lc) ? lc : lang_code, NULL);
1302 gst_ts_demux_create_tags (TSDemuxStream * stream)
1304 MpegTSBaseStream *bstream = (MpegTSBaseStream *) stream;
1305 const GstMpegtsDescriptor *desc = NULL;
1309 mpegts_get_descriptor_from_stream (bstream,
1310 GST_MTS_DESC_ISO_639_LANGUAGE);
1314 nb = gst_mpegts_descriptor_parse_iso_639_language_nb (desc);
1316 GST_DEBUG_OBJECT (stream->pad, "Found ISO 639 descriptor (%d entries)", nb);
1318 for (i = 0; i < nb; i++)
1319 if (gst_mpegts_descriptor_parse_iso_639_language_idx (desc, i, &lang_code,
1321 add_iso639_language_to_tags (stream, lang_code);
1329 mpegts_get_descriptor_from_stream (bstream, GST_MTS_DESC_DVB_SUBTITLING);
1334 nb = gst_mpegts_descriptor_parse_dvb_subtitling_nb (desc);
1336 GST_DEBUG_OBJECT (stream->pad, "Found SUBTITLING descriptor (%d entries)",
1339 for (i = 0; i < nb; i++)
1340 if (gst_mpegts_descriptor_parse_dvb_subtitling_idx (desc, i, &lang_code,
1341 NULL, NULL, NULL)) {
1342 add_iso639_language_to_tags (stream, lang_code);
1347 if (bstream->stream_type == GST_MPEGTS_STREAM_TYPE_PRIVATE_PES_PACKETS) {
1348 desc = mpegts_get_descriptor_from_stream_with_extension (bstream,
1349 GST_MTS_DESC_DVB_EXTENSION, GST_MTS_DESC_EXT_DVB_AUDIO_PRESELECTION);
1353 GstMpegtsAudioPreselectionDescriptor *item;
1355 if (gst_mpegts_descriptor_parse_audio_preselection_list (desc, &list)) {
1356 GST_DEBUG ("Found AUDIO PRESELECTION descriptor (%d entries)",
1359 for (i = 0; i < list->len; i++) {
1360 item = g_ptr_array_index (list, i);
1361 gst_mpegts_descriptor_parse_audio_preselection_dump (item);
1363 if (item->language_code_present) {
1364 add_iso639_language_to_tags (stream, item->language_code);
1368 g_ptr_array_unref (list);
1375 create_pad_for_stream (MpegTSBase * base, MpegTSBaseStream * bstream,
1376 MpegTSBaseProgram * program)
1378 GstTSDemux *demux = GST_TS_DEMUX (base);
1379 TSDemuxStream *stream = (TSDemuxStream *) bstream;
1381 GstCaps *caps = NULL;
1382 GstPadTemplate *template = NULL;
1383 const GstMpegtsDescriptor *desc = NULL;
1385 gboolean sparse = FALSE;
1386 gboolean is_audio = FALSE, is_video = FALSE, is_subpicture = FALSE,
1389 gst_ts_demux_create_tags (stream);
1391 GST_LOG_OBJECT (demux,
1392 "Attempting to create pad for stream 0x%04x with stream_type %d",
1393 bstream->pid, bstream->stream_type);
1395 /* First handle BluRay-specific stream types since there is some overlap
1396 * between BluRay and non-BluRay streay type identifiers */
1397 if (program->registration_id == DRF_ID_HDMV) {
1398 switch (bstream->stream_type) {
1399 case ST_BD_AUDIO_AC3:
1401 const GstMpegtsDescriptor *ac3_desc;
1403 /* ATSC ac3 audio descriptor */
1405 mpegts_get_descriptor_from_stream (bstream,
1406 GST_MTS_DESC_AC3_AUDIO_STREAM);
1407 if (ac3_desc && DESC_AC_AUDIO_STREAM_bsid (ac3_desc->data) != 16) {
1408 GST_LOG_OBJECT (demux, "ac3 audio");
1410 caps = gst_caps_new_empty_simple ("audio/x-ac3");
1413 caps = gst_caps_new_empty_simple ("audio/x-eac3");
1417 case ST_BD_AUDIO_EAC3:
1418 case ST_BD_AUDIO_AC3_PLUS:
1420 caps = gst_caps_new_empty_simple ("audio/x-eac3");
1422 case ST_BD_AUDIO_AC3_TRUE_HD:
1424 caps = gst_caps_new_empty_simple ("audio/x-true-hd");
1425 stream->target_pes_substream = 0x72;
1427 case ST_BD_AUDIO_LPCM:
1429 caps = gst_caps_new_empty_simple ("audio/x-private-ts-lpcm");
1431 case ST_BD_PGS_SUBPICTURE:
1432 is_subpicture = TRUE;
1433 caps = gst_caps_new_empty_simple ("subpicture/x-pgs");
1436 case ST_BD_AUDIO_DTS_HD:
1437 case ST_BD_AUDIO_DTS_HD_MASTER_AUDIO:
1439 caps = gst_caps_new_empty_simple ("audio/x-dts");
1440 stream->target_pes_substream = 0x71;
1448 /* Handle non-BluRay stream types */
1449 switch (bstream->stream_type) {
1450 case GST_MPEGTS_STREAM_TYPE_VIDEO_MPEG1:
1451 case GST_MPEGTS_STREAM_TYPE_VIDEO_MPEG2:
1452 case ST_PS_VIDEO_MPEG2_DCII:
1453 /* FIXME : Use DCII registration code (ETV1 ?) to handle that special
1454 * Stream type (ST_PS_VIDEO_MPEG2_DCII) */
1455 /* FIXME : Use video descriptor (0x1) to refine caps with:
1457 * * profile_and_level
1459 GST_LOG_OBJECT (demux, "mpeg video");
1461 caps = gst_caps_new_simple ("video/mpeg",
1462 "mpegversion", G_TYPE_INT,
1463 bstream->stream_type == GST_MPEGTS_STREAM_TYPE_VIDEO_MPEG1 ? 1 : 2,
1464 "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
1467 case GST_MPEGTS_STREAM_TYPE_AUDIO_MPEG1:
1468 case GST_MPEGTS_STREAM_TYPE_AUDIO_MPEG2:
1469 GST_LOG_OBJECT (demux, "mpeg audio");
1472 gst_caps_new_simple ("audio/mpeg", "mpegversion", G_TYPE_INT, 1,
1474 /* HDV is always mpeg 1 audio layer 2 */
1475 if (program->registration_id == DRF_ID_TSHV)
1476 gst_caps_set_simple (caps, "layer", G_TYPE_INT, 2, NULL);
1478 case GST_MPEGTS_STREAM_TYPE_PRIVATE_PES_PACKETS:
1479 GST_LOG_OBJECT (demux, "private data");
1480 /* FIXME: Move all of this into a common method (there might be other
1481 * types also, depending on registratino descriptors also
1484 desc = mpegts_get_descriptor_from_stream_with_extension (bstream,
1485 GST_MTS_DESC_DVB_EXTENSION, GST_MTS_DESC_EXT_DVB_AC4);
1487 GST_LOG_OBJECT (demux, "ac4 audio");
1489 caps = gst_caps_new_empty_simple ("audio/x-ac4");
1493 desc = mpegts_get_descriptor_from_stream (bstream, GST_MTS_DESC_DVB_AC3);
1495 GST_LOG_OBJECT (demux, "ac3 audio");
1497 caps = gst_caps_new_empty_simple ("audio/x-ac3");
1502 mpegts_get_descriptor_from_stream (bstream,
1503 GST_MTS_DESC_DVB_ENHANCED_AC3);
1505 GST_LOG_OBJECT (demux, "ac3 audio");
1507 caps = gst_caps_new_empty_simple ("audio/x-eac3");
1511 mpegts_get_descriptor_from_stream (bstream,
1512 GST_MTS_DESC_DVB_TELETEXT);
1514 GST_LOG_OBJECT (demux, "teletext");
1516 caps = gst_caps_new_empty_simple ("application/x-teletext");
1521 mpegts_get_descriptor_from_stream (bstream,
1522 GST_MTS_DESC_DVB_SUBTITLING);
1524 GST_LOG_OBJECT (demux, "subtitling");
1525 is_subpicture = TRUE;
1526 caps = gst_caps_new_empty_simple ("subpicture/x-dvb");
1531 switch (bstream->registration_id) {
1535 /* SMPTE registered DTS */
1537 caps = gst_caps_new_empty_simple ("audio/x-dts");
1541 caps = gst_caps_new_empty_simple ("audio/x-smpte-302m");
1544 desc = mpegts_get_descriptor_from_stream (bstream,
1545 GST_MTS_DESC_DVB_EXTENSION);
1546 if (desc != NULL && desc->tag_extension == 0x80 && desc->length >= 1) { /* User defined (provisional Opus) */
1547 guint8 channel_config_code;
1550 /* skip tag, length and tag_extension */
1551 gst_byte_reader_init (&br, desc->data + 3, desc->length - 1);
1552 channel_config_code = gst_byte_reader_get_uint8_unchecked (&br);
1554 if ((channel_config_code & 0x8f) <= 8) {
1555 static const guint8 coupled_stream_counts[9] = {
1556 1, 0, 1, 1, 2, 2, 2, 3, 3
1558 static const guint8 channel_map_a[8][8] = {
1565 {0, 4, 1, 2, 3, 5, 6},
1566 {0, 6, 1, 2, 3, 4, 5, 7},
1568 static const guint8 channel_map_b[8][8] = {
1575 {0, 1, 2, 3, 4, 5, 6},
1576 {0, 1, 2, 3, 4, 5, 6, 7},
1579 gint channels = -1, stream_count, coupled_count, mapping_family;
1580 guint8 *channel_mapping = NULL;
1582 channels = channel_config_code ? (channel_config_code & 0x0f) : 2;
1583 if (channel_config_code == 0 || channel_config_code == 0x80) {
1586 mapping_family = 255;
1587 if (channel_config_code == 0) {
1594 channel_mapping = g_new0 (guint8, channels);
1595 memcpy (channel_mapping, &channel_map_a[1], channels);
1596 } else if (channel_config_code <= 8) {
1597 mapping_family = (channels > 2) ? 1 : 0;
1599 channel_config_code -
1600 coupled_stream_counts[channel_config_code];
1601 coupled_count = coupled_stream_counts[channel_config_code];
1602 if (mapping_family != 0) {
1603 channel_mapping = g_new0 (guint8, channels);
1604 memcpy (channel_mapping, &channel_map_a[channels - 1],
1607 } else if (channel_config_code >= 0x82
1608 && channel_config_code <= 0x88) {
1610 stream_count = channels;
1612 channel_mapping = g_new0 (guint8, channels);
1613 memcpy (channel_mapping, &channel_map_b[channels - 1],
1615 } else if (channel_config_code == 0x81) {
1616 if (gst_byte_reader_get_remaining (&br) < 2) {
1617 GST_WARNING_OBJECT (demux,
1618 "Invalid Opus descriptor with extended channel configuration");
1623 channels = gst_byte_reader_get_uint8_unchecked (&br);
1624 mapping_family = gst_byte_reader_get_uint8_unchecked (&br);
1626 /* Overwrite values from above */
1627 if (channels == 0) {
1628 GST_WARNING_OBJECT (demux,
1629 "Invalid Opus descriptor with extended channel configuration");
1634 if (mapping_family == 0 && channels <= 2) {
1635 stream_count = channels - coupled_stream_counts[channels];
1636 coupled_count = coupled_stream_counts[channels];
1638 GstBitReader breader;
1639 guint8 stream_count_minus_one, coupled_stream_count;
1640 gint stream_count_minus_one_len, coupled_stream_count_len;
1641 gint channel_mapping_len, i;
1642 guint remaining_bytes;
1644 remaining_bytes = gst_byte_reader_get_remaining (&br);
1645 gst_bit_reader_init (&breader,
1646 gst_byte_reader_get_data_unchecked
1647 (&br, remaining_bytes), remaining_bytes);
1649 stream_count_minus_one_len = ceil (_gst_log2 (channels));
1650 if (!gst_bit_reader_get_bits_uint8 (&breader,
1651 &stream_count_minus_one,
1652 stream_count_minus_one_len)) {
1653 GST_WARNING_OBJECT (demux,
1654 "Invalid Opus descriptor with extended channel configuration");
1659 stream_count = stream_count_minus_one + 1;
1660 coupled_stream_count_len =
1661 ceil (_gst_log2 (stream_count_minus_one + 2));
1663 if (!gst_bit_reader_get_bits_uint8 (&breader,
1664 &coupled_stream_count, coupled_stream_count_len)) {
1665 GST_WARNING_OBJECT (demux,
1666 "Invalid Opus descriptor with extended channel configuration");
1671 coupled_count = coupled_stream_count;
1673 channel_mapping_len =
1674 ceil (_gst_log2 (stream_count_minus_one + 1 +
1675 coupled_stream_count + 1));
1676 channel_mapping = g_new0 (guint8, channels);
1677 for (i = 0; i < channels; i++) {
1678 if (!gst_bit_reader_get_bits_uint8 (&breader,
1679 &channel_mapping[i], channel_mapping_len)) {
1680 GST_WARNING_OBJECT (demux,
1681 "Invalid Opus descriptor with extended channel configuration");
1687 if (i != channels) {
1689 g_free (channel_mapping);
1690 channel_mapping = NULL;
1695 g_assert_not_reached ();
1698 if (channels != -1) {
1701 gst_codec_utils_opus_create_caps (48000, channels,
1702 mapping_family, stream_count, coupled_count,
1705 g_free (channel_mapping);
1708 GST_WARNING_OBJECT (demux,
1709 "unexpected channel config code 0x%02x", channel_config_code);
1712 GST_WARNING_OBJECT (demux, "Opus, but no extension descriptor");
1717 caps = gst_caps_new_simple ("video/x-h265",
1718 "stream-format", G_TYPE_STRING, "byte-stream", NULL);
1723 caps = gst_caps_new_simple ("meta/x-klv",
1724 "parsed", G_TYPE_BOOLEAN, TRUE, NULL);
1728 caps = gst_caps_new_empty_simple ("audio/x-ac4");
1734 /* hack for itv hd (sid 10510, video pid 3401 */
1735 if (program->program_number == 10510 && bstream->pid == 3401) {
1737 caps = gst_caps_new_simple ("video/x-h264",
1738 "stream-format", G_TYPE_STRING, "byte-stream", NULL);
1742 /* FIXME : Should only be used with specific PMT registration_descriptor */
1743 /* We don't expose those streams since they're only helper streams */
1744 /* template = gst_static_pad_template_get (&private_template); */
1745 /* name = g_strdup_printf ("private_%04x", bstream->pid); */
1746 /* caps = gst_caps_new_simple ("hdv/aux-v", NULL); */
1749 /* FIXME : Should only be used with specific PMT registration_descriptor */
1750 /* We don't expose those streams since they're only helper streams */
1751 /* template = gst_static_pad_template_get (&private_template); */
1752 /* name = g_strdup_printf ("private_%04x", bstream->pid); */
1753 /* caps = gst_caps_new_simple ("hdv/aux-a", NULL); */
1755 case GST_MPEGTS_STREAM_TYPE_AUDIO_AAC_ADTS:
1757 /* prefer mpegversion 4 since it's more commonly supported one */
1758 caps = gst_caps_new_simple ("audio/mpeg",
1759 "mpegversion", G_TYPE_INT, 4,
1760 "stream-format", G_TYPE_STRING, "adts", NULL);
1761 /* we will set caps later once parsing adts header is done */
1762 stream->atdsInfos.mpegversion = 4;
1764 case GST_MPEGTS_STREAM_TYPE_AUDIO_AAC_LATM:
1766 caps = gst_caps_new_simple ("audio/mpeg",
1767 "mpegversion", G_TYPE_INT, 4,
1768 "stream-format", G_TYPE_STRING, "loas", NULL);
1770 case GST_MPEGTS_STREAM_TYPE_VIDEO_MPEG4:
1772 caps = gst_caps_new_simple ("video/mpeg",
1773 "mpegversion", G_TYPE_INT, 4,
1774 "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
1776 case GST_MPEGTS_STREAM_TYPE_VIDEO_H264:
1778 caps = gst_caps_new_simple ("video/x-h264",
1779 "stream-format", G_TYPE_STRING, "byte-stream", NULL);
1781 case GST_MPEGTS_STREAM_TYPE_VIDEO_HEVC:
1783 caps = gst_caps_new_simple ("video/x-h265",
1784 "stream-format", G_TYPE_STRING, "byte-stream", NULL);
1786 case GST_MPEGTS_STREAM_TYPE_VIDEO_JP2K:
1789 mpegts_get_descriptor_from_stream (bstream, GST_MTS_DESC_J2K_VIDEO);
1791 caps = gst_caps_new_empty_simple ("image/x-jpc");
1795 guint16 DEN_frame_rate = 0;
1796 guint16 NUM_frame_rate = 0;
1797 guint8 color_specification = 0;
1798 guint8 remaining_8b = 0;
1799 gboolean interlaced_video = 0;
1800 const gchar *interlace_mode = NULL;
1801 const gchar *colorspace = NULL;
1802 const gchar *colorimetry_mode = NULL;
1803 guint16 profile_and_level G_GNUC_UNUSED;
1804 guint32 horizontal_size G_GNUC_UNUSED;
1805 guint32 vertical_size G_GNUC_UNUSED;
1806 guint32 max_bit_rate G_GNUC_UNUSED;
1807 guint32 max_buffer_size G_GNUC_UNUSED;
1808 const guint desc_min_length = 24;
1810 if (desc->length < desc_min_length) {
1811 GST_ERROR_OBJECT (demux,
1812 "GST_MPEGTS_STREAM_TYPE_VIDEO_JP2K: descriptor length %d too short",
1817 /* Skip the descriptor tag and length */
1818 gst_byte_reader_init (&br, desc->data + 2, desc->length);
1820 profile_and_level = gst_byte_reader_get_uint16_be_unchecked (&br);
1821 horizontal_size = gst_byte_reader_get_uint32_be_unchecked (&br);
1822 vertical_size = gst_byte_reader_get_uint32_be_unchecked (&br);
1823 max_bit_rate = gst_byte_reader_get_uint32_be_unchecked (&br);
1824 max_buffer_size = gst_byte_reader_get_uint32_be_unchecked (&br);
1825 DEN_frame_rate = gst_byte_reader_get_uint16_be_unchecked (&br);
1826 NUM_frame_rate = gst_byte_reader_get_uint16_be_unchecked (&br);
1827 color_specification = gst_byte_reader_get_uint8_unchecked (&br);
1828 remaining_8b = gst_byte_reader_get_uint8_unchecked (&br);
1829 interlaced_video = remaining_8b & 0x40;
1830 /* we don't support demuxing interlaced at the moment */
1831 if (interlaced_video) {
1832 GST_ERROR_OBJECT (demux,
1833 "GST_MPEGTS_STREAM_TYPE_VIDEO_JP2K: interlaced video not supported");
1836 interlace_mode = "progressive";
1837 stream->jp2kInfos.interlace = FALSE;
1839 switch (color_specification) {
1840 case GST_MPEGTSDEMUX_JPEG2000_COLORSPEC_SRGB:
1841 colorspace = "sRGB";
1842 colorimetry_mode = GST_VIDEO_COLORIMETRY_SRGB;
1844 case GST_MPEGTSDEMUX_JPEG2000_COLORSPEC_REC601:
1845 colorspace = "sYUV";
1846 colorimetry_mode = GST_VIDEO_COLORIMETRY_BT601;
1848 case GST_MPEGTSDEMUX_JPEG2000_COLORSPEC_REC709:
1849 case GST_MPEGTSDEMUX_JPEG2000_COLORSPEC_CIELUV:
1850 colorspace = "sYUV";
1851 colorimetry_mode = GST_VIDEO_COLORIMETRY_BT709;
1856 caps = gst_caps_new_simple ("image/x-jpc",
1857 "framerate", GST_TYPE_FRACTION, NUM_frame_rate, DEN_frame_rate,
1858 "interlace-mode", G_TYPE_STRING, interlace_mode,
1859 "colorimetry", G_TYPE_STRING, colorimetry_mode,
1860 "colorspace", G_TYPE_STRING, colorspace, NULL);
1863 case ST_VIDEO_DIRAC:
1864 if (bstream->registration_id == 0x64726163) {
1865 GST_LOG_OBJECT (demux, "dirac");
1868 caps = gst_caps_new_empty_simple ("video/x-dirac");
1871 case ST_PRIVATE_EA: /* Try to detect a VC1 stream */
1873 gboolean is_vc1 = FALSE;
1875 /* Note/FIXME: RP-227 specifies that the registration descriptor
1876 * for vc1 can also contain other information, such as profile,
1877 * level, alignment, buffer_size, .... */
1878 if (bstream->registration_id == DRF_ID_VC1)
1881 GST_WARNING_OBJECT (demux, "0xea private stream type found but "
1882 "no descriptor for VC1. Assuming plain VC1.");
1886 caps = gst_caps_new_simple ("video/x-wmv",
1887 "wmvversion", G_TYPE_INT, 3, "format", G_TYPE_STRING, "WVC1", NULL);
1891 case ST_PS_AUDIO_AC3:
1892 /* DVB_ENHANCED_AC3 */
1894 mpegts_get_descriptor_from_stream (bstream,
1895 GST_MTS_DESC_DVB_ENHANCED_AC3);
1898 caps = gst_caps_new_empty_simple ("audio/x-eac3");
1902 /* If stream has ac3 descriptor
1903 * OR program is ATSC (GA94)
1904 * OR stream registration is AC-3
1905 * then it's regular AC3 */
1906 if (bstream->registration_id == DRF_ID_AC3 ||
1907 program->registration_id == DRF_ID_GA94 ||
1908 mpegts_get_descriptor_from_stream (bstream, GST_MTS_DESC_DVB_AC3)) {
1910 caps = gst_caps_new_empty_simple ("audio/x-ac3");
1914 GST_WARNING_OBJECT (demux,
1915 "AC3 stream type found but no guaranteed "
1916 "way found to differentiate between AC3 and EAC3. "
1917 "Assuming plain AC3.");
1919 caps = gst_caps_new_empty_simple ("audio/x-ac3");
1921 case ST_PS_AUDIO_EAC3:
1923 /* ATSC_ENHANCED_AC3 */
1924 if (bstream->registration_id == DRF_ID_EAC3 ||
1925 mpegts_get_descriptor_from_stream (bstream, GST_MTS_DESC_ATSC_EAC3)) {
1927 caps = gst_caps_new_empty_simple ("audio/x-eac3");
1931 GST_ELEMENT_WARNING (demux, STREAM, DEMUX,
1932 ("Assuming ATSC E-AC3 audio stream."),
1933 ("ATSC E-AC3 stream type found but no guarantee way found to "
1934 "differentiate among other standards (DVB, ISDB and etc..)"));
1937 caps = gst_caps_new_empty_simple ("audio/x-eac3");
1940 case ST_PS_AUDIO_LPCM2:
1942 caps = gst_caps_new_empty_simple ("audio/x-private2-lpcm");
1944 case ST_PS_AUDIO_DTS:
1946 caps = gst_caps_new_empty_simple ("audio/x-dts");
1948 case ST_PS_AUDIO_LPCM:
1950 caps = gst_caps_new_empty_simple ("audio/x-lpcm");
1952 case ST_PS_DVD_SUBPICTURE:
1953 is_subpicture = TRUE;
1954 caps = gst_caps_new_empty_simple ("subpicture/x-dvd");
1958 /* hack for Chinese AVS video stream which use 0x42 as stream_id
1959 * NOTE: this is unofficial and within the ISO reserved range. */
1961 caps = gst_caps_new_empty_simple ("video/x-cavs");
1964 GST_DEBUG_OBJECT (demux,
1965 "Non-media stream (stream_type:0x%x). Not creating pad",
1966 bstream->stream_type);
1973 template = gst_static_pad_template_get (&audio_template);
1975 g_strdup_printf ("audio_%01x_%04x", demux->program_generation,
1977 gst_stream_set_stream_type (bstream->stream_object,
1978 GST_STREAM_TYPE_AUDIO);
1979 } else if (is_video) {
1980 template = gst_static_pad_template_get (&video_template);
1982 g_strdup_printf ("video_%01x_%04x", demux->program_generation,
1984 gst_stream_set_stream_type (bstream->stream_object,
1985 GST_STREAM_TYPE_VIDEO);
1986 } else if (is_private) {
1987 template = gst_static_pad_template_get (&private_template);
1989 g_strdup_printf ("private_%01x_%04x", demux->program_generation,
1991 } else if (is_subpicture) {
1992 template = gst_static_pad_template_get (&subpicture_template);
1994 g_strdup_printf ("subpicture_%01x_%04x", demux->program_generation,
1996 gst_stream_set_stream_type (bstream->stream_object, GST_STREAM_TYPE_TEXT);
1998 g_assert_not_reached ();
2002 if (template && name && caps) {
2004 const gchar *stream_id;
2006 GST_LOG_OBJECT (demux,
2007 "stream:%p creating pad with name %s and caps %" GST_PTR_FORMAT,
2008 stream, name, caps);
2009 pad = gst_pad_new_from_template (template, name);
2010 gst_pad_set_active (pad, TRUE);
2011 gst_pad_use_fixed_caps (pad);
2012 stream_id = gst_stream_get_stream_id (bstream->stream_object);
2014 event = gst_pad_get_sticky_event (base->sinkpad, GST_EVENT_STREAM_START, 0);
2016 if (gst_event_parse_group_id (event, &demux->group_id))
2017 demux->have_group_id = TRUE;
2019 demux->have_group_id = FALSE;
2020 gst_event_unref (event);
2021 } else if (!demux->have_group_id) {
2022 demux->have_group_id = TRUE;
2023 demux->group_id = gst_util_group_id_next ();
2025 event = gst_event_new_stream_start (stream_id);
2026 gst_event_set_stream (event, bstream->stream_object);
2027 if (demux->have_group_id)
2028 gst_event_set_group_id (event, demux->group_id);
2030 gst_event_set_stream_flags (event, GST_STREAM_FLAG_SPARSE);
2031 gst_stream_set_stream_flags (bstream->stream_object,
2032 GST_STREAM_FLAG_SPARSE);
2034 stream->sparse = sparse;
2035 gst_stream_set_caps (bstream->stream_object, caps);
2036 if (!stream->taglist)
2037 stream->taglist = gst_tag_list_new_empty ();
2038 gst_pb_utils_add_codec_description_to_tag_list (stream->taglist, NULL,
2040 gst_stream_set_tags (bstream->stream_object, stream->taglist);
2042 gst_pad_push_event (pad, event);
2043 gst_pad_set_caps (pad, caps);
2044 gst_pad_set_query_function (pad, gst_ts_demux_srcpad_query);
2045 gst_pad_set_event_function (pad, gst_ts_demux_srcpad_event);
2050 gst_object_unref (template);
2052 gst_caps_unref (caps);
2058 gst_ts_demux_stream_added (MpegTSBase * base, MpegTSBaseStream * bstream,
2059 MpegTSBaseProgram * program)
2061 GstTSDemux *demux = (GstTSDemux *) base;
2062 TSDemuxStream *stream = (TSDemuxStream *) bstream;
2065 /* Create the pad */
2066 if (bstream->stream_type != 0xff) {
2067 stream->pad = create_pad_for_stream (base, bstream, program);
2069 gst_flow_combiner_add_pad (demux->flowcombiner, stream->pad);
2072 if (base->mode != BASE_MODE_PUSHING
2073 && bstream->stream_type == GST_MPEGTS_STREAM_TYPE_VIDEO_H264) {
2074 stream->scan_function =
2075 (GstTsDemuxKeyFrameScanFunction) scan_keyframe_h264;
2077 stream->scan_function = NULL;
2080 stream->active = FALSE;
2082 stream->need_newsegment = TRUE;
2083 /* Reset segment if we're not doing an accurate seek */
2084 demux->reset_segment =
2085 (!(base->out_segment.flags & GST_SEEK_FLAG_ACCURATE));
2086 stream->needs_keyframe = FALSE;
2087 stream->discont = TRUE;
2088 stream->pts = GST_CLOCK_TIME_NONE;
2089 stream->dts = GST_CLOCK_TIME_NONE;
2090 stream->first_pts = GST_CLOCK_TIME_NONE;
2091 stream->raw_pts = -1;
2092 stream->raw_dts = -1;
2093 stream->pending_ts = TRUE;
2094 stream->nb_out_buffers = 0;
2095 stream->gap_ref_buffers = 0;
2096 stream->gap_ref_pts = GST_CLOCK_TIME_NONE;
2097 /* Only wait for a valid timestamp if we have a PCR_PID */
2098 stream->pending_ts = program->pcr_pid < 0x1fff;
2099 stream->continuity_counter = CONTINUITY_UNSET;
2102 return (stream->pad != NULL);
2106 tsdemux_h264_parsing_info_clear (TSDemuxH264ParsingInfos * h264infos)
2108 clear_simple_buffer (&h264infos->framedata);
2110 if (h264infos->parser) {
2111 gst_h264_nal_parser_free (h264infos->parser);
2112 gst_byte_writer_free (h264infos->sps);
2113 gst_byte_writer_free (h264infos->pps);
2114 gst_byte_writer_free (h264infos->sei);
2119 gst_ts_demux_stream_removed (MpegTSBase * base, MpegTSBaseStream * bstream)
2121 TSDemuxStream *stream = (TSDemuxStream *) bstream;
2124 gst_flow_combiner_remove_pad (GST_TS_DEMUX_CAST (base)->flowcombiner,
2126 if (stream->active) {
2128 if (gst_pad_is_active (stream->pad)) {
2129 /* Flush out all data */
2130 GST_DEBUG_OBJECT (stream->pad, "Flushing out pending data");
2131 gst_ts_demux_push_pending_data ((GstTSDemux *) base, stream, NULL);
2133 GST_DEBUG_OBJECT (stream->pad, "Pushing out EOS");
2134 gst_pad_push_event (stream->pad, gst_event_new_eos ());
2135 gst_pad_set_active (stream->pad, FALSE);
2138 GST_DEBUG_OBJECT (stream->pad, "Removing pad");
2139 gst_element_remove_pad (GST_ELEMENT_CAST (base), stream->pad);
2140 stream->active = FALSE;
2142 gst_object_unref (stream->pad);
2147 gst_ts_demux_stream_flush (stream, GST_TS_DEMUX_CAST (base), TRUE);
2149 if (stream->taglist != NULL) {
2150 gst_tag_list_unref (stream->taglist);
2151 stream->taglist = NULL;
2154 tsdemux_h264_parsing_info_clear (&stream->h264infos);
2158 activate_pad_for_stream (GstTSDemux * tsdemux, TSDemuxStream * stream)
2161 GST_DEBUG_OBJECT (tsdemux, "Activating pad %s:%s for stream %p",
2162 GST_DEBUG_PAD_NAME (stream->pad), stream);
2163 gst_element_add_pad ((GstElement *) tsdemux, stream->pad);
2164 stream->active = TRUE;
2165 GST_DEBUG_OBJECT (stream->pad, "done adding pad");
2166 } else if (((MpegTSBaseStream *) stream)->stream_type != 0xff) {
2167 GST_DEBUG_OBJECT (tsdemux,
2168 "stream %p (pid 0x%04x, type:0x%02x) has no pad", stream,
2169 ((MpegTSBaseStream *) stream)->pid,
2170 ((MpegTSBaseStream *) stream)->stream_type);
2175 gst_ts_demux_stream_flush (TSDemuxStream * stream, GstTSDemux * tsdemux,
2178 GST_DEBUG ("flushing stream %p", stream);
2180 g_free (stream->data);
2181 stream->data = NULL;
2182 g_free (stream->pending_header_data);
2183 stream->pending_header_data = NULL;
2184 stream->pending_header_size = 0;
2185 stream->state = PENDING_PACKET_EMPTY;
2186 stream->expected_size = 0;
2187 stream->allocated_size = 0;
2188 stream->current_size = 0;
2189 stream->discont = TRUE;
2190 stream->pts = GST_CLOCK_TIME_NONE;
2191 stream->dts = GST_CLOCK_TIME_NONE;
2192 stream->raw_pts = -1;
2193 stream->raw_dts = -1;
2194 stream->pending_ts = TRUE;
2195 stream->nb_out_buffers = 0;
2196 stream->gap_ref_buffers = 0;
2197 stream->gap_ref_pts = GST_CLOCK_TIME_NONE;
2198 stream->continuity_counter = CONTINUITY_UNSET;
2200 if (G_UNLIKELY (stream->pending)) {
2203 GST_DEBUG ("clearing pending %p", stream);
2204 for (tmp = stream->pending; tmp; tmp = tmp->next) {
2205 PendingBuffer *pend = (PendingBuffer *) tmp->data;
2206 gst_buffer_unref (pend->buffer);
2207 g_slice_free (PendingBuffer, pend);
2209 g_list_free (stream->pending);
2210 stream->pending = NULL;
2214 stream->first_pts = GST_CLOCK_TIME_NONE;
2215 stream->need_newsegment = TRUE;
2220 gst_ts_demux_flush_streams (GstTSDemux * demux, gboolean hard)
2223 if (!demux->program)
2226 for (walk = demux->program->stream_list; walk; walk = g_list_next (walk))
2227 gst_ts_demux_stream_flush (walk->data, demux, hard);
2231 gst_ts_demux_can_remove_program (MpegTSBase * base, MpegTSBaseProgram * program)
2233 GstTSDemux *demux = GST_TS_DEMUX (base);
2235 /* If it's our current active program, we return FALSE, we'll deactivate it
2236 * ourselves when the next program gets activated */
2237 if (demux->program == program) {
2239 ("Attempting to remove current program, delaying until new program gets activated");
2240 demux->previous_program = program;
2241 demux->program_number = -1;
2248 gst_ts_demux_update_program (MpegTSBase * base, MpegTSBaseProgram * program)
2250 GstTSDemux *demux = GST_TS_DEMUX (base);
2253 GST_DEBUG ("Updating program %d", program->program_number);
2254 /* Emit collection message */
2255 gst_element_post_message ((GstElement *) base,
2256 gst_message_new_stream_collection ((GstObject *) base,
2257 program->collection));
2259 /* Add all streams, then fire no-more-pads */
2260 for (tmp = program->stream_list; tmp; tmp = tmp->next) {
2261 TSDemuxStream *stream = (TSDemuxStream *) tmp->data;
2262 #ifdef TIZEN_FEATURE_TSDEMUX_UPDATE_STREAM
2264 || (stream->pad && !stream->active)) {
2268 activate_pad_for_stream (demux, stream);
2269 if (stream->sparse) {
2270 /* force sending of pending sticky events which have been stored on the
2271 * pad already and which otherwise would only be sent on the first buffer
2272 * or serialized event (which means very late in case of subtitle streams),
2273 * and playsink waits for stream-start or another serialized event */
2274 GST_DEBUG_OBJECT (stream->pad, "sparse stream, pushing GAP event");
2275 gst_pad_push_event (stream->pad, gst_event_new_gap (0, 0));
2279 gst_pad_push_event (stream->pad,
2280 gst_event_new_stream_collection (program->collection));
2285 gst_ts_demux_program_started (MpegTSBase * base, MpegTSBaseProgram * program)
2287 GstTSDemux *demux = GST_TS_DEMUX (base);
2289 GST_DEBUG ("Current program %d, new program %d requested program %d",
2290 (gint) demux->program_number, program->program_number,
2291 demux->requested_program_number);
2293 if (demux->requested_program_number == program->program_number ||
2294 (demux->requested_program_number == -1 && demux->program_number == -1)) {
2296 gboolean have_pads = FALSE;
2298 GST_LOG ("program %d started", program->program_number);
2299 demux->program_number = program->program_number;
2300 demux->program = program;
2302 /* Increment the program_generation counter */
2303 demux->program_generation = (demux->program_generation + 1) & 0xf;
2305 /* Emit collection message */
2306 gst_element_post_message ((GstElement *) base,
2307 gst_message_new_stream_collection ((GstObject *) base,
2308 program->collection));
2310 /* If this is not the initial program, we need to calculate
2312 g_mutex_lock (&demux->lock);
2313 gst_event_replace (&demux->segment_event, NULL);
2314 g_mutex_unlock (&demux->lock);
2316 /* DRAIN ALL STREAMS FIRST ! */
2317 if (demux->previous_program) {
2319 GST_DEBUG_OBJECT (demux, "Draining previous program");
2320 for (tmp = demux->previous_program->stream_list; tmp; tmp = tmp->next) {
2321 TSDemuxStream *stream = (TSDemuxStream *) tmp->data;
2323 gst_ts_demux_push_pending_data (demux, stream,
2324 demux->previous_program);
2328 /* Add all streams, then fire no-more-pads */
2329 for (tmp = program->stream_list; tmp; tmp = tmp->next) {
2330 TSDemuxStream *stream = (TSDemuxStream *) tmp->data;
2331 activate_pad_for_stream (demux, stream);
2336 /* If there was a previous program, now is the time to deactivate it
2337 * and remove old pads (including pushing EOS) */
2338 if (demux->previous_program) {
2339 GST_DEBUG ("Deactivating previous program");
2340 mpegts_base_deactivate_and_free_program (base, demux->previous_program);
2341 demux->previous_program = NULL;
2345 /* If we had no pads, this stream is likely corrupted or unsupported and
2346 * there's not much we can do at this point */
2347 GST_ELEMENT_ERROR (demux, STREAM, WRONG_TYPE,
2348 ("This stream contains no valid or supported streams."),
2349 ("activating program but got no pads"));
2353 /* If any of the stream is sparse, push a GAP event before anything else
2354 * This is done here, and not in activate_pad_for_stream() because pushing
2355 * a GAP event *is* considering data, and we want to ensure the (potential)
2356 * old pads are all removed before we push any data on the new ones */
2357 for (tmp = program->stream_list; tmp; tmp = tmp->next) {
2358 TSDemuxStream *stream = (TSDemuxStream *) tmp->data;
2359 if (stream->sparse) {
2360 /* force sending of pending sticky events which have been stored on the
2361 * pad already and which otherwise would only be sent on the first buffer
2362 * or serialized event (which means very late in case of subtitle streams),
2363 * and playsink waits for stream-start or another serialized event */
2364 GST_DEBUG_OBJECT (stream->pad, "sparse stream, pushing GAP event");
2365 gst_pad_push_event (stream->pad, gst_event_new_gap (0, 0));
2368 gst_pad_push_event (stream->pad,
2369 gst_event_new_stream_collection (program->collection));
2372 gst_element_no_more_pads ((GstElement *) demux);
2377 gst_ts_demux_program_stopped (MpegTSBase * base, MpegTSBaseProgram * program)
2379 GstTSDemux *demux = GST_TS_DEMUX (base);
2381 if (demux->program == program) {
2382 demux->program = NULL;
2383 demux->program_number = -1;
2389 gst_ts_demux_record_pts (GstTSDemux * demux, TSDemuxStream * stream,
2390 guint64 pts, guint64 offset)
2392 MpegTSBaseStream *bs = (MpegTSBaseStream *) stream;
2393 MpegTSBase *base = GST_MPEGTS_BASE (demux);
2395 stream->raw_pts = pts;
2397 stream->pts = GST_CLOCK_TIME_NONE;
2401 GST_LOG ("pid 0x%04x raw pts:%" G_GUINT64_FORMAT " at offset %"
2402 G_GUINT64_FORMAT, bs->pid, pts, offset);
2404 /* Compute PTS in GstClockTime */
2406 mpegts_packetizer_pts_to_ts (MPEG_TS_BASE_PACKETIZER (demux),
2407 MPEGTIME_TO_GSTTIME (pts), demux->program->pcr_pid);
2409 if (base->out_segment.format == GST_FORMAT_TIME)
2410 demux->mpeg_pts_offset =
2411 (GSTTIME_TO_MPEGTIME (gst_segment_to_running_time (&base->out_segment,
2412 GST_FORMAT_TIME, stream->pts)) - pts) & 0x1ffffffff;
2414 /* Sanity check, some stream have completely different PTS vs DTS. If that
2415 * happens we only keep the DTS */
2416 if (GST_CLOCK_TIME_IS_VALID (stream->pts) &&
2417 GST_CLOCK_TIME_IS_VALID (stream->dts) &&
2418 ABSDIFF (stream->pts, stream->dts) > 5 * GST_SECOND) {
2419 GST_WARNING ("pid 0x%04x PTS %" GST_TIME_FORMAT
2420 " differs too much against DTS %" GST_TIME_FORMAT ", discarding it",
2421 bs->pid, GST_TIME_ARGS (stream->pts), GST_TIME_ARGS (stream->dts));
2422 stream->raw_pts = stream->raw_dts;
2423 stream->pts = stream->dts;
2427 GST_LOG ("pid 0x%04x Stored PTS %" G_GUINT64_FORMAT, bs->pid, stream->pts);
2429 if (G_UNLIKELY (demux->emit_statistics)) {
2431 st = gst_structure_new_id_empty (QUARK_TSDEMUX);
2432 gst_structure_id_set (st,
2433 QUARK_PID, G_TYPE_UINT, bs->pid,
2434 QUARK_OFFSET, G_TYPE_UINT64, offset, QUARK_PTS, G_TYPE_UINT64, pts,
2435 #ifdef TIZEN_FEATURE_HLS_WEBVTT
2436 QUARK_BUFFER_PTS, G_TYPE_UINT64, stream->pts,
2439 gst_element_post_message (GST_ELEMENT_CAST (demux),
2440 gst_message_new_element (GST_OBJECT (demux), st));
2445 gst_ts_demux_record_dts (GstTSDemux * demux, TSDemuxStream * stream,
2446 guint64 dts, guint64 offset)
2448 MpegTSBaseStream *bs = (MpegTSBaseStream *) stream;
2450 stream->raw_dts = dts;
2452 stream->dts = GST_CLOCK_TIME_NONE;
2456 GST_LOG ("pid 0x%04x raw dts:%" G_GUINT64_FORMAT " at offset %"
2457 G_GUINT64_FORMAT, bs->pid, dts, offset);
2459 /* Compute DTS in GstClockTime */
2461 mpegts_packetizer_pts_to_ts (MPEG_TS_BASE_PACKETIZER (demux),
2462 MPEGTIME_TO_GSTTIME (dts), demux->program->pcr_pid);
2464 GST_LOG ("pid 0x%04x Stored DTS %" G_GUINT64_FORMAT, bs->pid, stream->dts);
2466 if (G_UNLIKELY (demux->emit_statistics)) {
2468 st = gst_structure_new_id_empty (QUARK_TSDEMUX);
2469 gst_structure_id_set (st,
2470 QUARK_PID, G_TYPE_UINT, bs->pid,
2471 QUARK_OFFSET, G_TYPE_UINT64, offset, QUARK_DTS, G_TYPE_UINT64, dts,
2473 gst_element_post_message (GST_ELEMENT_CAST (demux),
2474 gst_message_new_element (GST_OBJECT (demux), st));
2478 /* This is called when we haven't got a valid initial PTS/DTS on all streams */
2480 check_pending_buffers (GstTSDemux * demux)
2482 gboolean have_observation = FALSE;
2483 /* The biggest offset */
2486 gboolean have_only_sparse = TRUE;
2487 gboolean exceeded_threshold = FALSE;
2488 #ifdef TIZEN_FEATURE_TSDEMUX_INVALID_PCR_PID
2489 gboolean wrong_pcr_pid = FALSE;
2492 /* 0. Do we only have sparse stream */
2493 for (tmp = demux->program->stream_list; tmp; tmp = tmp->next) {
2494 TSDemuxStream *tmpstream = (TSDemuxStream *) tmp->data;
2496 if (!tmpstream->sparse) {
2497 have_only_sparse = FALSE;
2502 /* 1. Go over all streams */
2503 for (tmp = demux->program->stream_list; tmp; tmp = tmp->next) {
2504 TSDemuxStream *tmpstream = (TSDemuxStream *) tmp->data;
2505 /* 1.1 check if at least one stream got a valid DTS */
2506 if (have_only_sparse || !tmpstream->sparse) {
2507 if ((tmpstream->raw_dts != -1 && tmpstream->dts != GST_CLOCK_TIME_NONE) ||
2508 (tmpstream->raw_pts != -1 && tmpstream->pts != GST_CLOCK_TIME_NONE)) {
2509 have_observation = TRUE;
2512 /* 1.2 Check if we exceeded the maximum threshold of pending data */
2513 if (tmpstream->pending && (tmpstream->raw_dts != -1
2514 || tmpstream->raw_pts != -1)) {
2515 PendingBuffer *pend = tmpstream->pending->data;
2517 tmpstream->raw_dts != -1 ? tmpstream->raw_dts : tmpstream->raw_pts;
2518 guint64 firstval = pend->dts != -1 ? pend->dts : pend->pts;
2520 g_assert (firstval != -1);
2521 dur = MPEGTIME_TO_GSTTIME (lastval - firstval);
2522 GST_DEBUG_OBJECT (tmpstream->pad,
2523 "Pending content duration: %" GST_TIME_FORMAT, GST_TIME_ARGS (dur));
2524 if (dur > 500 * GST_MSECOND) {
2525 exceeded_threshold = TRUE;
2532 if (have_observation == FALSE) {
2533 /* 2. If we don't have a valid value yet, break out */
2534 if (!exceeded_threshold)
2537 #ifdef TIZEN_FEATURE_TSDEMUX_INVALID_PCR_PID
2538 /* Checking PCR other pid */
2539 for (int i = 0; i < demux->program->pmt->streams->len; ++i) {
2540 GstMpegtsPMTStream *pmt_stream =
2541 g_ptr_array_index (demux->program->pmt->streams, i);
2542 if (pmt_stream->pid == demux->program->pcr_pid)
2544 if (GST_CLOCK_TIME_IS_VALID (mpegts_packetizer_get_pcr_base_time
2545 (MPEG_TS_BASE_PACKETIZER (demux), pmt_stream->pid))) {
2546 GST_WARNING ("PCR_PID will update %x -> %x", demux->program->pcr_pid,
2548 demux->program->pcr_pid = pmt_stream->pid;
2549 wrong_pcr_pid = TRUE;
2556 /* Except if we've exceed the maximum amount of pending buffers, in which
2557 * case we ignore PCR from now on */
2558 GST_DEBUG_OBJECT (demux,
2559 "Saw more than 500ms of data without PCR. Ignoring PCR from now on");
2560 GST_MPEGTS_BASE (demux)->ignore_pcr = TRUE;
2561 demux->program->pcr_pid = 0x1fff;
2562 g_object_notify (G_OBJECT (demux), "ignore-pcr");
2565 /* 3. Go over all streams that have current/pending data */
2566 for (tmp = demux->program->stream_list; tmp; tmp = tmp->next) {
2567 TSDemuxStream *tmpstream = (TSDemuxStream *) tmp->data;
2568 PendingBuffer *pend;
2569 guint64 firstval, lastval, ts;
2571 /* 3.1 Calculate the offset between current DTS and first DTS */
2572 if (tmpstream->pending == NULL || tmpstream->state == PENDING_PACKET_EMPTY)
2574 /* If we don't have any pending data, the offset is 0 for this stream */
2575 if (tmpstream->pending == NULL)
2577 if (tmpstream->raw_dts != -1)
2578 lastval = tmpstream->raw_dts;
2579 else if (tmpstream->raw_pts != -1)
2580 lastval = tmpstream->raw_pts;
2582 GST_WARNING ("Don't have a last DTS/PTS to use for offset recalculation");
2585 pend = tmpstream->pending->data;
2586 if (pend->dts != -1)
2587 firstval = pend->dts;
2588 else if (pend->pts != -1)
2589 firstval = pend->pts;
2592 ("Don't have a first DTS/PTS to use for offset recalculation");
2595 /* 3.2 Add to the offset the report TS for the current DTS */
2596 ts = mpegts_packetizer_pts_to_ts (MPEG_TS_BASE_PACKETIZER (demux),
2597 MPEGTIME_TO_GSTTIME (lastval), demux->program->pcr_pid);
2598 if (ts == GST_CLOCK_TIME_NONE) {
2599 GST_WARNING ("THIS SHOULD NOT HAPPEN !");
2602 ts += MPEGTIME_TO_GSTTIME (lastval - firstval);
2603 /* 3.3 If that offset is bigger than the current offset, store it */
2608 GST_DEBUG ("New initial pcr_offset %" GST_TIME_FORMAT,
2609 GST_TIME_ARGS (offset));
2611 /* 4. Set the offset on the packetizer */
2612 mpegts_packetizer_set_current_pcr_offset (MPEG_TS_BASE_PACKETIZER (demux),
2613 offset, demux->program->pcr_pid);
2615 /* 4. Go over all streams */
2616 for (tmp = demux->program->stream_list; tmp; tmp = tmp->next) {
2617 TSDemuxStream *stream = (TSDemuxStream *) tmp->data;
2619 stream->pending_ts = FALSE;
2620 /* 4.1 Set pending_ts for FALSE */
2622 /* 4.2 Recalculate PTS/DTS (in running time) for pending data */
2623 if (stream->pending) {
2625 for (tmp2 = stream->pending; tmp2; tmp2 = tmp2->next) {
2626 PendingBuffer *pend = (PendingBuffer *) tmp2->data;
2627 if (pend->pts != -1)
2628 GST_BUFFER_PTS (pend->buffer) =
2629 mpegts_packetizer_pts_to_ts (MPEG_TS_BASE_PACKETIZER (demux),
2630 MPEGTIME_TO_GSTTIME (pend->pts), demux->program->pcr_pid);
2631 if (pend->dts != -1)
2632 GST_BUFFER_DTS (pend->buffer) =
2633 mpegts_packetizer_pts_to_ts (MPEG_TS_BASE_PACKETIZER (demux),
2634 MPEGTIME_TO_GSTTIME (pend->dts), demux->program->pcr_pid);
2635 /* 4.2.2 Set first_pts to TS of lowest PTS (for segment) */
2636 if (stream->first_pts == GST_CLOCK_TIME_NONE) {
2637 if (GST_BUFFER_PTS (pend->buffer) != GST_CLOCK_TIME_NONE)
2638 stream->first_pts = GST_BUFFER_PTS (pend->buffer);
2639 else if (GST_BUFFER_DTS (pend->buffer) != GST_CLOCK_TIME_NONE)
2640 stream->first_pts = GST_BUFFER_DTS (pend->buffer);
2644 /* Recalculate PTS/DTS (in running time) for current data */
2645 if (stream->state != PENDING_PACKET_EMPTY) {
2646 if (stream->raw_pts != -1) {
2648 mpegts_packetizer_pts_to_ts (MPEG_TS_BASE_PACKETIZER (demux),
2649 MPEGTIME_TO_GSTTIME (stream->raw_pts), demux->program->pcr_pid);
2650 if (stream->first_pts == GST_CLOCK_TIME_NONE)
2651 stream->first_pts = stream->pts;
2653 if (stream->raw_dts != -1) {
2655 mpegts_packetizer_pts_to_ts (MPEG_TS_BASE_PACKETIZER (demux),
2656 MPEGTIME_TO_GSTTIME (stream->raw_dts), demux->program->pcr_pid);
2657 if (stream->first_pts == GST_CLOCK_TIME_NONE)
2658 stream->first_pts = stream->dts;
2667 gst_ts_demux_parse_pes_header (GstTSDemux * demux, TSDemuxStream * stream,
2668 guint8 * data, guint32 length, guint64 bufferoffset)
2671 PESParsingResult parseres;
2673 GST_MEMDUMP ("Header buffer", data, MIN (length, 32));
2675 if (G_UNLIKELY (stream->pending_header_data)) {
2676 /* Accumulate with previous header if present */
2677 stream->pending_header_data =
2678 g_realloc (stream->pending_header_data,
2679 stream->pending_header_size + length);
2680 memcpy (stream->pending_header_data + stream->pending_header_size, data,
2682 data = stream->pending_header_data;
2683 length = stream->pending_header_size + length;
2686 parseres = mpegts_parse_pes_header (data, length, &header);
2688 if (G_UNLIKELY (parseres == PES_PARSING_NEED_MORE)) {
2689 /* This can happen if PES header is bigger than a packet. */
2690 if (!stream->pending_header_data)
2691 stream->pending_header_data = g_memdup2 (data, length);
2692 stream->pending_header_size = length;
2695 if (G_UNLIKELY (parseres == PES_PARSING_BAD)) {
2696 GST_WARNING ("Error parsing PES header. pid: 0x%x stream_type: 0x%x",
2697 stream->stream.pid, stream->stream.stream_type);
2701 if (stream->target_pes_substream != 0
2702 && header.stream_id_extension != stream->target_pes_substream) {
2703 GST_DEBUG ("Skipping unwanted substream");
2707 gst_ts_demux_record_dts (demux, stream, header.DTS, bufferoffset);
2708 gst_ts_demux_record_pts (demux, stream, header.PTS, bufferoffset);
2709 if (G_UNLIKELY (stream->pending_ts &&
2710 (stream->pts != GST_CLOCK_TIME_NONE
2711 || stream->dts != GST_CLOCK_TIME_NONE))) {
2712 GST_DEBUG ("Got pts/dts update, rechecking all streams");
2713 check_pending_buffers (demux);
2714 } else if (stream->first_pts == GST_CLOCK_TIME_NONE) {
2715 if (GST_CLOCK_TIME_IS_VALID (stream->pts))
2716 stream->first_pts = stream->pts;
2717 else if (GST_CLOCK_TIME_IS_VALID (stream->dts))
2718 stream->first_pts = stream->dts;
2721 GST_DEBUG_OBJECT (demux,
2722 "stream PTS %" GST_TIME_FORMAT " DTS %" GST_TIME_FORMAT,
2723 GST_TIME_ARGS (stream->pts), GST_TIME_ARGS (stream->dts));
2725 /* Remove PES headers */
2726 GST_DEBUG ("Moving data forward by %d bytes (packet_size:%d, have:%d)",
2727 header.header_size, header.packet_length, length);
2728 stream->expected_size = header.packet_length;
2729 if (stream->expected_size) {
2730 if (G_LIKELY (stream->expected_size > header.header_size)) {
2731 stream->expected_size -= header.header_size;
2733 /* next packet will have to complete this one */
2734 GST_WARNING ("invalid header and packet size combination, empty packet");
2735 stream->expected_size = 0;
2738 data += header.header_size;
2739 length -= header.header_size;
2741 /* Create the output buffer */
2742 if (stream->expected_size)
2743 stream->allocated_size = MAX (stream->expected_size, length);
2745 stream->allocated_size = MAX (8192, length);
2747 g_assert (stream->data == NULL);
2748 stream->data = g_malloc (stream->allocated_size);
2749 memcpy (stream->data, data, length);
2750 stream->current_size = length;
2752 stream->state = PENDING_PACKET_BUFFER;
2754 if (stream->pending_header_data) {
2755 g_free (stream->pending_header_data);
2756 stream->pending_header_data = NULL;
2757 stream->pending_header_size = 0;
2763 if (stream->pending_header_data) {
2764 g_free (stream->pending_header_data);
2765 stream->pending_header_data = NULL;
2766 stream->pending_header_size = 0;
2768 stream->state = PENDING_PACKET_DISCONT;
2773 * * WITH packet->payload != NULL
2774 * * WITH pending/current flushed out if beginning of new PES packet
2777 gst_ts_demux_queue_data (GstTSDemux * demux, TSDemuxStream * stream,
2778 MpegTSPacketizerPacket * packet)
2782 guint8 cc = FLAGS_CONTINUITY_COUNTER (packet->scram_afc_cc);
2784 GST_LOG_OBJECT (demux, "pid: 0x%04x state:%d", stream->stream.pid,
2787 size = packet->data_end - packet->payload;
2788 data = packet->payload;
2790 if (stream->continuity_counter == CONTINUITY_UNSET) {
2791 GST_DEBUG_OBJECT (demux, "CONTINUITY: Initialize to %d", cc);
2792 } else if ((cc == stream->continuity_counter + 1 ||
2793 (stream->continuity_counter == MAX_CONTINUITY && cc == 0))) {
2794 GST_LOG_OBJECT (demux, "CONTINUITY: Got expected %d", cc);
2796 if (stream->state != PENDING_PACKET_EMPTY) {
2797 if (packet->payload_unit_start_indicator) {
2798 /* A mismatch is fatal, except if this is the beginning of a new
2799 * frame (from which we can recover) */
2800 if (G_UNLIKELY (stream->data)) {
2801 g_free (stream->data);
2802 stream->data = NULL;
2804 if (G_UNLIKELY (stream->pending_header_data)) {
2805 g_free (stream->pending_header_data);
2806 stream->pending_header_data = NULL;
2808 stream->state = PENDING_PACKET_HEADER;
2810 gchar *pad_name = gst_pad_get_name (stream->pad);
2811 GST_ELEMENT_WARNING_WITH_DETAILS (demux, STREAM, DEMUX,
2812 ("CONTINUITY: Mismatch packet %d, stream %d (pid 0x%04x)", cc,
2813 stream->continuity_counter, stream->stream.pid), (NULL),
2814 ("warning-type", G_TYPE_STRING, "continuity-mismatch",
2815 "packet", G_TYPE_INT, cc,
2816 "stream", G_TYPE_INT, stream->continuity_counter,
2817 "pid", G_TYPE_UINT, stream->stream.pid,
2818 "pad-name", G_TYPE_STRING, pad_name, NULL));
2820 stream->state = PENDING_PACKET_DISCONT;
2824 stream->continuity_counter = cc;
2826 if (stream->state == PENDING_PACKET_EMPTY) {
2827 if (G_UNLIKELY (!packet->payload_unit_start_indicator)) {
2828 stream->state = PENDING_PACKET_DISCONT;
2829 GST_DEBUG_OBJECT (demux, "Didn't get the first packet of this PES");
2831 GST_LOG_OBJECT (demux, "EMPTY=>HEADER");
2832 stream->state = PENDING_PACKET_HEADER;
2836 switch (stream->state) {
2837 case PENDING_PACKET_HEADER:
2839 GST_LOG_OBJECT (demux, "HEADER: Parsing PES header");
2841 /* parse the header */
2842 gst_ts_demux_parse_pes_header (demux, stream, data, size, packet->offset);
2845 case PENDING_PACKET_BUFFER:
2847 GST_LOG_OBJECT (demux, "BUFFER: appending data");
2848 if (G_UNLIKELY (stream->current_size + size > stream->allocated_size)) {
2849 GST_LOG_OBJECT (demux, "resizing buffer");
2851 stream->allocated_size = MAX (8192, 2 * stream->allocated_size);
2852 } while (stream->current_size + size > stream->allocated_size);
2853 stream->data = g_realloc (stream->data, stream->allocated_size);
2855 memcpy (stream->data + stream->current_size, data, size);
2856 stream->current_size += size;
2859 case PENDING_PACKET_DISCONT:
2861 GST_LOG_OBJECT (demux, "DISCONT: not storing/pushing");
2862 if (G_UNLIKELY (stream->data)) {
2863 g_free (stream->data);
2864 stream->data = NULL;
2866 if (G_UNLIKELY (stream->pending_header_data)) {
2867 g_free (stream->pending_header_data);
2868 stream->pending_header_data = NULL;
2870 stream->continuity_counter = CONTINUITY_UNSET;
2881 calculate_and_push_newsegment (GstTSDemux * demux, TSDemuxStream * stream,
2882 MpegTSBaseProgram * target_program)
2884 MpegTSBase *base = (MpegTSBase *) demux;
2885 GstClockTime lowest_pts = GST_CLOCK_TIME_NONE;
2886 GstClockTime firstts = 0;
2889 GST_DEBUG_OBJECT (demux, "Creating new newsegment for stream %p", stream);
2891 if (target_program == NULL)
2892 target_program = demux->program;
2894 /* Speedup : if we don't need to calculate anything, go straight to pushing */
2895 g_mutex_lock (&demux->lock);
2896 if (demux->segment_event) {
2897 g_mutex_unlock (&demux->lock);
2898 goto push_new_segment;
2900 g_mutex_unlock (&demux->lock);
2902 /* Calculate the 'new_start' value, used for newsegment */
2903 for (tmp = target_program->stream_list; tmp; tmp = tmp->next) {
2904 TSDemuxStream *pstream = (TSDemuxStream *) tmp->data;
2906 if (GST_CLOCK_TIME_IS_VALID (pstream->first_pts)) {
2907 if (!GST_CLOCK_TIME_IS_VALID (lowest_pts)
2908 || pstream->first_pts < lowest_pts)
2909 lowest_pts = pstream->first_pts;
2912 if (GST_CLOCK_TIME_IS_VALID (lowest_pts))
2913 firstts = lowest_pts;
2914 GST_DEBUG_OBJECT (demux, "lowest_pts %" G_GUINT64_FORMAT " => clocktime %"
2915 GST_TIME_FORMAT, lowest_pts, GST_TIME_ARGS (firstts));
2917 if (base->out_segment.format != GST_FORMAT_TIME || demux->reset_segment) {
2918 /* It will happen only if it's first program or after flushes. */
2919 GST_DEBUG_OBJECT (demux, "Calculating actual segment");
2920 if (base->segment.format == GST_FORMAT_TIME) {
2921 /* Try to recover segment info from base if it's in TIME format */
2922 base->out_segment = base->segment;
2924 /* Start from the first ts/pts */
2925 GstSegment *seg = &base->out_segment;
2927 seg->base + seg->position - (seg->start + seg->offset);
2928 GstClockTime stop = seg->stop;
2930 gst_segment_init (seg, GST_FORMAT_TIME);
2931 seg->start = firstts;
2932 seg->stop = MAX (seg->start, stop);
2933 seg->position = firstts;
2934 seg->time = firstts;
2935 seg->rate = demux->rate;
2938 } else if (base->out_segment.start < firstts) {
2939 /* Take into account the offset to the first buffer timestamp */
2940 if (base->out_segment.rate > 0) {
2941 if (GST_CLOCK_TIME_IS_VALID (base->out_segment.stop))
2942 base->out_segment.stop += firstts - base->out_segment.start;
2943 base->out_segment.start = firstts;
2944 base->out_segment.position = firstts;
2948 GST_LOG_OBJECT (demux, "Output segment now %" GST_SEGMENT_FORMAT,
2949 &base->out_segment);
2951 g_mutex_lock (&demux->lock);
2952 if (!demux->segment_event) {
2953 gst_event_take (&demux->segment_event,
2954 gst_event_new_segment (&base->out_segment));
2956 if (base->last_seek_seqnum != GST_SEQNUM_INVALID)
2957 gst_event_set_seqnum (demux->segment_event, base->last_seek_seqnum);
2959 g_mutex_unlock (&demux->lock);
2962 for (tmp = target_program->stream_list; tmp; tmp = tmp->next) {
2963 stream = (TSDemuxStream *) tmp->data;
2964 if (stream->pad == NULL)
2967 g_mutex_lock (&demux->lock);
2968 if (demux->segment_event) {
2969 GstEvent *evt = gst_event_ref (demux->segment_event);
2970 GST_DEBUG_OBJECT (stream->pad, "Pushing newsegment event");
2972 g_mutex_unlock (&demux->lock);
2973 gst_pad_push_event (stream->pad, evt);
2975 g_mutex_unlock (&demux->lock);
2978 if (demux->global_tags) {
2979 gst_pad_push_event (stream->pad,
2980 gst_event_new_tag (gst_tag_list_ref (demux->global_tags)));
2982 #ifdef TIZEN_FEATURE_TSDEMUX_LANG_TAG
2983 if (demux->pending_custom_event) {
2984 GST_DEBUG_OBJECT (stream->pad, "Pushing custom event");
2985 gst_pad_push_event (stream->pad, demux->pending_custom_event);
2986 demux->pending_custom_event = NULL;
2990 /* Push pending tags */
2991 if (stream->taglist) {
2992 #ifdef TIZEN_FEATURE_TSDEMUX_LANG_TAG
2993 if (demux->pending_language_tag) {
2994 gchar *audio_codec = NULL;
2995 if (gst_tag_list_get_string (stream->taglist, GST_TAG_AUDIO_CODEC,
2997 GST_DEBUG ("Sending pending language tags %" GST_PTR_FORMAT,
2998 demux->pending_language_tag);
2999 gst_pad_push_event (stream->pad,
3000 gst_event_new_tag (gst_tag_list_ref
3001 (demux->pending_language_tag)));
3002 g_free (audio_codec);
3003 gst_tag_list_unref (demux->pending_language_tag);
3004 demux->pending_language_tag = NULL;
3008 GST_DEBUG_OBJECT (stream->pad, "Sending tags %" GST_PTR_FORMAT,
3010 gst_pad_push_event (stream->pad, gst_event_new_tag (stream->taglist));
3011 stream->taglist = NULL;
3014 stream->need_newsegment = FALSE;
3016 if (base->seek_event) {
3017 g_assert (base->out_segment.format != GST_FORMAT_UNDEFINED);
3018 gst_ts_demux_do_seek (base, base->seek_event);
3019 gst_event_replace (&base->seek_event, NULL);
3024 gst_ts_demux_check_and_sync_streams (GstTSDemux * demux, GstClockTime time)
3028 GST_DEBUG_OBJECT (demux,
3029 "Recheck streams and sync to at least: %" GST_TIME_FORMAT,
3030 GST_TIME_ARGS (time));
3032 if (G_UNLIKELY (demux->program == NULL))
3035 /* Go over each stream and update it to at least 'time' time.
3036 * For each stream, the pad stores the buffer counter the last time
3037 * a gap check occurred (gap_ref_buffers) and a gap_ref_pts timestamp
3038 * that is either the PTS from the stream or the PCR the pad was updated
3041 * We can check nb_out_buffers to see if any buffers were pushed since then.
3042 * This means we can detect buffers passing without PTSes fine and still generate
3045 * If there haven't been any buffers pushed on this stream since the last gap
3046 * check *AND* there is no pending data (stream->current_size), push a gap
3047 * event updating to the indicated input PCR time and update the pad's
3050 * If there have been buffers pushed, update the reference buffer count
3051 * and but don't push a gap event
3053 for (tmp = demux->program->stream_list; tmp; tmp = tmp->next) {
3054 TSDemuxStream *ps = (TSDemuxStream *) tmp->data;
3055 GST_DEBUG_OBJECT (ps->pad,
3056 "0x%04x, PTS:%" GST_TIME_FORMAT " REFPTS:%" GST_TIME_FORMAT " Gap:%"
3057 GST_TIME_FORMAT " nb_buffers: %d (ref:%d) pending_data size %u",
3058 ((MpegTSBaseStream *) ps)->pid, GST_TIME_ARGS (ps->pts),
3059 GST_TIME_ARGS (ps->gap_ref_pts),
3060 GST_TIME_ARGS (ps->pts - ps->gap_ref_pts), ps->nb_out_buffers,
3061 ps->gap_ref_buffers, ps->current_size);
3062 if (ps->pad == NULL)
3065 if (ps->nb_out_buffers == ps->gap_ref_buffers && ps->current_size == 0
3066 && ps->gap_ref_pts != ps->pts) {
3067 /* Do initial setup of pad if needed - segment etc */
3068 GST_DEBUG_OBJECT (ps->pad,
3069 "Stream needs update. Pushing GAP event to TS %" GST_TIME_FORMAT,
3070 GST_TIME_ARGS (time));
3071 if (G_UNLIKELY (ps->need_newsegment))
3072 calculate_and_push_newsegment (demux, ps, NULL);
3074 /* Now send gap event */
3075 gst_pad_push_event (ps->pad, gst_event_new_gap (time, 0));
3078 /* Update GAP tracking vars so we don't re-check this stream for a while */
3079 ps->gap_ref_pts = time;
3080 if (ps->pts != GST_CLOCK_TIME_NONE && ps->pts > time)
3081 ps->gap_ref_pts = ps->pts;
3082 ps->gap_ref_buffers = ps->nb_out_buffers;
3086 static GstBufferList *
3087 parse_opus_access_unit (TSDemuxStream * stream)
3089 GstByteReader reader;
3090 GstBufferList *buffer_list = NULL;
3092 buffer_list = gst_buffer_list_new ();
3093 gst_byte_reader_init (&reader, stream->data, stream->current_size);
3100 gboolean start_trim_flag, end_trim_flag, control_extension_flag;
3101 guint16 start_trim = 0, end_trim = 0;
3102 guint8 *packet_data;
3105 if (!gst_byte_reader_get_uint16_be (&reader, &id))
3108 /* No control header */
3109 if ((id >> 5) != 0x3ff)
3113 if (!gst_byte_reader_get_uint8 (&reader, &b))
3116 } while (b == 0xff);
3118 start_trim_flag = (id >> 4) & 0x1;
3119 end_trim_flag = (id >> 3) & 0x1;
3120 control_extension_flag = (id >> 2) & 0x1;
3122 if (start_trim_flag) {
3123 if (!gst_byte_reader_get_uint16_be (&reader, &start_trim))
3127 if (end_trim_flag) {
3128 if (!gst_byte_reader_get_uint16_be (&reader, &end_trim))
3132 if (control_extension_flag) {
3133 if (!gst_byte_reader_get_uint8 (&reader, &b))
3136 if (!gst_byte_reader_skip (&reader, b))
3140 packet_size = au_size;
3142 /* FIXME: this should be
3143 * packet_size = au_size - gst_byte_reader_get_pos (&reader);
3144 * but ffmpeg and the only available sample stream from obe.tv
3145 * are not including the control header size in au_size
3147 if (gst_byte_reader_get_remaining (&reader) < packet_size)
3149 if (!gst_byte_reader_dup_data (&reader, packet_size, &packet_data))
3152 buffer = gst_buffer_new_wrapped (packet_data, packet_size);
3154 if (start_trim != 0 || end_trim != 0) {
3155 gst_buffer_add_audio_clipping_meta (buffer, GST_FORMAT_DEFAULT,
3156 start_trim, end_trim);
3159 gst_buffer_list_add (buffer_list, buffer);
3160 } while (gst_byte_reader_get_remaining (&reader) > 0);
3162 g_free (stream->data);
3163 stream->data = NULL;
3164 stream->current_size = 0;
3170 GST_ERROR ("Failed to parse Opus access unit");
3171 g_free (stream->data);
3172 stream->data = NULL;
3173 stream->current_size = 0;
3175 gst_buffer_list_unref (buffer_list);
3180 /* interlaced mode is disabled at the moment */
3181 /*#define TSDEMUX_JP2K_SUPPORT_INTERLACE */
3183 parse_jp2k_access_unit (TSDemuxStream * stream)
3185 GstByteReader reader;
3189 guint16 den G_GNUC_UNUSED;
3190 guint16 num G_GNUC_UNUSED;
3191 /* Maximum bitrate box */
3192 guint32 MaxBr G_GNUC_UNUSED;
3193 guint32 AUF[2] = { 0, 0 };
3194 #ifdef TSDEMUX_JP2K_SUPPORT_INTERLACE
3195 /* Field Coding Box */
3196 guint8 Fic G_GNUC_UNUSED = 1;
3197 guint8 Fio G_GNUC_UNUSED = 0;
3198 /* header size equals 38 for non-interlaced, and 48 for interlaced */
3199 guint header_size = stream->jp2kInfos.interlace ? 48 : 38;
3201 /* header size equals 38 for non-interlaced, and 48 for interlaced */
3202 guint header_size = 38;
3205 guint32 HHMMSSFF G_GNUC_UNUSED;
3206 /* Broadcast color box */
3207 guint8 CollC G_GNUC_UNUSED;
3208 guint8 b G_GNUC_UNUSED;
3210 guint data_location;
3211 GstBuffer *retbuf = NULL;
3213 if (stream->current_size < header_size) {
3214 GST_ERROR_OBJECT (stream->pad, "Not enough data for header");
3218 gst_byte_reader_init (&reader, stream->data, stream->current_size);
3220 /* Check for the location of the jp2k magic */
3222 gst_byte_reader_masked_scan_uint32 (&reader, 0xffffffff, 0xff4fff51, 0,
3223 stream->current_size);
3224 GST_DEBUG_OBJECT (stream->pad, "data location %d", data_location);
3225 if (data_location == -1) {
3226 GST_ERROR_OBJECT (stream->pad, "Stream does not contain jp2k magic header");
3230 /* Elementary stream header box 'elsm' == 0x656c736d */
3231 header_tag = gst_byte_reader_get_uint32_be_unchecked (&reader);
3232 if (header_tag != 0x656c736d) {
3233 GST_ERROR_OBJECT (stream->pad, "Expected ELSM box but found box %x instead",
3237 /* Frame rate box 'frat' == 0x66726174 */
3238 header_tag = gst_byte_reader_get_uint32_be_unchecked (&reader);
3239 if (header_tag != 0x66726174) {
3240 GST_ERROR_OBJECT (stream->pad,
3241 "Expected frame rate box, but found box %x instead", header_tag);
3245 den = gst_byte_reader_get_uint16_be_unchecked (&reader);
3246 num = gst_byte_reader_get_uint16_be_unchecked (&reader);
3247 /* Maximum bit rate box 'brat' == 0x62726174 */
3248 header_tag = gst_byte_reader_get_uint32_be_unchecked (&reader);
3249 if (header_tag != 0x62726174) {
3250 GST_ERROR_OBJECT (stream->pad, "Expected brat box but read box %x instead",
3255 MaxBr = gst_byte_reader_get_uint32_be_unchecked (&reader);
3256 AUF[0] = gst_byte_reader_get_uint32_be_unchecked (&reader);
3257 if (stream->jp2kInfos.interlace) {
3258 #ifdef TSDEMUX_JP2K_SUPPORT_INTERLACE
3259 AUF[1] = gst_byte_reader_get_uint32_be_unchecked (&reader);
3260 /* Field Coding Box 'fiel' == 0x6669656c */
3261 header_tag = gst_byte_reader_get_uint32_be_unchecked (&reader);
3262 if (header_tag != 0x6669656c) {
3263 GST_ERROR_OBJECT (stream->pad,
3264 "Expected Field Coding box but found box %x instead", header_tag);
3267 Fic = gst_byte_reader_get_uint8_unchecked (&reader);
3268 Fio = gst_byte_reader_get_uint8_unchecked (&reader);
3270 GST_ERROR_OBJECT (stream->pad, "interlaced mode not supported");
3275 /* Time Code Box 'tcod' == 0x74636f64 */
3276 /* Some progressive streams might have a AUF[1] of value 0 present */
3277 header_tag = gst_byte_reader_get_uint32_be_unchecked (&reader);
3278 if (header_tag == 0 && !stream->jp2kInfos.interlace) {
3279 AUF[1] = header_tag;
3280 header_tag = gst_byte_reader_get_uint32_be_unchecked (&reader);
3281 /* Bump up header size and recheck */
3283 if (stream->current_size < header_size) {
3284 GST_ERROR_OBJECT (stream->pad, "Not enough data for header");
3288 if (header_tag != 0x74636f64) {
3289 GST_ERROR_OBJECT (stream->pad,
3290 "Expected Time code box but found %d box instead", header_tag);
3293 HHMMSSFF = gst_byte_reader_get_uint32_be_unchecked (&reader);
3294 /* Broadcast Color Box 'bcol' == 0x6263686c */
3295 header_tag = gst_byte_reader_get_uint32_be_unchecked (&reader);
3296 if (header_tag != 0x62636f6c) {
3297 GST_ERROR_OBJECT (stream->pad,
3298 "Expected Broadcast color box but found %x box instead", header_tag);
3301 CollC = gst_byte_reader_get_uint8_unchecked (&reader);
3302 b = gst_byte_reader_get_uint8_unchecked (&reader);
3304 /* Check if we have enough data to create a valid buffer */
3305 if ((stream->current_size - data_location) < (AUF[0] + AUF[1])) {
3308 "Required size (%d) greater than remaining size in buffer (%d)",
3309 AUF[0] + AUF[1], (stream->current_size - data_location));
3310 if (stream->expected_size && stream->current_size != stream->expected_size) {
3311 /* warn if buffer is truncated due to draining */
3314 "Truncated buffer: current size (%d) doesn't match expected size (%d)",
3315 stream->current_size, stream->expected_size);
3317 /* kill pipeline if either we don't know what expected size is, or
3318 * we know the expected size, and thus are sure that the buffer is not
3319 * truncated due to draining */
3324 retbuf = gst_buffer_new_wrapped_full (0, stream->data, stream->current_size,
3325 data_location, stream->current_size - data_location,
3326 stream->data, g_free);
3327 stream->data = NULL;
3328 stream->current_size = 0;
3332 GST_ERROR ("Failed to parse JP2K access unit");
3333 g_free (stream->data);
3334 stream->data = NULL;
3335 stream->current_size = 0;
3340 parse_aac_adts_frame (TSDemuxStream * stream)
3342 gint data_location = -1;
3345 guint mpegversion = 4;
3348 if (stream->current_size < 6) {
3349 GST_DEBUG_OBJECT (stream->pad, "Not enough data for header");
3353 /* check syncword */
3354 for (i = 0; i < stream->current_size - 2; i++) {
3355 if ((stream->data[i] == 0xff) && ((stream->data[i + 1] & 0xf6) == 0xf0)) {
3361 GST_TRACE_OBJECT (stream->pad, "data location %d", data_location);
3363 if (data_location == -1) {
3364 GST_DEBUG_OBJECT (stream->pad, "Stream does not contain adts syncword");
3368 if (stream->current_size - data_location < 6) {
3369 GST_DEBUG_OBJECT (stream->pad, "Not enough data for header");
3373 frame_len = ((stream->data[data_location + 3] & 0x03) << 11) |
3374 (stream->data[data_location + 4] << 3) | ((stream->data[data_location +
3377 crc_size = (stream->data[data_location + 1] & 0x01) ? 0 : 2;
3379 if (frame_len < 7 + crc_size) {
3380 GST_DEBUG_OBJECT (stream->pad, "Invalid frame len %d", frame_len);
3384 /* this seems to be valid adts header, check mpeg version now
3386 * TODO: check channels, rate, and profile and then update caps too?
3388 mpegversion = (stream->data[data_location + 1] & 0x08) ? 2 : 4;
3391 if (mpegversion != stream->atdsInfos.mpegversion) {
3393 MpegTSBaseStream *bstream = (MpegTSBaseStream *) stream;
3395 GST_DEBUG_OBJECT (stream->pad, "Update mpegversion from %d to %d",
3396 stream->atdsInfos.mpegversion, mpegversion);
3397 stream->atdsInfos.mpegversion = mpegversion;
3399 caps = gst_stream_get_caps (bstream->stream_object);
3400 caps = gst_caps_make_writable (caps);
3402 gst_caps_set_simple (caps, "mpegversion", G_TYPE_INT, mpegversion, NULL);
3403 gst_stream_set_caps (bstream->stream_object, caps);
3404 gst_pad_set_caps (stream->pad, caps);
3405 gst_caps_unref (caps);
3408 return gst_buffer_new_wrapped (stream->data, stream->current_size);
3412 static GstFlowReturn
3413 gst_ts_demux_push_pending_data (GstTSDemux * demux, TSDemuxStream * stream,
3414 MpegTSBaseProgram * target_program)
3416 MpegTSBase *base = GST_MPEGTS_BASE (demux);
3417 GstFlowReturn res = GST_FLOW_OK;
3418 MpegTSBaseStream *bs = (MpegTSBaseStream *) stream;
3419 GstBuffer *buffer = NULL;
3420 GstBufferList *buffer_list = NULL;
3423 GST_DEBUG_OBJECT (stream->pad,
3424 "stream:%p, pid:0x%04x stream_type:%d state:%d", stream, bs->pid,
3425 bs->stream_type, stream->state);
3427 if (G_UNLIKELY (stream->data == NULL)) {
3428 GST_LOG_OBJECT (stream->pad, "stream->data == NULL");
3432 if (G_UNLIKELY (stream->state == PENDING_PACKET_EMPTY)) {
3433 GST_LOG_OBJECT (stream->pad, "EMPTY: returning");
3437 if (G_UNLIKELY (stream->state != PENDING_PACKET_BUFFER)) {
3438 GST_LOG_OBJECT (stream->pad, "state:%d, returning", stream->state);
3442 if (G_UNLIKELY (demux->program == NULL)) {
3443 GST_LOG_OBJECT (demux, "No program");
3444 g_free (stream->data);
3448 if (stream->needs_keyframe) {
3449 MpegTSBase *base = (MpegTSBase *) demux;
3451 if ((gst_ts_demux_adjust_seek_offset_for_keyframe (stream, stream->data,
3452 stream->current_size)) || demux->last_seek_offset == 0) {
3453 GST_DEBUG_OBJECT (stream->pad,
3454 "Got Keyframe, ready to go at %" GST_TIME_FORMAT,
3455 GST_TIME_ARGS (stream->pts));
3457 if (bs->stream_type == GST_MPEGTS_STREAM_TYPE_PRIVATE_PES_PACKETS &&
3458 bs->registration_id == DRF_ID_OPUS) {
3459 buffer_list = parse_opus_access_unit (stream);
3461 res = GST_FLOW_ERROR;
3465 if (gst_buffer_list_length (buffer_list) == 1) {
3466 buffer = gst_buffer_ref (gst_buffer_list_get (buffer_list, 0));
3467 gst_buffer_list_unref (buffer_list);
3470 } else if (bs->stream_type == GST_MPEGTS_STREAM_TYPE_VIDEO_JP2K) {
3471 buffer = parse_jp2k_access_unit (stream);
3473 res = GST_FLOW_ERROR;
3477 buffer = gst_buffer_new_wrapped (stream->data, stream->current_size);
3480 stream->seeked_pts = stream->pts;
3481 stream->seeked_dts = stream->dts;
3482 stream->needs_keyframe = FALSE;
3485 GST_DEBUG_OBJECT (stream->pad, "Rewinding after keyframe seek failure");
3486 base->seek_offset = demux->last_seek_offset - 200 * base->packetsize;
3487 if (demux->last_seek_offset < 200 * base->packetsize)
3488 base->seek_offset = 0;
3489 demux->last_seek_offset = base->seek_offset;
3490 mpegts_packetizer_flush (base->packetizer, FALSE);
3492 /* Reset all streams accordingly */
3493 for (tmp = demux->program->stream_list; tmp; tmp = tmp->next) {
3494 TSDemuxStream *cand = tmp->data;
3496 GST_DEBUG_OBJECT (cand->pad, "Clearing stream");
3497 cand->continuity_counter = CONTINUITY_UNSET;
3498 cand->state = PENDING_PACKET_EMPTY;
3500 g_free (cand->data);
3502 cand->allocated_size = 0;
3503 cand->current_size = 0;
3505 base->mode = BASE_MODE_SEEKING;
3507 res = GST_FLOW_REWINDING;
3511 if (bs->stream_type == GST_MPEGTS_STREAM_TYPE_PRIVATE_PES_PACKETS &&
3512 bs->registration_id == DRF_ID_OPUS) {
3513 buffer_list = parse_opus_access_unit (stream);
3515 res = GST_FLOW_ERROR;
3519 if (gst_buffer_list_length (buffer_list) == 1) {
3520 buffer = gst_buffer_ref (gst_buffer_list_get (buffer_list, 0));
3521 gst_buffer_list_unref (buffer_list);
3524 } else if (bs->stream_type == GST_MPEGTS_STREAM_TYPE_VIDEO_JP2K) {
3525 buffer = parse_jp2k_access_unit (stream);
3527 res = GST_FLOW_ERROR;
3530 } else if (bs->stream_type == GST_MPEGTS_STREAM_TYPE_AUDIO_AAC_ADTS) {
3531 buffer = parse_aac_adts_frame (stream);
3533 res = GST_FLOW_ERROR;
3537 buffer = gst_buffer_new_wrapped (stream->data, stream->current_size);
3540 if (G_UNLIKELY (stream->pending_ts && !check_pending_buffers (demux))) {
3542 PendingBuffer *pend;
3543 pend = g_slice_new0 (PendingBuffer);
3544 pend->buffer = buffer;
3545 pend->pts = stream->raw_pts;
3546 pend->dts = stream->raw_dts;
3547 stream->pending = g_list_append (stream->pending, pend);
3551 n = gst_buffer_list_length (buffer_list);
3552 for (i = 0; i < n; i++) {
3553 PendingBuffer *pend;
3554 pend = g_slice_new0 (PendingBuffer);
3555 pend->buffer = gst_buffer_ref (gst_buffer_list_get (buffer_list, i));
3556 pend->pts = i == 0 ? stream->raw_pts : -1;
3557 pend->dts = i == 0 ? stream->raw_dts : -1;
3558 stream->pending = g_list_append (stream->pending, pend);
3560 gst_buffer_list_unref (buffer_list);
3562 GST_DEBUG_OBJECT (demux,
3563 "Not enough information to push buffers yet, storing buffer");
3568 if (G_UNLIKELY (stream->need_newsegment))
3569 calculate_and_push_newsegment (demux, stream, target_program);
3571 /* FIXME : Push pending buffers if any */
3572 if (G_UNLIKELY (stream->pending)) {
3574 for (tmp = stream->pending; tmp; tmp = tmp->next) {
3575 PendingBuffer *pend = (PendingBuffer *) tmp->data;
3577 GST_DEBUG_OBJECT (stream->pad,
3578 "Pushing pending buffer PTS:%" GST_TIME_FORMAT " DTS:%"
3579 GST_TIME_FORMAT, GST_TIME_ARGS (GST_BUFFER_PTS (pend->buffer)),
3580 GST_TIME_ARGS (GST_BUFFER_DTS (pend->buffer)));
3582 if (stream->discont)
3583 GST_BUFFER_FLAG_SET (pend->buffer, GST_BUFFER_FLAG_DISCONT);
3584 stream->discont = FALSE;
3586 res = gst_pad_push (stream->pad, pend->buffer);
3587 stream->nb_out_buffers += 1;
3588 g_slice_free (PendingBuffer, pend);
3590 g_list_free (stream->pending);
3591 stream->pending = NULL;
3594 if ((GST_CLOCK_TIME_IS_VALID (stream->seeked_pts)
3595 && stream->pts < stream->seeked_pts) ||
3596 (GST_CLOCK_TIME_IS_VALID (stream->seeked_dts) &&
3597 stream->pts < stream->seeked_dts)) {
3598 GST_INFO_OBJECT (stream->pad,
3599 "Droping with PTS: %" GST_TIME_FORMAT " DTS: %" GST_TIME_FORMAT
3600 " after seeking as other stream needed to be seeked further"
3601 "(seeked PTS: %" GST_TIME_FORMAT " DTS: %" GST_TIME_FORMAT ")",
3602 GST_TIME_ARGS (stream->pts), GST_TIME_ARGS (stream->dts),
3603 GST_TIME_ARGS (stream->seeked_pts), GST_TIME_ARGS (stream->seeked_dts));
3605 gst_buffer_unref (buffer);
3607 gst_buffer_list_unref (buffer_list);
3611 GST_DEBUG_OBJECT (stream->pad, "stream->pts %" GST_TIME_FORMAT,
3612 GST_TIME_ARGS (stream->pts));
3614 /* Decorate buffer or first buffer of the buffer list */
3616 buffer = gst_buffer_list_get (buffer_list, 0);
3618 if (GST_CLOCK_TIME_IS_VALID (stream->pts))
3619 GST_BUFFER_PTS (buffer) = GST_BUFFER_DTS (buffer) = stream->pts;
3620 /* DTS = PTS by default, we override it if there's a real DTS */
3621 if (GST_CLOCK_TIME_IS_VALID (stream->dts))
3622 GST_BUFFER_DTS (buffer) = stream->dts;
3624 if (stream->discont)
3625 GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DISCONT);
3626 stream->discont = FALSE;
3631 GST_DEBUG_OBJECT (stream->pad,
3632 "Pushing buffer%s with PTS: %" GST_TIME_FORMAT " , DTS: %"
3633 GST_TIME_FORMAT, (buffer_list ? "list" : ""), GST_TIME_ARGS (stream->pts),
3634 GST_TIME_ARGS (stream->dts));
3636 if (GST_CLOCK_TIME_IS_VALID (stream->dts)) {
3637 if (stream->dts > base->out_segment.position)
3638 base->out_segment.position = stream->dts;
3639 } else if (GST_CLOCK_TIME_IS_VALID (stream->pts)) {
3640 if (stream->pts > base->out_segment.position)
3641 base->out_segment.position = stream->pts;
3645 res = gst_pad_push (stream->pad, buffer);
3646 /* Record that a buffer was pushed */
3647 stream->nb_out_buffers += 1;
3649 guint n = gst_buffer_list_length (buffer_list);
3650 res = gst_pad_push_list (stream->pad, buffer_list);
3651 /* Record that a buffer was pushed */
3652 stream->nb_out_buffers += n;
3654 GST_DEBUG_OBJECT (stream->pad, "Returned %s", gst_flow_get_name (res));
3655 res = gst_flow_combiner_update_flow (demux->flowcombiner, res);
3656 GST_DEBUG_OBJECT (stream->pad, "combined %s", gst_flow_get_name (res));
3658 /* GAP / sparse stream tracking */
3659 if (G_UNLIKELY (stream->gap_ref_pts == GST_CLOCK_TIME_NONE))
3660 stream->gap_ref_pts = stream->pts;
3662 /* Look if the stream PTS has advanced 2 seconds since the last
3663 * gap check, and sync streams if it has. The first stream to
3664 * hit this will trigger a gap check */
3665 if (G_UNLIKELY (stream->pts != GST_CLOCK_TIME_NONE &&
3666 stream->pts > stream->gap_ref_pts + 2 * GST_SECOND)) {
3667 if (demux->program->pcr_pid != 0x1fff) {
3668 GstClockTime curpcr =
3669 mpegts_packetizer_get_current_time (MPEG_TS_BASE_PACKETIZER (demux),
3670 demux->program->pcr_pid);
3671 if (curpcr == GST_CLOCK_TIME_NONE || curpcr < 800 * GST_MSECOND)
3673 curpcr -= 800 * GST_MSECOND;
3674 /* Use the current PCR (with a safety margin) to sync against */
3675 gst_ts_demux_check_and_sync_streams (demux, curpcr);
3677 /* If we don't have a PCR track, just use the current stream PTS */
3678 gst_ts_demux_check_and_sync_streams (demux, stream->pts);
3684 /* Reset the PES payload collection, but don't clear the state,
3685 * we might want to keep collecting this PES */
3686 GST_LOG_OBJECT (demux, "Cleared PES data. returning %s",
3687 gst_flow_get_name (res));
3688 if (stream->expected_size) {
3689 if (stream->current_size > stream->expected_size)
3690 stream->expected_size = 0;
3692 stream->expected_size -= stream->current_size;
3694 stream->data = NULL;
3695 stream->allocated_size = 0;
3696 stream->current_size = 0;
3701 static GstFlowReturn
3702 gst_ts_demux_handle_packet (GstTSDemux * demux, TSDemuxStream * stream,
3703 MpegTSPacketizerPacket * packet, GstMpegtsSection * section)
3705 GstFlowReturn res = GST_FLOW_OK;
3707 GST_LOG_OBJECT (demux, "pid 0x%04x pusi:%d, afc:%d, cont:%d, payload:%p",
3708 packet->pid, packet->payload_unit_start_indicator,
3709 packet->scram_afc_cc & 0x30,
3710 FLAGS_CONTINUITY_COUNTER (packet->scram_afc_cc), packet->payload);
3712 if (G_UNLIKELY (packet->payload_unit_start_indicator) &&
3713 FLAGS_HAS_PAYLOAD (packet->scram_afc_cc)) {
3714 /* Flush previous data */
3715 res = gst_ts_demux_push_pending_data (demux, stream, NULL);
3716 if (res != GST_FLOW_REWINDING) {
3717 /* Tell the data collecting to expect this header. We don't do this when
3718 * rewinding since the states will have been resetted accordingly */
3719 stream->state = PENDING_PACKET_HEADER;
3723 if (packet->payload && (res == GST_FLOW_OK || res == GST_FLOW_NOT_LINKED)
3725 gst_ts_demux_queue_data (demux, stream, packet);
3726 GST_LOG_OBJECT (demux, "current_size:%d, expected_size:%d",
3727 stream->current_size, stream->expected_size);
3728 /* Finally check if the data we queued completes a packet, or got too
3729 * large and needs output now */
3730 if ((stream->expected_size && stream->current_size >= stream->expected_size)
3731 || (stream->current_size >= MAX_PES_PAYLOAD)) {
3732 GST_LOG_OBJECT (demux, "pushing packet of size %u", stream->current_size);
3733 res = gst_ts_demux_push_pending_data (demux, stream, NULL);
3737 /* We are rewinding to find a keyframe,
3738 * and didn't want the data to be queued
3740 if (res == GST_FLOW_REWINDING)
3747 gst_ts_demux_flush (MpegTSBase * base, gboolean hard)
3749 GstTSDemux *demux = GST_TS_DEMUX_CAST (base);
3751 gst_ts_demux_flush_streams (demux, hard);
3753 g_mutex_lock (&demux->lock);
3754 gst_event_replace (&demux->segment_event, NULL);
3755 g_mutex_unlock (&demux->lock);
3756 if (demux->global_tags) {
3757 gst_tag_list_unref (demux->global_tags);
3758 demux->global_tags = NULL;
3761 /* For pull mode seeks the current segment needs to be preserved */
3763 gst_segment_init (&base->out_segment, GST_FORMAT_UNDEFINED);
3767 static GstFlowReturn
3768 gst_ts_demux_drain (MpegTSBase * base)
3770 GstTSDemux *demux = GST_TS_DEMUX_CAST (base);
3772 GstFlowReturn res = GST_FLOW_OK;
3774 if (!demux->program)
3777 for (tmp = demux->program->stream_list; tmp; tmp = tmp->next) {
3778 TSDemuxStream *stream = (TSDemuxStream *) tmp->data;
3780 res = gst_ts_demux_push_pending_data (demux, stream, NULL);
3781 if (G_UNLIKELY (res != GST_FLOW_OK))
3789 static GstFlowReturn
3790 gst_ts_demux_push (MpegTSBase * base, MpegTSPacketizerPacket * packet,
3791 GstMpegtsSection * section)
3793 GstTSDemux *demux = GST_TS_DEMUX_CAST (base);
3794 TSDemuxStream *stream = NULL;
3795 GstFlowReturn res = GST_FLOW_OK;
3797 if (G_LIKELY (demux->program)) {
3798 stream = (TSDemuxStream *) demux->program->streams[packet->pid];
3801 res = gst_ts_demux_handle_packet (demux, stream, packet, section);