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 nsecs */
76 #define TS_LATENCY (700 * GST_MSECOND)
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;
100 PENDING_PACKET_EMPTY = 0, /* No pending packet/buffer
101 * Push incoming buffers to the array */
102 PENDING_PACKET_HEADER, /* PES header needs to be parsed
103 * Push incoming buffers to the array */
104 PENDING_PACKET_BUFFER, /* Currently filling up output buffer
105 * Push incoming buffers to the bufferlist */
106 PENDING_PACKET_DISCONT /* Discontinuity in incoming packets
107 * Drop all incoming buffers */
108 } PendingPacketState;
113 /* The fully reconstructed buffer */
116 /* Raw PTS/DTS (in 90kHz units) */
120 typedef struct _TSDemuxStream TSDemuxStream;
122 typedef struct _TSDemuxH264ParsingInfos TSDemuxH264ParsingInfos;
123 typedef struct _TSDemuxJP2KParsingInfos TSDemuxJP2KParsingInfos;
125 /* Returns TRUE if a keyframe was found */
126 typedef gboolean (*GstTsDemuxKeyFrameScanFunction) (TSDemuxStream * stream,
127 guint8 * data, const gsize data_size, const gsize max_frame_offset);
135 struct _TSDemuxH264ParsingInfos
137 /* H264 parsing data */
138 GstH264NalParser *parser;
142 SimpleBuffer framedata;
145 struct _TSDemuxJP2KParsingInfos
147 /* J2K parsing data */
150 struct _TSDemuxStream
152 MpegTSBaseStream stream;
156 /* Whether the pad was added or not */
159 /* Whether this is a sparse stream (subtitles or metadata) */
162 /* TRUE if we are waiting for a valid timestamp */
166 PendingPacketState state;
168 /* Data being reconstructed (allocated) */
171 /* Size of data being reconstructed (if known, else 0) */
174 /* Amount of bytes in current ->data */
177 guint allocated_size;
179 /* Current PTS/DTS for this stream (in running time) */
183 /* Reference PTS used to detect gaps */
184 GstClockTime gap_ref_pts;
185 /* Number of outputted buffers */
186 guint32 nb_out_buffers;
187 /* Reference number of buffers for gaps */
188 guint32 gap_ref_buffers;
190 /* Current PTS/DTS for this stream (in 90kHz unit) */
191 guint64 raw_pts, raw_dts;
193 /* Whether this stream needs to send a newsegment */
194 gboolean need_newsegment;
196 /* Whether the next output buffer should be DISCONT */
199 /* The value to use when calculating the newsegment */
200 GstClockTime first_pts;
204 gint continuity_counter;
206 /* List of pending buffers */
209 /* if != 0, output only PES from that substream */
210 guint8 target_pes_substream;
211 gboolean needs_keyframe;
213 GstClockTime seeked_pts, seeked_dts;
215 GstTsDemuxKeyFrameScanFunction scan_function;
216 TSDemuxH264ParsingInfos h264infos;
217 TSDemuxJP2KParsingInfos jp2kInfos;
218 #ifdef TIZEN_FEATURE_AVOID_PAD_SWITCHING
219 /* For pad matching to avoid switching pads */
220 TSDemuxStream *matched_stream;
227 "mpegversion = (int) { 1, 2, 4 }, " \
228 "systemstream = (boolean) FALSE; " \
229 "video/x-h264,stream-format=(string)byte-stream," \
230 "alignment=(string)nal;" \
231 "video/x-h265,stream-format=(string)byte-stream," \
232 "alignment=(string)nal;" \
236 "wmvversion = (int) 3, " \
237 "format = (string) WVC1;" \
244 "mpegversion = (int) 1;" \
246 "mpegversion = (int) 2, " \
247 "stream-format = (string) adts; " \
249 "mpegversion = (int) 4, " \
250 "stream-format = (string) loas; " \
252 "width = (int) { 16, 20, 24 }, " \
253 "rate = (int) { 48000, 96000 }, " \
254 "channels = (int) [ 1, 8 ], " \
255 "dynamic_range = (int) [ 0, 255 ], " \
256 "emphasis = (boolean) { FALSE, TRUE }, " \
257 "mute = (boolean) { FALSE, TRUE }; " \
258 "audio/x-ac3; audio/x-eac3;" \
261 "audio/x-private-ts-lpcm" \
264 /* Can also use the subpicture pads for text subtitles? */
265 #define SUBPICTURE_CAPS \
266 GST_STATIC_CAPS ("subpicture/x-pgs; subpicture/x-dvd; subpicture/x-dvb")
268 static GstStaticPadTemplate video_template =
269 GST_STATIC_PAD_TEMPLATE ("video_%01x_%05x", GST_PAD_SRC,
273 static GstStaticPadTemplate audio_template =
274 GST_STATIC_PAD_TEMPLATE ("audio_%01x_%05x",
279 static GstStaticPadTemplate subpicture_template =
280 GST_STATIC_PAD_TEMPLATE ("subpicture_%01x_%05x",
285 static GstStaticPadTemplate private_template =
286 GST_STATIC_PAD_TEMPLATE ("private_%01x_%05x",
289 GST_STATIC_CAPS_ANY);
302 /* mpegtsbase methods */
304 gst_ts_demux_update_program (MpegTSBase * base, MpegTSBaseProgram * program);
306 gst_ts_demux_program_started (MpegTSBase * base, MpegTSBaseProgram * program);
308 gst_ts_demux_program_stopped (MpegTSBase * base, MpegTSBaseProgram * program);
310 gst_ts_demux_can_remove_program (MpegTSBase * base,
311 MpegTSBaseProgram * program);
312 static void gst_ts_demux_reset (MpegTSBase * base);
314 gst_ts_demux_push (MpegTSBase * base, MpegTSPacketizerPacket * packet,
315 GstMpegtsSection * section);
316 static void gst_ts_demux_flush (MpegTSBase * base, gboolean hard);
317 static GstFlowReturn gst_ts_demux_drain (MpegTSBase * base);
319 gst_ts_demux_stream_added (MpegTSBase * base, MpegTSBaseStream * stream,
320 MpegTSBaseProgram * program);
322 gst_ts_demux_stream_removed (MpegTSBase * base, MpegTSBaseStream * stream);
323 static GstFlowReturn gst_ts_demux_do_seek (MpegTSBase * base, GstEvent * event);
324 static void gst_ts_demux_set_property (GObject * object, guint prop_id,
325 const GValue * value, GParamSpec * pspec);
326 static void gst_ts_demux_get_property (GObject * object, guint prop_id,
327 GValue * value, GParamSpec * pspec);
328 static void gst_ts_demux_flush_streams (GstTSDemux * tsdemux, gboolean hard);
330 gst_ts_demux_push_pending_data (GstTSDemux * demux, TSDemuxStream * stream,
331 MpegTSBaseProgram * program);
332 static void gst_ts_demux_stream_flush (TSDemuxStream * stream,
333 GstTSDemux * demux, gboolean hard);
335 #ifdef TIZEN_FEATURE_AVOID_PAD_SWITCHING
336 static void gst_ts_demux_remove_stream (GstTSDemux * tsdemux,
337 TSDemuxStream * stream, gboolean push_eos);
338 static void gst_ts_demux_remove_old_streams (GstTSDemux * demux,
341 static gboolean push_event (MpegTSBase * base, GstEvent * event);
342 static gboolean sink_query (MpegTSBase * base, GstQuery * query);
343 static void gst_ts_demux_check_and_sync_streams (GstTSDemux * demux,
349 QUARK_TSDEMUX = g_quark_from_string ("tsdemux");
350 QUARK_PID = g_quark_from_string ("pid");
351 QUARK_PCR = g_quark_from_string ("pcr");
352 QUARK_OPCR = g_quark_from_string ("opcr");
353 QUARK_PTS = g_quark_from_string ("pts");
354 QUARK_DTS = g_quark_from_string ("dts");
355 QUARK_OFFSET = g_quark_from_string ("offset");
358 #define gst_ts_demux_parent_class parent_class
359 G_DEFINE_TYPE_WITH_CODE (GstTSDemux, gst_ts_demux, GST_TYPE_MPEGTS_BASE,
363 gst_ts_demux_dispose (GObject * object)
365 GstTSDemux *demux = GST_TS_DEMUX_CAST (object);
367 gst_flow_combiner_free (demux->flowcombiner);
369 GST_CALL_PARENT (G_OBJECT_CLASS, dispose, (object));
373 gst_ts_demux_class_init (GstTSDemuxClass * klass)
375 GObjectClass *gobject_class;
376 GstElementClass *element_class;
377 MpegTSBaseClass *ts_class;
379 gobject_class = G_OBJECT_CLASS (klass);
380 gobject_class->set_property = gst_ts_demux_set_property;
381 gobject_class->get_property = gst_ts_demux_get_property;
382 gobject_class->dispose = gst_ts_demux_dispose;
384 g_object_class_install_property (gobject_class, PROP_PROGRAM_NUMBER,
385 g_param_spec_int ("program-number", "Program number",
386 "Program Number to demux for (-1 to ignore)", -1, G_MAXINT,
387 -1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
389 g_object_class_install_property (gobject_class, PROP_EMIT_STATS,
390 g_param_spec_boolean ("emit-stats", "Emit statistics",
391 "Emit messages for every pcr/opcr/pts/dts", FALSE,
392 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
394 element_class = GST_ELEMENT_CLASS (klass);
395 gst_element_class_add_pad_template (element_class,
396 gst_static_pad_template_get (&video_template));
397 gst_element_class_add_pad_template (element_class,
398 gst_static_pad_template_get (&audio_template));
399 gst_element_class_add_pad_template (element_class,
400 gst_static_pad_template_get (&subpicture_template));
401 gst_element_class_add_pad_template (element_class,
402 gst_static_pad_template_get (&private_template));
404 gst_element_class_set_static_metadata (element_class,
405 "MPEG transport stream demuxer",
407 "Demuxes MPEG2 transport streams",
408 "Zaheer Abbas Merali <zaheerabbas at merali dot org>\n"
409 "Edward Hervey <edward.hervey@collabora.co.uk>");
411 ts_class = GST_MPEGTS_BASE_CLASS (klass);
412 ts_class->reset = GST_DEBUG_FUNCPTR (gst_ts_demux_reset);
413 ts_class->push = GST_DEBUG_FUNCPTR (gst_ts_demux_push);
414 ts_class->push_event = GST_DEBUG_FUNCPTR (push_event);
415 ts_class->sink_query = GST_DEBUG_FUNCPTR (sink_query);
416 ts_class->program_started = GST_DEBUG_FUNCPTR (gst_ts_demux_program_started);
417 ts_class->program_stopped = GST_DEBUG_FUNCPTR (gst_ts_demux_program_stopped);
418 ts_class->update_program = GST_DEBUG_FUNCPTR (gst_ts_demux_update_program);
419 ts_class->can_remove_program = gst_ts_demux_can_remove_program;
420 ts_class->stream_added = gst_ts_demux_stream_added;
421 ts_class->stream_removed = gst_ts_demux_stream_removed;
422 ts_class->seek = GST_DEBUG_FUNCPTR (gst_ts_demux_do_seek);
423 ts_class->flush = GST_DEBUG_FUNCPTR (gst_ts_demux_flush);
424 ts_class->drain = GST_DEBUG_FUNCPTR (gst_ts_demux_drain);
428 gst_ts_demux_reset (MpegTSBase * base)
430 GstTSDemux *demux = (GstTSDemux *) base;
433 gst_segment_init (&demux->segment, GST_FORMAT_UNDEFINED);
434 if (demux->segment_event) {
435 gst_event_unref (demux->segment_event);
436 demux->segment_event = NULL;
439 if (demux->global_tags) {
440 gst_tag_list_unref (demux->global_tags);
441 demux->global_tags = NULL;
444 if (demux->previous_program) {
445 mpegts_base_deactivate_and_free_program (base, demux->previous_program);
446 demux->previous_program = NULL;
449 demux->have_group_id = FALSE;
450 demux->group_id = G_MAXUINT;
452 demux->last_seek_offset = -1;
453 demux->program_generation = 0;
454 #ifdef TIZEN_FEATURE_AVOID_PAD_SWITCHING
455 gst_ts_demux_remove_old_streams (demux, FALSE);
460 gst_ts_demux_init (GstTSDemux * demux)
462 MpegTSBase *base = (MpegTSBase *) demux;
464 base->stream_size = sizeof (TSDemuxStream);
465 base->parse_private_sections = TRUE;
466 /* We are not interested in sections (all handled by mpegtsbase) */
467 base->push_section = FALSE;
469 demux->flowcombiner = gst_flow_combiner_new ();
470 demux->requested_program_number = -1;
471 demux->program_number = -1;
472 gst_ts_demux_reset (base);
477 gst_ts_demux_set_property (GObject * object, guint prop_id,
478 const GValue * value, GParamSpec * pspec)
480 GstTSDemux *demux = GST_TS_DEMUX (object);
483 case PROP_PROGRAM_NUMBER:
484 /* FIXME: do something if program is switched as opposed to set at
486 demux->requested_program_number = g_value_get_int (value);
488 case PROP_EMIT_STATS:
489 demux->emit_statistics = g_value_get_boolean (value);
492 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
497 gst_ts_demux_get_property (GObject * object, guint prop_id,
498 GValue * value, GParamSpec * pspec)
500 GstTSDemux *demux = GST_TS_DEMUX (object);
503 case PROP_PROGRAM_NUMBER:
504 g_value_set_int (value, demux->requested_program_number);
506 case PROP_EMIT_STATS:
507 g_value_set_boolean (value, demux->emit_statistics);
510 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
515 gst_ts_demux_get_duration (GstTSDemux * demux, GstClockTime * dur)
517 MpegTSBase *base = (MpegTSBase *) demux;
518 gboolean res = FALSE;
521 if (!demux->program) {
522 GST_DEBUG_OBJECT (demux, "No active program yet, can't provide duration");
526 /* Get total size in bytes */
527 if (gst_pad_peer_query_duration (base->sinkpad, GST_FORMAT_BYTES, &val)) {
528 /* Convert it to duration */
530 mpegts_packetizer_offset_to_ts (base->packetizer, val,
531 demux->program->pcr_pid);
532 if (GST_CLOCK_TIME_IS_VALID (*dur))
539 gst_ts_demux_srcpad_query (GstPad * pad, GstObject * parent, GstQuery * query)
546 demux = GST_TS_DEMUX (parent);
547 base = GST_MPEGTS_BASE (demux);
549 switch (GST_QUERY_TYPE (query)) {
550 case GST_QUERY_DURATION:
552 GST_DEBUG ("query duration");
553 gst_query_parse_duration (query, &format, NULL);
554 if (format == GST_FORMAT_TIME) {
555 if (!gst_pad_peer_query (base->sinkpad, query)) {
557 if (gst_ts_demux_get_duration (demux, &dur))
558 gst_query_set_duration (query, GST_FORMAT_TIME, dur);
563 GST_DEBUG_OBJECT (demux, "only query duration on TIME is supported");
568 case GST_QUERY_LATENCY:
570 GST_DEBUG ("query latency");
571 res = gst_pad_peer_query (base->sinkpad, query);
573 GstClockTime min_lat, max_lat;
576 /* According to H.222.0
577 Annex D.0.3 (System Time Clock recovery in the decoder)
578 and D.0.2 (Audio and video presentation synchronization)
580 We can end up with an interval of up to 700ms between valid
581 PTS/DTS. We therefore allow a latency of 700ms for that.
583 gst_query_parse_latency (query, &live, &min_lat, &max_lat);
584 min_lat += TS_LATENCY;
585 if (GST_CLOCK_TIME_IS_VALID (max_lat))
586 max_lat += TS_LATENCY;
587 gst_query_set_latency (query, live, min_lat, max_lat);
591 case GST_QUERY_SEEKING:
593 GST_DEBUG ("query seeking");
594 gst_query_parse_seeking (query, &format, NULL, NULL, NULL);
595 GST_DEBUG ("asked for format %s", gst_format_get_name (format));
596 if (format == GST_FORMAT_TIME) {
597 gboolean seekable = FALSE;
599 if (gst_pad_peer_query (base->sinkpad, query))
600 gst_query_parse_seeking (query, NULL, &seekable, NULL, NULL);
602 /* If upstream is not seekable in TIME format we use
603 * our own values here */
606 if (gst_ts_demux_get_duration (demux, &dur)) {
607 gst_query_set_seeking (query, GST_FORMAT_TIME, TRUE, 0, dur);
608 GST_DEBUG ("Gave duration: %" GST_TIME_FORMAT, GST_TIME_ARGS (dur));
612 GST_DEBUG_OBJECT (demux, "only TIME is supported for query seeking");
617 case GST_QUERY_SEGMENT:{
621 format = demux->segment.format;
624 gst_segment_to_stream_time (&demux->segment, format,
625 demux->segment.start);
626 if ((stop = demux->segment.stop) == -1)
627 stop = demux->segment.duration;
629 stop = gst_segment_to_stream_time (&demux->segment, format, stop);
631 gst_query_set_segment (query, demux->segment.rate, format, start, stop);
636 res = gst_pad_query_default (pad, parent, query);
644 clear_simple_buffer (SimpleBuffer * sbuf)
655 scan_keyframe_h264 (TSDemuxStream * stream, const guint8 * data,
656 const gsize data_size, const gsize max_frame_offset)
659 GstH264NalUnit unit, frame_unit = { 0, };
660 GstH264ParserResult res = GST_H264_PARSER_OK;
661 TSDemuxH264ParsingInfos *h264infos = &stream->h264infos;
663 GstH264NalParser *parser = h264infos->parser;
665 if (G_UNLIKELY (parser == NULL)) {
666 parser = h264infos->parser = gst_h264_nal_parser_new ();
667 h264infos->sps = gst_byte_writer_new ();
668 h264infos->pps = gst_byte_writer_new ();
669 h264infos->sei = gst_byte_writer_new ();
672 while (res == GST_H264_PARSER_OK) {
674 gst_h264_parser_identify_nalu (parser, data, offset, data_size, &unit);
676 if (res != GST_H264_PARSER_OK && res != GST_H264_PARSER_NO_NAL_END) {
677 GST_INFO_OBJECT (stream->pad, "Error identifying nalu: %i", res);
681 res = gst_h264_parser_parse_nal (parser, &unit);
682 if (res != GST_H264_PARSER_OK) {
687 case GST_H264_NAL_SEI:
691 if (gst_byte_writer_put_data (h264infos->sei,
692 unit.data + unit.sc_offset,
693 unit.size + unit.offset - unit.sc_offset)) {
694 GST_DEBUG ("adding SEI %u", unit.size + unit.offset - unit.sc_offset);
696 GST_WARNING ("Could not write SEI");
699 case GST_H264_NAL_PPS:
703 if (gst_byte_writer_put_data (h264infos->pps,
704 unit.data + unit.sc_offset,
705 unit.size + unit.offset - unit.sc_offset)) {
706 GST_DEBUG ("adding PPS %u", unit.size + unit.offset - unit.sc_offset);
708 GST_WARNING ("Could not write PPS");
711 case GST_H264_NAL_SPS:
715 if (gst_byte_writer_put_data (h264infos->sps,
716 unit.data + unit.sc_offset,
717 unit.size + unit.offset - unit.sc_offset)) {
718 GST_DEBUG ("adding SPS %u", unit.size + unit.offset - unit.sc_offset);
720 GST_WARNING ("Could not write SPS");
723 /* these units are considered keyframes in h264parse */
724 case GST_H264_NAL_SLICE:
725 case GST_H264_NAL_SLICE_DPA:
726 case GST_H264_NAL_SLICE_DPB:
727 case GST_H264_NAL_SLICE_DPC:
728 case GST_H264_NAL_SLICE_IDR:
730 GstH264SliceHdr slice;
732 if (h264infos->framedata.size)
735 res = gst_h264_parser_parse_slice_hdr (parser, &unit, &slice,
738 if (GST_H264_IS_I_SLICE (&slice) || GST_H264_IS_SI_SLICE (&slice)) {
739 if (*(unit.data + unit.offset + 1) & 0x80) {
740 /* means first_mb_in_slice == 0 */
741 /* real frame data */
742 GST_DEBUG_OBJECT (stream->pad, "Found keyframe at: %u",
754 if (offset == unit.sc_offset + unit.size)
757 offset = unit.sc_offset + unit.size;
760 /* We've got all the infos we need (SPS / PPS and a keyframe, plus
761 * and possibly SEI units. We can stop rewinding the stream
763 if (gst_byte_writer_get_size (h264infos->sps) &&
764 gst_byte_writer_get_size (h264infos->pps) &&
765 (h264infos->framedata.size || frame_unit.size)) {
768 gsize tmpsize = gst_byte_writer_get_size (h264infos->pps);
770 /* We know that the SPS is first so just put all our data in there */
771 data = gst_byte_writer_reset_and_get_data (h264infos->pps);
772 gst_byte_writer_put_data (h264infos->sps, data, tmpsize);
775 tmpsize = gst_byte_writer_get_size (h264infos->sei);
777 GST_DEBUG ("Adding SEI");
778 data = gst_byte_writer_reset_and_get_data (h264infos->sei);
779 gst_byte_writer_put_data (h264infos->sps, data, tmpsize);
783 if (frame_unit.size) { /* We found the everything in one go! */
784 GST_DEBUG ("Adding Keyframe");
785 gst_byte_writer_put_data (h264infos->sps,
786 frame_unit.data + frame_unit.sc_offset,
787 stream->current_size - frame_unit.sc_offset);
789 GST_DEBUG ("Adding Keyframe");
790 gst_byte_writer_put_data (h264infos->sps,
791 h264infos->framedata.data, h264infos->framedata.size);
792 clear_simple_buffer (&h264infos->framedata);
795 g_free (stream->data);
796 stream->current_size = gst_byte_writer_get_size (h264infos->sps);
797 stream->data = gst_byte_writer_reset_and_get_data (h264infos->sps);
798 gst_byte_writer_init (h264infos->sps);
799 gst_byte_writer_init (h264infos->pps);
800 gst_byte_writer_init (h264infos->sei);
805 if (frame_unit.size) {
806 GST_DEBUG_OBJECT (stream->pad, "Keep the keyframe as this is the one"
807 " we will push later");
809 h264infos->framedata.data =
810 g_memdup (frame_unit.data + frame_unit.sc_offset,
811 stream->current_size - frame_unit.sc_offset);
812 h264infos->framedata.size = stream->current_size - frame_unit.sc_offset;
818 /* We merge data from TS packets so that the scanning methods get a continuous chunk,
819 however the scanning method will return keyframe offset which needs to be translated
820 back to actual offset in file */
823 gint64 real_offset; /* offset of TS packet */
824 gint merged_offset; /* offset of merged data in buffer */
828 gst_ts_demux_adjust_seek_offset_for_keyframe (TSDemuxStream * stream,
829 guint8 * data, guint64 size)
833 if (!stream->scan_function)
836 scan_pid = ((MpegTSBaseStream *) stream)->pid;
838 if (scan_pid != -1) {
839 return stream->scan_function (stream, data, size, size);
846 gst_ts_demux_do_seek (MpegTSBase * base, GstEvent * event)
850 GstTSDemux *demux = (GstTSDemux *) base;
851 GstFlowReturn res = GST_FLOW_ERROR;
855 GstSeekType start_type, stop_type;
857 guint64 start_offset;
859 gst_event_parse_seek (event, &rate, &format, &flags, &start_type, &start,
862 GST_DEBUG ("seek event, rate: %f start: %" GST_TIME_FORMAT
863 " stop: %" GST_TIME_FORMAT, rate, GST_TIME_ARGS (start),
864 GST_TIME_ARGS (stop));
867 GST_WARNING ("Negative rate not supported");
871 if (flags & (GST_SEEK_FLAG_SEGMENT)) {
872 GST_WARNING ("seek flags 0x%x are not supported", (int) flags);
876 /* configure the segment with the seek variables */
877 GST_DEBUG_OBJECT (demux, "configuring seek");
879 if (start_type != GST_SEEK_TYPE_NONE) {
881 mpegts_packetizer_ts_to_offset (base->packetizer, MAX (0,
882 start - SEEK_TIMESTAMP_OFFSET), demux->program->pcr_pid);
884 if (G_UNLIKELY (start_offset == -1)) {
885 GST_WARNING ("Couldn't convert start position to an offset");
889 for (tmp = demux->program->stream_list; tmp; tmp = tmp->next) {
890 TSDemuxStream *stream = tmp->data;
892 stream->need_newsegment = TRUE;
894 gst_segment_init (&demux->segment, GST_FORMAT_UNDEFINED);
895 if (demux->segment_event) {
896 gst_event_unref (demux->segment_event);
897 demux->segment_event = NULL;
904 /* record offset and rate */
905 base->seek_offset = start_offset;
906 demux->last_seek_offset = base->seek_offset;
910 gst_segment_do_seek (&demux->segment, rate, format, flags, start_type,
911 start, stop_type, stop, NULL);
912 /* Reset segment if we're not doing an accurate seek */
913 demux->reset_segment = (!(flags & GST_SEEK_FLAG_ACCURATE));
915 if (demux->segment_event) {
916 gst_event_unref (demux->segment_event);
917 demux->segment_event = NULL;
920 for (tmp = demux->program->stream_list; tmp; tmp = tmp->next) {
921 TSDemuxStream *stream = tmp->data;
923 if (flags & GST_SEEK_FLAG_ACCURATE)
924 stream->needs_keyframe = TRUE;
926 stream->seeked_pts = GST_CLOCK_TIME_NONE;
927 stream->seeked_dts = GST_CLOCK_TIME_NONE;
928 stream->need_newsegment = TRUE;
929 stream->first_pts = GST_CLOCK_TIME_NONE;
937 gst_ts_demux_srcpad_event (GstPad * pad, GstObject * parent, GstEvent * event)
940 GstTSDemux *demux = GST_TS_DEMUX (parent);
942 GST_DEBUG_OBJECT (pad, "Got event %s",
943 gst_event_type_get_name (GST_EVENT_TYPE (event)));
945 switch (GST_EVENT_TYPE (event)) {
947 res = mpegts_base_handle_seek_event ((MpegTSBase *) demux, pad, event);
949 GST_WARNING ("seeking failed");
950 gst_event_unref (event);
953 res = gst_pad_event_default (pad, parent, event);
960 clean_global_taglist (GstTagList * taglist)
962 gst_tag_list_remove_tag (taglist, GST_TAG_CONTAINER_FORMAT);
963 gst_tag_list_remove_tag (taglist, GST_TAG_CODEC);
967 push_event (MpegTSBase * base, GstEvent * event)
969 GstTSDemux *demux = (GstTSDemux *) base;
971 gboolean early_ret = FALSE;
973 if (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT) {
974 GST_DEBUG_OBJECT (base, "Ignoring segment event (recreated later)");
975 gst_event_unref (event);
978 } else if (GST_EVENT_TYPE (event) == GST_EVENT_TAG) {
979 /* In case we receive tags before data, store them to send later
980 * If we already have the program, send it right away */
983 gst_event_parse_tag (event, &taglist);
985 if (demux->global_tags == NULL) {
986 demux->global_tags = gst_tag_list_copy (taglist);
988 /* Tags that are stream specific for the container should be considered
989 * global for the container streams */
990 if (gst_tag_list_get_scope (taglist) == GST_TAG_SCOPE_STREAM) {
991 gst_tag_list_set_scope (demux->global_tags, GST_TAG_SCOPE_GLOBAL);
994 demux->global_tags = gst_tag_list_make_writable (demux->global_tags);
995 gst_tag_list_insert (demux->global_tags, taglist, GST_TAG_MERGE_REPLACE);
997 clean_global_taglist (demux->global_tags);
999 /* tags are stored to be used after if there are no streams yet,
1000 * so we should never reject */
1004 if (G_UNLIKELY (demux->program == NULL)) {
1005 gst_event_unref (event);
1009 for (tmp = demux->program->stream_list; tmp; tmp = tmp->next) {
1010 TSDemuxStream *stream = (TSDemuxStream *) tmp->data;
1012 /* If we are pushing out EOS, flush out pending data first */
1013 if (GST_EVENT_TYPE (event) == GST_EVENT_EOS &&
1014 gst_pad_is_active (stream->pad))
1015 gst_ts_demux_push_pending_data (demux, stream, NULL);
1017 gst_event_ref (event);
1018 gst_pad_push_event (stream->pad, event);
1022 gst_event_unref (event);
1028 sink_query (MpegTSBase * base, GstQuery * query)
1030 GstTSDemux *demux = (GstTSDemux *) base;
1031 gboolean res = FALSE;
1033 switch (GST_QUERY_TYPE (query)) {
1034 case GST_QUERY_BITRATE:{
1036 GstClockTime duration;
1038 if (gst_pad_peer_query_duration (base->sinkpad, GST_FORMAT_BYTES,
1039 &size_bytes) && size_bytes > 0) {
1040 if (gst_ts_demux_get_duration (demux, &duration) && duration > 0
1041 && duration != GST_CLOCK_TIME_NONE) {
1043 gst_util_uint64_scale (8 * size_bytes, GST_SECOND, duration);
1045 GST_LOG_OBJECT (demux, "bitrate query byte length: %" G_GINT64_FORMAT
1046 " duration %" GST_TIME_FORMAT " resulting in a bitrate of %u",
1047 size_bytes, GST_TIME_ARGS (duration), bitrate);
1048 gst_query_set_bitrate (query, bitrate);
1055 res = GST_MPEGTS_BASE_CLASS (parent_class)->sink_query (base, query);
1063 add_iso639_language_to_tags (TSDemuxStream * stream, gchar * lang_code)
1067 GST_LOG ("Add language code for stream: '%s'", lang_code);
1069 if (!stream->taglist)
1070 stream->taglist = gst_tag_list_new_empty ();
1072 /* descriptor contains ISO 639-2 code, we want the ISO 639-1 code */
1073 lc = gst_tag_get_language_code (lang_code);
1075 /* Only set tag if we have a valid one */
1076 if (lc || (lang_code[0] && lang_code[1]))
1077 gst_tag_list_add (stream->taglist, GST_TAG_MERGE_REPLACE,
1078 GST_TAG_LANGUAGE_CODE, (lc) ? lc : lang_code, NULL);
1082 gst_ts_demux_create_tags (TSDemuxStream * stream)
1084 MpegTSBaseStream *bstream = (MpegTSBaseStream *) stream;
1085 const GstMpegtsDescriptor *desc = NULL;
1089 mpegts_get_descriptor_from_stream (bstream,
1090 GST_MTS_DESC_ISO_639_LANGUAGE);
1094 nb = gst_mpegts_descriptor_parse_iso_639_language_nb (desc);
1096 GST_DEBUG ("Found ISO 639 descriptor (%d entries)", nb);
1098 for (i = 0; i < nb; i++)
1099 if (gst_mpegts_descriptor_parse_iso_639_language_idx (desc, i, &lang_code,
1101 add_iso639_language_to_tags (stream, lang_code);
1109 mpegts_get_descriptor_from_stream (bstream, GST_MTS_DESC_DVB_SUBTITLING);
1114 nb = gst_mpegts_descriptor_parse_dvb_subtitling_nb (desc);
1116 GST_DEBUG ("Found SUBTITLING descriptor (%d entries)", nb);
1118 for (i = 0; i < nb; i++)
1119 if (gst_mpegts_descriptor_parse_dvb_subtitling_idx (desc, i, &lang_code,
1120 NULL, NULL, NULL)) {
1121 add_iso639_language_to_tags (stream, lang_code);
1127 #ifdef TIZEN_FEATURE_AVOID_PAD_SWITCHING
1129 gst_ts_demux_stream_send_stream_start (MpegTSBase * base,
1130 MpegTSBaseStream * bstream, GstPad * pad)
1132 GstTSDemux *demux = GST_TS_DEMUX_CAST (base);
1133 TSDemuxStream *stream = (TSDemuxStream *) bstream;
1135 const gchar *stream_id;
1137 stream_id = gst_stream_get_stream_id (bstream->stream_object);
1138 event = gst_pad_get_sticky_event (base->sinkpad, GST_EVENT_STREAM_START, 0);
1140 if (gst_event_parse_group_id (event, &demux->group_id))
1141 demux->have_group_id = TRUE;
1143 demux->have_group_id = FALSE;
1144 gst_event_unref (event);
1145 } else if (!demux->have_group_id) {
1146 demux->have_group_id = TRUE;
1147 demux->group_id = gst_util_group_id_next ();
1149 event = gst_event_new_stream_start (stream_id);
1150 gst_event_set_stream (event, bstream->stream_object);
1151 if (demux->have_group_id)
1152 gst_event_set_group_id (event, demux->group_id);
1154 if (stream->sparse) {
1155 gst_event_set_stream_flags (event, GST_STREAM_FLAG_SPARSE);
1156 gst_stream_set_stream_flags (bstream->stream_object,
1157 GST_STREAM_FLAG_SPARSE);
1160 gst_pad_push_event (pad, event);
1165 create_pad_for_stream (MpegTSBase * base, MpegTSBaseStream * bstream,
1166 MpegTSBaseProgram * program)
1168 GstTSDemux *demux = GST_TS_DEMUX (base);
1169 TSDemuxStream *stream = (TSDemuxStream *) bstream;
1171 GstCaps *caps = NULL;
1172 GstPadTemplate *template = NULL;
1173 const GstMpegtsDescriptor *desc = NULL;
1175 gboolean sparse = FALSE;
1176 gboolean is_audio = FALSE, is_video = FALSE, is_subpicture = FALSE,
1179 gst_ts_demux_create_tags (stream);
1181 GST_LOG ("Attempting to create pad for stream 0x%04x with stream_type %d",
1182 bstream->pid, bstream->stream_type);
1184 /* First handle BluRay-specific stream types since there is some overlap
1185 * between BluRay and non-BluRay streay type identifiers */
1186 if (program->registration_id == DRF_ID_HDMV) {
1187 switch (bstream->stream_type) {
1188 case ST_BD_AUDIO_AC3:
1190 const GstMpegtsDescriptor *ac3_desc;
1192 /* ATSC ac3 audio descriptor */
1194 mpegts_get_descriptor_from_stream (bstream,
1195 GST_MTS_DESC_AC3_AUDIO_STREAM);
1196 if (ac3_desc && DESC_AC_AUDIO_STREAM_bsid (ac3_desc->data) != 16) {
1197 GST_LOG ("ac3 audio");
1199 caps = gst_caps_new_empty_simple ("audio/x-ac3");
1202 caps = gst_caps_new_empty_simple ("audio/x-eac3");
1206 case ST_BD_AUDIO_EAC3:
1207 case ST_BD_AUDIO_AC3_PLUS:
1209 caps = gst_caps_new_empty_simple ("audio/x-eac3");
1211 case ST_BD_AUDIO_AC3_TRUE_HD:
1213 caps = gst_caps_new_empty_simple ("audio/x-true-hd");
1214 stream->target_pes_substream = 0x72;
1216 case ST_BD_AUDIO_LPCM:
1218 caps = gst_caps_new_empty_simple ("audio/x-private-ts-lpcm");
1220 case ST_BD_PGS_SUBPICTURE:
1221 is_subpicture = TRUE;
1222 caps = gst_caps_new_empty_simple ("subpicture/x-pgs");
1225 case ST_BD_AUDIO_DTS_HD:
1226 case ST_BD_AUDIO_DTS_HD_MASTER_AUDIO:
1228 caps = gst_caps_new_empty_simple ("audio/x-dts");
1229 stream->target_pes_substream = 0x71;
1237 /* Handle non-BluRay stream types */
1238 switch (bstream->stream_type) {
1239 case GST_MPEGTS_STREAM_TYPE_VIDEO_MPEG1:
1240 case GST_MPEGTS_STREAM_TYPE_VIDEO_MPEG2:
1241 case ST_PS_VIDEO_MPEG2_DCII:
1242 /* FIXME : Use DCII registration code (ETV1 ?) to handle that special
1243 * Stream type (ST_PS_VIDEO_MPEG2_DCII) */
1244 /* FIXME : Use video decriptor (0x1) to refine caps with:
1246 * * profile_and_level
1248 GST_LOG ("mpeg video");
1250 caps = gst_caps_new_simple ("video/mpeg",
1251 "mpegversion", G_TYPE_INT,
1252 bstream->stream_type == GST_MPEGTS_STREAM_TYPE_VIDEO_MPEG1 ? 1 : 2,
1253 "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
1256 case GST_MPEGTS_STREAM_TYPE_AUDIO_MPEG1:
1257 case GST_MPEGTS_STREAM_TYPE_AUDIO_MPEG2:
1258 GST_LOG ("mpeg audio");
1261 gst_caps_new_simple ("audio/mpeg", "mpegversion", G_TYPE_INT, 1,
1263 /* HDV is always mpeg 1 audio layer 2 */
1264 if (program->registration_id == DRF_ID_TSHV)
1265 gst_caps_set_simple (caps, "layer", G_TYPE_INT, 2, NULL);
1267 case GST_MPEGTS_STREAM_TYPE_PRIVATE_PES_PACKETS:
1268 GST_LOG ("private data");
1269 /* FIXME: Move all of this into a common method (there might be other
1270 * types also, depending on registratino descriptors also
1272 desc = mpegts_get_descriptor_from_stream (bstream, GST_MTS_DESC_DVB_AC3);
1274 GST_LOG ("ac3 audio");
1276 caps = gst_caps_new_empty_simple ("audio/x-ac3");
1281 mpegts_get_descriptor_from_stream (bstream,
1282 GST_MTS_DESC_DVB_ENHANCED_AC3);
1284 GST_LOG ("ac3 audio");
1286 caps = gst_caps_new_empty_simple ("audio/x-eac3");
1290 mpegts_get_descriptor_from_stream (bstream,
1291 GST_MTS_DESC_DVB_TELETEXT);
1293 GST_LOG ("teletext");
1295 caps = gst_caps_new_empty_simple ("application/x-teletext");
1300 mpegts_get_descriptor_from_stream (bstream,
1301 GST_MTS_DESC_DVB_SUBTITLING);
1303 GST_LOG ("subtitling");
1304 is_subpicture = TRUE;
1305 caps = gst_caps_new_empty_simple ("subpicture/x-dvb");
1310 switch (bstream->registration_id) {
1314 /* SMPTE registered DTS */
1316 caps = gst_caps_new_empty_simple ("audio/x-dts");
1320 caps = gst_caps_new_empty_simple ("audio/x-smpte-302m");
1323 desc = mpegts_get_descriptor_from_stream (bstream,
1324 GST_MTS_DESC_DVB_EXTENSION);
1325 if (desc != NULL && desc->tag_extension == 0x80 && desc->length >= 1) { /* User defined (provisional Opus) */
1326 guint8 channel_config_code;
1329 /* skip tag, length and tag_extension */
1330 gst_byte_reader_init (&br, desc->data + 3, desc->length - 1);
1331 channel_config_code = gst_byte_reader_get_uint8_unchecked (&br);
1333 if ((channel_config_code & 0x8f) <= 8) {
1334 static const guint8 coupled_stream_counts[9] = {
1335 1, 0, 1, 1, 2, 2, 2, 3, 3
1337 static const guint8 channel_map_a[8][8] = {
1344 {0, 4, 1, 2, 3, 5, 6},
1345 {0, 6, 1, 2, 3, 4, 5, 7},
1347 static const guint8 channel_map_b[8][8] = {
1354 {0, 1, 2, 3, 4, 5, 6},
1355 {0, 1, 2, 3, 4, 5, 6, 7},
1358 gint channels = -1, stream_count, coupled_count, mapping_family;
1359 guint8 *channel_mapping = NULL;
1361 channels = channel_config_code ? (channel_config_code & 0x0f) : 2;
1362 if (channel_config_code == 0 || channel_config_code == 0x80) {
1364 mapping_family = 255;
1365 if (channel_config_code == 0) {
1372 channel_mapping = g_new0 (guint8, channels);
1373 memcpy (channel_mapping, &channel_map_a[1], channels);
1374 } else if (channel_config_code <= 8) {
1375 mapping_family = (channels > 2) ? 1 : 0;
1377 channel_config_code -
1378 coupled_stream_counts[channel_config_code];
1379 coupled_count = coupled_stream_counts[channel_config_code];
1380 if (mapping_family != 0) {
1381 channel_mapping = g_new0 (guint8, channels);
1382 memcpy (channel_mapping, &channel_map_a[channels - 1],
1385 } else if (channel_config_code >= 0x82
1386 && channel_config_code <= 0x88) {
1388 stream_count = channels;
1390 channel_mapping = g_new0 (guint8, channels);
1391 memcpy (channel_mapping, &channel_map_b[channels - 1],
1393 } else if (channel_config_code == 0x81) {
1394 if (gst_byte_reader_get_remaining (&br) < 2) {
1395 GST_WARNING_OBJECT (demux,
1396 "Invalid Opus descriptor with extended channel configuration");
1401 channels = gst_byte_reader_get_uint8_unchecked (&br);
1402 mapping_family = gst_byte_reader_get_uint8_unchecked (&br);
1404 /* Overwrite values from above */
1405 if (channels == 0) {
1406 GST_WARNING_OBJECT (demux,
1407 "Invalid Opus descriptor with extended channel configuration");
1412 if (mapping_family == 0 && channels <= 2) {
1413 stream_count = channels - coupled_stream_counts[channels];
1414 coupled_count = coupled_stream_counts[channels];
1416 GstBitReader breader;
1417 guint8 stream_count_minus_one, coupled_stream_count;
1418 gint stream_count_minus_one_len, coupled_stream_count_len;
1419 gint channel_mapping_len, i;
1421 gst_bit_reader_init (&breader,
1422 gst_byte_reader_get_data_unchecked
1423 (&br, gst_byte_reader_get_remaining
1424 (&br)), gst_byte_reader_get_remaining (&br));
1426 stream_count_minus_one_len = ceil (_gst_log2 (channels));
1427 if (!gst_bit_reader_get_bits_uint8 (&breader,
1428 &stream_count_minus_one,
1429 stream_count_minus_one_len)) {
1430 GST_WARNING_OBJECT (demux,
1431 "Invalid Opus descriptor with extended channel configuration");
1436 stream_count = stream_count_minus_one + 1;
1437 coupled_stream_count_len =
1438 ceil (_gst_log2 (stream_count_minus_one + 2));
1440 if (!gst_bit_reader_get_bits_uint8 (&breader,
1441 &coupled_stream_count, coupled_stream_count_len)) {
1442 GST_WARNING_OBJECT (demux,
1443 "Invalid Opus descriptor with extended channel configuration");
1448 coupled_count = coupled_stream_count;
1450 channel_mapping_len =
1451 ceil (_gst_log2 (stream_count_minus_one + 1 +
1452 coupled_stream_count + 1));
1453 channel_mapping = g_new0 (guint8, channels);
1454 for (i = 0; i < channels; i++) {
1455 if (!gst_bit_reader_get_bits_uint8 (&breader,
1456 &channel_mapping[i], channel_mapping_len)) {
1457 GST_WARNING_OBJECT (demux,
1458 "Invalid Opus descriptor with extended channel configuration");
1464 if (i != channels) {
1466 g_free (channel_mapping);
1467 channel_mapping = NULL;
1472 g_assert_not_reached ();
1475 if (channels != -1) {
1478 gst_codec_utils_opus_create_caps (48000, channels,
1479 mapping_family, stream_count, coupled_count,
1482 g_free (channel_mapping);
1485 GST_WARNING_OBJECT (demux,
1486 "unexpected channel config code 0x%02x", channel_config_code);
1489 GST_WARNING_OBJECT (demux, "Opus, but no extension descriptor");
1494 caps = gst_caps_new_simple ("video/x-h265",
1495 "stream-format", G_TYPE_STRING, "byte-stream",
1496 "alignment", G_TYPE_STRING, "nal", NULL);
1501 caps = gst_caps_new_simple ("meta/x-klv",
1502 "parsed", G_TYPE_BOOLEAN, TRUE, NULL);
1508 /* hack for itv hd (sid 10510, video pid 3401 */
1509 if (program->program_number == 10510 && bstream->pid == 3401) {
1511 caps = gst_caps_new_simple ("video/x-h264",
1512 "stream-format", G_TYPE_STRING, "byte-stream",
1513 "alignment", G_TYPE_STRING, "nal", NULL);
1517 /* FIXME : Should only be used with specific PMT registration_descriptor */
1518 /* We don't expose those streams since they're only helper streams */
1519 /* template = gst_static_pad_template_get (&private_template); */
1520 /* name = g_strdup_printf ("private_%04x", bstream->pid); */
1521 /* caps = gst_caps_new_simple ("hdv/aux-v", NULL); */
1524 /* FIXME : Should only be used with specific PMT registration_descriptor */
1525 /* We don't expose those streams since they're only helper streams */
1526 /* template = gst_static_pad_template_get (&private_template); */
1527 /* name = g_strdup_printf ("private_%04x", bstream->pid); */
1528 /* caps = gst_caps_new_simple ("hdv/aux-a", NULL); */
1530 case GST_MPEGTS_STREAM_TYPE_AUDIO_AAC_ADTS:
1532 caps = gst_caps_new_simple ("audio/mpeg",
1533 "mpegversion", G_TYPE_INT, 2,
1534 "stream-format", G_TYPE_STRING, "adts", NULL);
1536 case GST_MPEGTS_STREAM_TYPE_AUDIO_AAC_LATM:
1538 caps = gst_caps_new_simple ("audio/mpeg",
1539 "mpegversion", G_TYPE_INT, 4,
1540 "stream-format", G_TYPE_STRING, "loas", NULL);
1542 case GST_MPEGTS_STREAM_TYPE_VIDEO_MPEG4:
1544 caps = gst_caps_new_simple ("video/mpeg",
1545 "mpegversion", G_TYPE_INT, 4,
1546 "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
1548 case GST_MPEGTS_STREAM_TYPE_VIDEO_H264:
1550 caps = gst_caps_new_simple ("video/x-h264",
1551 "stream-format", G_TYPE_STRING, "byte-stream",
1552 "alignment", G_TYPE_STRING, "nal", NULL);
1554 case GST_MPEGTS_STREAM_TYPE_VIDEO_HEVC:
1556 caps = gst_caps_new_simple ("video/x-h265",
1557 "stream-format", G_TYPE_STRING, "byte-stream",
1558 "alignment", G_TYPE_STRING, "nal", NULL);
1560 case GST_MPEGTS_STREAM_TYPE_VIDEO_JP2K:
1563 mpegts_get_descriptor_from_stream (bstream, GST_MTS_DESC_J2K_VIDEO);
1565 caps = gst_caps_new_empty_simple ("image/x-jpc");
1569 guint16 DEN_frame_rate = 0;
1570 guint16 NUM_frame_rate = 0;
1571 guint8 color_specification = 0;
1572 guint8 remaining_8b = 0;
1573 gboolean interlaced_video = 0;
1574 const gchar *interlace_mode = NULL;
1575 const gchar *colorspace = NULL;
1576 const gchar *colorimetry_mode = NULL;
1577 guint16 profile_and_level G_GNUC_UNUSED;
1578 guint32 horizontal_size G_GNUC_UNUSED;
1579 guint32 vertical_size G_GNUC_UNUSED;
1580 guint32 max_bit_rate G_GNUC_UNUSED;
1581 guint32 max_buffer_size G_GNUC_UNUSED;
1582 const guint desc_min_length = 24;
1584 if (desc->length < desc_min_length) {
1586 ("GST_MPEGTS_STREAM_TYPE_VIDEO_JP2K: descriptor length %d too short",
1591 /* Skip the descriptor tag and length */
1592 gst_byte_reader_init (&br, desc->data + 2, desc->length);
1594 profile_and_level = gst_byte_reader_get_uint16_be_unchecked (&br);
1595 horizontal_size = gst_byte_reader_get_uint32_be_unchecked (&br);
1596 vertical_size = gst_byte_reader_get_uint32_be_unchecked (&br);
1597 max_bit_rate = gst_byte_reader_get_uint32_be_unchecked (&br);
1598 max_buffer_size = gst_byte_reader_get_uint32_be_unchecked (&br);
1599 DEN_frame_rate = gst_byte_reader_get_uint16_be_unchecked (&br);
1600 NUM_frame_rate = gst_byte_reader_get_uint16_be_unchecked (&br);
1601 color_specification = gst_byte_reader_get_uint8_unchecked (&br);
1602 remaining_8b = gst_byte_reader_get_uint8_unchecked (&br);
1603 interlaced_video = remaining_8b & 0x40;
1604 /* we don't support demuxing interlaced at the moment */
1605 if (interlaced_video) {
1607 ("GST_MPEGTS_STREAM_TYPE_VIDEO_JP2K: interlaced video not supported");
1610 interlace_mode = "progressive";
1611 stream->jp2kInfos.interlace = FALSE;
1613 switch (color_specification) {
1614 case GST_MPEGTSDEMUX_JPEG2000_COLORSPEC_SRGB:
1615 colorspace = "sRGB";
1616 colorimetry_mode = GST_VIDEO_COLORIMETRY_SRGB;
1618 case GST_MPEGTSDEMUX_JPEG2000_COLORSPEC_REC601:
1619 colorspace = "sYUV";
1620 colorimetry_mode = GST_VIDEO_COLORIMETRY_BT601;
1622 case GST_MPEGTSDEMUX_JPEG2000_COLORSPEC_REC709:
1623 case GST_MPEGTSDEMUX_JPEG2000_COLORSPEC_CIELUV:
1624 colorspace = "sYUV";
1625 colorimetry_mode = GST_VIDEO_COLORIMETRY_BT709;
1630 caps = gst_caps_new_simple ("image/x-jpc",
1631 "framerate", GST_TYPE_FRACTION, NUM_frame_rate, DEN_frame_rate,
1632 "interlace-mode", G_TYPE_STRING, interlace_mode,
1633 "colorimetry", G_TYPE_STRING, colorimetry_mode,
1634 "colorspace", G_TYPE_STRING, colorspace, NULL);
1637 case ST_VIDEO_DIRAC:
1638 if (bstream->registration_id == 0x64726163) {
1642 caps = gst_caps_new_empty_simple ("video/x-dirac");
1645 case ST_PRIVATE_EA: /* Try to detect a VC1 stream */
1647 gboolean is_vc1 = FALSE;
1649 /* Note/FIXME: RP-227 specifies that the registration descriptor
1650 * for vc1 can also contain other information, such as profile,
1651 * level, alignment, buffer_size, .... */
1652 if (bstream->registration_id == DRF_ID_VC1)
1655 GST_WARNING ("0xea private stream type found but no descriptor "
1656 "for VC1. Assuming plain VC1.");
1660 caps = gst_caps_new_simple ("video/x-wmv",
1661 "wmvversion", G_TYPE_INT, 3, "format", G_TYPE_STRING, "WVC1", NULL);
1665 case ST_PS_AUDIO_AC3:
1666 /* DVB_ENHANCED_AC3 */
1668 mpegts_get_descriptor_from_stream (bstream,
1669 GST_MTS_DESC_DVB_ENHANCED_AC3);
1672 caps = gst_caps_new_empty_simple ("audio/x-eac3");
1676 /* If stream has ac3 descriptor
1677 * OR program is ATSC (GA94)
1678 * OR stream registration is AC-3
1679 * then it's regular AC3 */
1680 if (bstream->registration_id == DRF_ID_AC3 ||
1681 program->registration_id == DRF_ID_GA94 ||
1682 mpegts_get_descriptor_from_stream (bstream, GST_MTS_DESC_DVB_AC3)) {
1684 caps = gst_caps_new_empty_simple ("audio/x-ac3");
1688 GST_WARNING ("AC3 stream type found but no guaranteed "
1689 "way found to differentiate between AC3 and EAC3. "
1690 "Assuming plain AC3.");
1692 caps = gst_caps_new_empty_simple ("audio/x-ac3");
1694 case ST_PS_AUDIO_EAC3:
1696 /* ATSC_ENHANCED_AC3 */
1697 if (bstream->registration_id == DRF_ID_EAC3 ||
1698 mpegts_get_descriptor_from_stream (bstream, GST_MTS_DESC_ATSC_EAC3)) {
1700 caps = gst_caps_new_empty_simple ("audio/x-eac3");
1704 GST_ELEMENT_WARNING (demux, STREAM, DEMUX,
1705 ("Assuming ATSC E-AC3 audio stream."),
1706 ("ATSC E-AC3 stream type found but no guarantee way found to "
1707 "differentiate among other standards (DVB, ISDB and etc..)"));
1710 caps = gst_caps_new_empty_simple ("audio/x-eac3");
1713 case ST_PS_AUDIO_LPCM2:
1715 caps = gst_caps_new_empty_simple ("audio/x-private2-lpcm");
1717 case ST_PS_AUDIO_DTS:
1719 caps = gst_caps_new_empty_simple ("audio/x-dts");
1721 case ST_PS_AUDIO_LPCM:
1723 caps = gst_caps_new_empty_simple ("audio/x-lpcm");
1725 case ST_PS_DVD_SUBPICTURE:
1726 is_subpicture = TRUE;
1727 caps = gst_caps_new_empty_simple ("subpicture/x-dvd");
1731 /* hack for Chinese AVS video stream which use 0x42 as stream_id
1732 * NOTE: this is unofficial and within the ISO reserved range. */
1734 caps = gst_caps_new_empty_simple ("video/x-cavs");
1737 GST_DEBUG ("Non-media stream (stream_type:0x%x). Not creating pad",
1738 bstream->stream_type);
1745 template = gst_static_pad_template_get (&audio_template);
1747 g_strdup_printf ("audio_%01x_%04x", demux->program_generation,
1749 gst_stream_set_stream_type (bstream->stream_object,
1750 GST_STREAM_TYPE_AUDIO);
1751 } else if (is_video) {
1752 template = gst_static_pad_template_get (&video_template);
1754 g_strdup_printf ("video_%01x_%04x", demux->program_generation,
1756 gst_stream_set_stream_type (bstream->stream_object,
1757 GST_STREAM_TYPE_VIDEO);
1758 } else if (is_private) {
1759 template = gst_static_pad_template_get (&private_template);
1761 g_strdup_printf ("private_%01x_%04x", demux->program_generation,
1763 } else if (is_subpicture) {
1764 template = gst_static_pad_template_get (&subpicture_template);
1766 g_strdup_printf ("subpicture_%01x_%04x", demux->program_generation,
1768 gst_stream_set_stream_type (bstream->stream_object, GST_STREAM_TYPE_TEXT);
1770 g_assert_not_reached ();
1774 if (template && name && caps) {
1775 #ifdef TIZEN_FEATURE_AVOID_PAD_SWITCHING
1776 GST_LOG ("stream:%p creating pad with name %s and caps %" GST_PTR_FORMAT,
1777 stream, name, caps);
1778 pad = gst_pad_new_from_template (template, name);
1779 gst_pad_set_active (pad, TRUE);
1780 gst_pad_use_fixed_caps (pad);
1782 stream->sparse = sparse;
1783 gst_ts_demux_stream_send_stream_start (base, bstream, pad);
1786 const gchar *stream_id;
1788 GST_LOG ("stream:%p creating pad with name %s and caps %" GST_PTR_FORMAT,
1789 stream, name, caps);
1790 pad = gst_pad_new_from_template (template, name);
1791 gst_pad_set_active (pad, TRUE);
1792 gst_pad_use_fixed_caps (pad);
1793 stream_id = gst_stream_get_stream_id (bstream->stream_object);
1795 event = gst_pad_get_sticky_event (base->sinkpad, GST_EVENT_STREAM_START, 0);
1797 if (gst_event_parse_group_id (event, &demux->group_id))
1798 demux->have_group_id = TRUE;
1800 demux->have_group_id = FALSE;
1801 gst_event_unref (event);
1802 } else if (!demux->have_group_id) {
1803 demux->have_group_id = TRUE;
1804 demux->group_id = gst_util_group_id_next ();
1806 event = gst_event_new_stream_start (stream_id);
1807 gst_event_set_stream (event, bstream->stream_object);
1808 if (demux->have_group_id)
1809 gst_event_set_group_id (event, demux->group_id);
1811 gst_event_set_stream_flags (event, GST_STREAM_FLAG_SPARSE);
1812 gst_stream_set_stream_flags (bstream->stream_object,
1813 GST_STREAM_FLAG_SPARSE);
1815 stream->sparse = sparse;
1817 gst_stream_set_caps (bstream->stream_object, caps);
1818 if (!stream->taglist)
1819 stream->taglist = gst_tag_list_new_empty ();
1820 gst_pb_utils_add_codec_description_to_tag_list (stream->taglist, NULL,
1822 gst_stream_set_tags (bstream->stream_object, stream->taglist);
1824 #ifndef TIZEN_FEATURE_AVOID_PAD_SWITCHING
1825 gst_pad_push_event (pad, event);
1827 gst_pad_set_caps (pad, caps);
1828 gst_pad_set_query_function (pad, gst_ts_demux_srcpad_query);
1829 gst_pad_set_event_function (pad, gst_ts_demux_srcpad_event);
1834 gst_object_unref (template);
1836 gst_caps_unref (caps);
1841 #ifdef TIZEN_FEATURE_AVOID_PAD_SWITCHING
1843 gst_ts_demux_remove_old_streams (GstTSDemux * demux, gboolean push_eos)
1845 if (demux->old_streams) {
1847 for (iter = demux->old_streams; iter; iter = g_list_next (iter)) {
1848 TSDemuxStream *stream = iter->data;
1850 gst_ts_demux_remove_stream (demux, stream, push_eos);
1851 mpegts_base_stream_unref ((MpegTSBaseStream *) stream);
1853 g_list_free (demux->old_streams);
1854 demux->old_streams = NULL;
1861 gst_ts_demux_stream_added (MpegTSBase * base, MpegTSBaseStream * bstream,
1862 MpegTSBaseProgram * program)
1864 GstTSDemux *demux = (GstTSDemux *) base;
1865 TSDemuxStream *stream = (TSDemuxStream *) bstream;
1868 /* Create the pad */
1869 if (bstream->stream_type != 0xff) {
1870 stream->pad = create_pad_for_stream (base, bstream, program);
1872 gst_flow_combiner_add_pad (demux->flowcombiner, stream->pad);
1875 if (base->mode != BASE_MODE_PUSHING
1876 && bstream->stream_type == GST_MPEGTS_STREAM_TYPE_VIDEO_H264) {
1877 stream->scan_function =
1878 (GstTsDemuxKeyFrameScanFunction) scan_keyframe_h264;
1880 stream->scan_function = NULL;
1883 stream->active = FALSE;
1885 stream->need_newsegment = TRUE;
1886 /* Reset segment if we're not doing an accurate seek */
1887 demux->reset_segment = (!(demux->segment.flags & GST_SEEK_FLAG_ACCURATE));
1888 stream->needs_keyframe = FALSE;
1889 stream->discont = TRUE;
1890 stream->pts = GST_CLOCK_TIME_NONE;
1891 stream->dts = GST_CLOCK_TIME_NONE;
1892 stream->first_pts = GST_CLOCK_TIME_NONE;
1893 stream->raw_pts = -1;
1894 stream->raw_dts = -1;
1895 stream->pending_ts = TRUE;
1896 stream->nb_out_buffers = 0;
1897 stream->gap_ref_buffers = 0;
1898 stream->gap_ref_pts = GST_CLOCK_TIME_NONE;
1899 /* Only wait for a valid timestamp if we have a PCR_PID */
1900 stream->pending_ts = program->pcr_pid < 0x1fff;
1901 stream->continuity_counter = CONTINUITY_UNSET;
1904 return (stream->pad != NULL);
1908 tsdemux_h264_parsing_info_clear (TSDemuxH264ParsingInfos * h264infos)
1910 clear_simple_buffer (&h264infos->framedata);
1912 if (h264infos->parser) {
1913 gst_h264_nal_parser_free (h264infos->parser);
1914 gst_byte_writer_free (h264infos->sps);
1915 gst_byte_writer_free (h264infos->pps);
1916 gst_byte_writer_free (h264infos->sei);
1920 #ifdef TIZEN_FEATURE_AVOID_PAD_SWITCHING
1922 gst_ts_demux_stream_rename_stopping_pad (GstTSDemux * demux,
1923 TSDemuxStream * stream)
1928 GST_DEBUG_OBJECT (stream->pad, "Renaming stopping pad: %s",
1929 GST_PAD_NAME (stream->pad));
1930 name = g_strdup_printf ("%s_stopping", GST_PAD_NAME (stream->pad));
1931 gst_object_set_name (GST_OBJECT_CAST (stream->pad), name);
1938 gst_ts_demux_remove_stream (GstTSDemux * tsdemux, TSDemuxStream * stream,
1942 if (push_eos && stream->active) {
1943 GST_DEBUG_OBJECT (stream->pad, "Pushing out EOS");
1944 gst_pad_push_event (stream->pad, gst_event_new_eos ());
1945 gst_pad_set_active (stream->pad, FALSE);
1948 GST_DEBUG_OBJECT (stream->pad, "Removing pad");
1949 gst_element_remove_pad (GST_ELEMENT_CAST (tsdemux), stream->pad);
1950 stream->active = FALSE;
1957 gst_ts_demux_stream_removed (MpegTSBase * base, MpegTSBaseStream * bstream)
1959 TSDemuxStream *stream = (TSDemuxStream *) bstream;
1960 #ifdef TIZEN_FEATURE_AVOID_PAD_SWITCHING
1961 GstTSDemux *tsdemux = (GstTSDemux *) base;
1965 gst_flow_combiner_remove_pad (GST_TS_DEMUX_CAST (base)->flowcombiner,
1967 if (stream->active) {
1969 if (gst_pad_is_active (stream->pad)) {
1970 /* Flush out all data */
1971 GST_DEBUG_OBJECT (stream->pad, "Flushing out pending data");
1972 gst_ts_demux_push_pending_data ((GstTSDemux *) base, stream, NULL);
1973 #ifndef TIZEN_FEATURE_AVOID_PAD_SWITCHING
1974 GST_DEBUG_OBJECT (stream->pad, "Pushing out EOS");
1975 gst_pad_push_event (stream->pad, gst_event_new_eos ());
1976 gst_pad_set_active (stream->pad, FALSE);
1979 #ifndef TIZEN_FEATURE_AVOID_PAD_SWITCHING
1980 GST_DEBUG_OBJECT (stream->pad, "Removing pad");
1981 gst_element_remove_pad (GST_ELEMENT_CAST (base), stream->pad);
1982 stream->active = FALSE;
1985 gst_object_unref (stream->pad);
1987 #ifndef TIZEN_FEATURE_AVOID_PAD_SWITCHING
1992 gst_ts_demux_stream_flush (stream, GST_TS_DEMUX_CAST (base), TRUE);
1994 if (stream->taglist != NULL) {
1995 gst_tag_list_unref (stream->taglist);
1996 stream->taglist = NULL;
1999 tsdemux_h264_parsing_info_clear (&stream->h264infos);
2000 #ifdef TIZEN_FEATURE_AVOID_PAD_SWITCHING
2001 /* Keep our reference as we can only finish the stream once we added
2002 * pads for the new program or the pipeline might go EOS */
2003 mpegts_base_stream_ref (bstream);
2004 tsdemux->old_streams = g_list_append (tsdemux->old_streams, bstream);
2010 activate_pad_for_stream (GstTSDemux * tsdemux, TSDemuxStream * stream)
2013 GST_DEBUG_OBJECT (tsdemux, "Activating pad %s:%s for stream %p",
2014 GST_DEBUG_PAD_NAME (stream->pad), stream);
2015 gst_element_add_pad ((GstElement *) tsdemux, stream->pad);
2016 stream->active = TRUE;
2017 GST_DEBUG_OBJECT (stream->pad, "done adding pad");
2018 } else if (((MpegTSBaseStream *) stream)->stream_type != 0xff) {
2019 GST_DEBUG_OBJECT (tsdemux,
2020 "stream %p (pid 0x%04x, type:0x%02x) has no pad", stream,
2021 ((MpegTSBaseStream *) stream)->pid,
2022 ((MpegTSBaseStream *) stream)->stream_type);
2027 gst_ts_demux_stream_flush (TSDemuxStream * stream, GstTSDemux * tsdemux,
2030 GST_DEBUG ("flushing stream %p", stream);
2032 g_free (stream->data);
2033 stream->data = NULL;
2034 stream->state = PENDING_PACKET_EMPTY;
2035 stream->expected_size = 0;
2036 stream->allocated_size = 0;
2037 stream->current_size = 0;
2038 stream->discont = TRUE;
2039 stream->pts = GST_CLOCK_TIME_NONE;
2040 stream->dts = GST_CLOCK_TIME_NONE;
2041 stream->raw_pts = -1;
2042 stream->raw_dts = -1;
2043 stream->pending_ts = TRUE;
2044 stream->nb_out_buffers = 0;
2045 stream->gap_ref_buffers = 0;
2046 stream->gap_ref_pts = GST_CLOCK_TIME_NONE;
2047 stream->continuity_counter = CONTINUITY_UNSET;
2049 if (G_UNLIKELY (stream->pending)) {
2052 GST_DEBUG ("clearing pending %p", stream);
2053 for (tmp = stream->pending; tmp; tmp = tmp->next) {
2054 PendingBuffer *pend = (PendingBuffer *) tmp->data;
2055 gst_buffer_unref (pend->buffer);
2056 g_slice_free (PendingBuffer, pend);
2058 g_list_free (stream->pending);
2059 stream->pending = NULL;
2063 stream->first_pts = GST_CLOCK_TIME_NONE;
2064 stream->need_newsegment = TRUE;
2069 gst_ts_demux_flush_streams (GstTSDemux * demux, gboolean hard)
2072 if (!demux->program)
2075 for (walk = demux->program->stream_list; walk; walk = g_list_next (walk))
2076 gst_ts_demux_stream_flush (walk->data, demux, hard);
2080 gst_ts_demux_can_remove_program (MpegTSBase * base, MpegTSBaseProgram * program)
2082 GstTSDemux *demux = GST_TS_DEMUX (base);
2084 /* If it's our current active program, we return FALSE, we'll deactivate it
2085 * ourselves when the next program gets activated */
2086 if (demux->program == program) {
2088 ("Attempting to remove current program, delaying until new program gets activated");
2089 demux->previous_program = program;
2090 demux->program_number = -1;
2097 gst_ts_demux_update_program (MpegTSBase * base, MpegTSBaseProgram * program)
2099 GstTSDemux *demux = GST_TS_DEMUX (base);
2102 GST_DEBUG ("Updating program %d", program->program_number);
2103 /* Emit collection message */
2104 gst_element_post_message ((GstElement *) base,
2105 gst_message_new_stream_collection ((GstObject *) base,
2106 program->collection));
2108 /* Add all streams, then fire no-more-pads */
2109 for (tmp = program->stream_list; tmp; tmp = tmp->next) {
2110 TSDemuxStream *stream = (TSDemuxStream *) tmp->data;
2112 activate_pad_for_stream (demux, stream);
2113 if (stream->sparse) {
2114 /* force sending of pending sticky events which have been stored on the
2115 * pad already and which otherwise would only be sent on the first buffer
2116 * or serialized event (which means very late in case of subtitle streams),
2117 * and playsink waits for stream-start or another serialized event */
2118 GST_DEBUG_OBJECT (stream->pad, "sparse stream, pushing GAP event");
2119 gst_pad_push_event (stream->pad, gst_event_new_gap (0, 0));
2125 #ifdef TIZEN_FEATURE_AVOID_PAD_SWITCHING
2127 gst_ts_demux_find_matching_stream (GstTSDemux * demux, TSDemuxStream * stream,
2128 GList * streams_list)
2132 if (stream->pad == NULL)
2135 this_caps = gst_pad_get_current_caps (stream->pad);
2136 for (; streams_list; streams_list = g_list_next (streams_list)) {
2137 TSDemuxStream *other_stream = streams_list->data;
2139 if (other_stream->pad == NULL)
2142 if (other_stream->matched_stream)
2145 if (gst_pad_peer_query_accept_caps (other_stream->pad, this_caps)) {
2146 /* TODO we are not checking the PIDs so the pad names will be
2147 * inconsistent with the new streams' PIDs */
2148 other_stream->matched_stream = stream;
2149 stream->matched_stream = other_stream;
2150 gst_caps_unref (this_caps);
2155 gst_caps_unref (this_caps);
2156 GST_DEBUG_OBJECT (demux, "No match found for stream: %p %" GST_PTR_FORMAT,
2157 stream, stream->pad);
2162 push_sticky_event (GstPad * pad, GstEvent ** event, gpointer udata)
2164 GstPad *other_pad = udata;
2166 gst_pad_push_event (other_pad, gst_event_ref (*event));
2172 gst_ts_demux_check_streams_match (GstTSDemux * demux)
2175 gint old_length = 0;
2176 gint new_length = 0;
2178 if (!demux->old_streams) {
2179 GST_DEBUG_OBJECT (demux, "No old streams present, streams don't match");
2183 /* Initialize matching variables */
2184 for (iter = demux->program->stream_list; iter; iter = g_list_next (iter)) {
2185 TSDemuxStream *stream = iter->data;
2188 stream->matched_stream = NULL;
2191 for (iter = demux->old_streams; iter; iter = g_list_next (iter)) {
2192 TSDemuxStream *stream = iter->data;
2195 stream->matched_stream = NULL;
2199 if (new_length != old_length) {
2200 GST_DEBUG_OBJECT (demux,
2201 "Number of streams is different, no match possible");
2205 for (iter = demux->program->stream_list; iter; iter = g_list_next (iter)) {
2206 if (!gst_ts_demux_find_matching_stream (demux, iter->data,
2207 demux->old_streams))
2211 GST_DEBUG_OBJECT (demux, "Streams matched, no need for pad switching");
2213 /* do the pad replacement, unref pads from new streams and use the pads
2214 * from the old ones */
2215 for (iter = demux->program->stream_list; iter; iter = g_list_next (iter)) {
2216 TSDemuxStream *stream = iter->data;
2218 if (stream->pad && stream->matched_stream) {
2219 GstPad *pad = stream->pad;
2221 stream->pad = stream->matched_stream->pad;
2222 stream->matched_stream->pad = NULL;
2223 stream->active = TRUE;
2224 stream->need_newsegment = FALSE;
2226 gst_ts_demux_stream_send_stream_start ((MpegTSBase *) demux,
2227 (MpegTSBaseStream *) stream, stream->pad);
2229 gst_pad_sticky_events_foreach (pad, push_sticky_event, stream->pad);
2231 gst_object_unref (pad);
2240 gst_ts_demux_program_started (MpegTSBase * base, MpegTSBaseProgram * program)
2242 GstTSDemux *demux = GST_TS_DEMUX (base);
2244 GST_DEBUG ("Current program %d, new program %d requested program %d",
2245 (gint) demux->program_number, program->program_number,
2246 demux->requested_program_number);
2248 if (demux->requested_program_number == program->program_number ||
2249 (demux->requested_program_number == -1 && demux->program_number == -1)) {
2251 #ifndef TIZEN_FEATURE_AVOID_PAD_SWITCHING
2252 gboolean have_pads = FALSE;
2255 GST_LOG ("program %d started", program->program_number);
2256 demux->program_number = program->program_number;
2257 demux->program = program;
2259 /* Increment the program_generation counter */
2260 demux->program_generation = (demux->program_generation + 1) & 0xf;
2262 /* Emit collection message */
2263 gst_element_post_message ((GstElement *) base,
2264 gst_message_new_stream_collection ((GstObject *) base,
2265 program->collection));
2267 /* If this is not the initial program, we need to calculate
2269 if (demux->segment_event) {
2270 gst_event_unref (demux->segment_event);
2271 demux->segment_event = NULL;
2273 #ifdef TIZEN_FEATURE_AVOID_PAD_SWITCHING
2274 /* Check if the new streams match the old ones to
2275 * prevent switching pads if not needed */
2276 if (gst_ts_demux_check_streams_match (demux))
2279 /* 1) Rename old pad names to avoid clashes (matching PIDs)
2280 * 2) add new streams
2281 * 3) Fire no-more-pads */
2282 for (tmp = demux->old_streams; tmp; tmp = tmp->next) {
2283 TSDemuxStream *stream = (TSDemuxStream *) tmp->data;
2284 gst_ts_demux_stream_rename_stopping_pad (demux, stream);
2286 for (tmp = program->stream_list; tmp; tmp = tmp->next) {
2287 TSDemuxStream *stream = (TSDemuxStream *) tmp->data;
2288 activate_pad_for_stream (demux, stream);
2290 gst_element_no_more_pads ((GstElement *) demux);
2292 gst_ts_demux_remove_old_streams (demux, TRUE);
2294 /* DRAIN ALL STREAMS FIRST ! */
2295 if (demux->previous_program) {
2297 GST_DEBUG_OBJECT (demux, "Draining previous program");
2298 for (tmp = demux->previous_program->stream_list; tmp; tmp = tmp->next) {
2299 TSDemuxStream *stream = (TSDemuxStream *) tmp->data;
2301 gst_ts_demux_push_pending_data (demux, stream,
2302 demux->previous_program);
2306 /* Add all streams, then fire no-more-pads */
2307 for (tmp = program->stream_list; tmp; tmp = tmp->next) {
2308 TSDemuxStream *stream = (TSDemuxStream *) tmp->data;
2309 activate_pad_for_stream (demux, stream);
2314 /* If there was a previous program, now is the time to deactivate it
2315 * and remove old pads (including pushing EOS) */
2316 if (demux->previous_program) {
2317 GST_DEBUG ("Deactivating previous program");
2318 mpegts_base_deactivate_and_free_program (base, demux->previous_program);
2319 demux->previous_program = NULL;
2323 /* If we had no pads, this stream is likely corrupted or unsupported and
2324 * there's not much we can do at this point */
2325 GST_ELEMENT_ERROR (demux, STREAM, WRONG_TYPE,
2326 ("This stream contains no valid or supported streams."),
2327 ("activating program but got no pads"));
2331 /* If any of the stream is sparse, push a GAP event before anything else
2332 * This is done here, and not in activate_pad_for_stream() because pushing
2333 * a GAP event *is* considering data, and we want to ensure the (potential)
2334 * old pads are all removed before we push any data on the new ones */
2335 for (tmp = program->stream_list; tmp; tmp = tmp->next) {
2336 TSDemuxStream *stream = (TSDemuxStream *) tmp->data;
2337 if (stream->sparse) {
2338 /* force sending of pending sticky events which have been stored on the
2339 * pad already and which otherwise would only be sent on the first buffer
2340 * or serialized event (which means very late in case of subtitle streams),
2341 * and playsink waits for stream-start or another serialized event */
2342 GST_DEBUG_OBJECT (stream->pad, "sparse stream, pushing GAP event");
2343 gst_pad_push_event (stream->pad, gst_event_new_gap (0, 0));
2347 gst_element_no_more_pads ((GstElement *) demux);
2353 gst_ts_demux_program_stopped (MpegTSBase * base, MpegTSBaseProgram * program)
2355 GstTSDemux *demux = GST_TS_DEMUX (base);
2357 if (demux->program == program) {
2358 demux->program = NULL;
2359 demux->program_number = -1;
2365 gst_ts_demux_record_pts (GstTSDemux * demux, TSDemuxStream * stream,
2366 guint64 pts, guint64 offset)
2368 MpegTSBaseStream *bs = (MpegTSBaseStream *) stream;
2370 stream->raw_pts = pts;
2372 stream->pts = GST_CLOCK_TIME_NONE;
2376 GST_LOG ("pid 0x%04x raw pts:%" G_GUINT64_FORMAT " at offset %"
2377 G_GUINT64_FORMAT, bs->pid, pts, offset);
2379 /* Compute PTS in GstClockTime */
2381 mpegts_packetizer_pts_to_ts (MPEG_TS_BASE_PACKETIZER (demux),
2382 MPEGTIME_TO_GSTTIME (pts), demux->program->pcr_pid);
2384 GST_LOG ("pid 0x%04x Stored PTS %" G_GUINT64_FORMAT, bs->pid, stream->pts);
2386 if (G_UNLIKELY (demux->emit_statistics)) {
2388 st = gst_structure_new_id_empty (QUARK_TSDEMUX);
2389 gst_structure_id_set (st,
2390 QUARK_PID, G_TYPE_UINT, bs->pid,
2391 QUARK_OFFSET, G_TYPE_UINT64, offset, QUARK_PTS, G_TYPE_UINT64, pts,
2393 gst_element_post_message (GST_ELEMENT_CAST (demux),
2394 gst_message_new_element (GST_OBJECT (demux), st));
2399 gst_ts_demux_record_dts (GstTSDemux * demux, TSDemuxStream * stream,
2400 guint64 dts, guint64 offset)
2402 MpegTSBaseStream *bs = (MpegTSBaseStream *) stream;
2404 stream->raw_dts = dts;
2406 stream->dts = GST_CLOCK_TIME_NONE;
2410 GST_LOG ("pid 0x%04x raw dts:%" G_GUINT64_FORMAT " at offset %"
2411 G_GUINT64_FORMAT, bs->pid, dts, offset);
2413 /* Compute DTS in GstClockTime */
2415 mpegts_packetizer_pts_to_ts (MPEG_TS_BASE_PACKETIZER (demux),
2416 MPEGTIME_TO_GSTTIME (dts), demux->program->pcr_pid);
2418 GST_LOG ("pid 0x%04x Stored DTS %" G_GUINT64_FORMAT, bs->pid, stream->dts);
2420 if (G_UNLIKELY (demux->emit_statistics)) {
2422 st = gst_structure_new_id_empty (QUARK_TSDEMUX);
2423 gst_structure_id_set (st,
2424 QUARK_PID, G_TYPE_UINT, bs->pid,
2425 QUARK_OFFSET, G_TYPE_UINT64, offset, QUARK_DTS, G_TYPE_UINT64, dts,
2427 gst_element_post_message (GST_ELEMENT_CAST (demux),
2428 gst_message_new_element (GST_OBJECT (demux), st));
2432 /* This is called when we haven't got a valid initial PTS/DTS on all streams */
2434 check_pending_buffers (GstTSDemux * demux)
2436 gboolean have_observation = FALSE;
2437 /* The biggest offset */
2440 gboolean have_only_sparse = TRUE;
2442 /* 0. Do we only have sparse stream */
2443 for (tmp = demux->program->stream_list; tmp; tmp = tmp->next) {
2444 TSDemuxStream *tmpstream = (TSDemuxStream *) tmp->data;
2446 if (!tmpstream->sparse) {
2447 have_only_sparse = FALSE;
2452 /* 1. Go over all streams */
2453 for (tmp = demux->program->stream_list; tmp; tmp = tmp->next) {
2454 TSDemuxStream *tmpstream = (TSDemuxStream *) tmp->data;
2455 /* 1.1 check if at least one stream got a valid DTS */
2456 if (have_only_sparse || !tmpstream->sparse) {
2457 if ((tmpstream->raw_dts != -1 && tmpstream->dts != GST_CLOCK_TIME_NONE) ||
2458 (tmpstream->raw_pts != -1 && tmpstream->pts != GST_CLOCK_TIME_NONE)) {
2459 have_observation = TRUE;
2465 /* 2. If we don't have a valid value yet, break out */
2466 if (have_observation == FALSE)
2469 /* 3. Go over all streams that have current/pending data */
2470 for (tmp = demux->program->stream_list; tmp; tmp = tmp->next) {
2471 TSDemuxStream *tmpstream = (TSDemuxStream *) tmp->data;
2472 PendingBuffer *pend;
2473 guint64 firstval, lastval, ts;
2475 /* 3.1 Calculate the offset between current DTS and first DTS */
2476 if (tmpstream->pending == NULL || tmpstream->state == PENDING_PACKET_EMPTY)
2478 /* If we don't have any pending data, the offset is 0 for this stream */
2479 if (tmpstream->pending == NULL)
2481 if (tmpstream->raw_dts != -1)
2482 lastval = tmpstream->raw_dts;
2483 else if (tmpstream->raw_pts != -1)
2484 lastval = tmpstream->raw_pts;
2486 GST_WARNING ("Don't have a last DTS/PTS to use for offset recalculation");
2489 pend = tmpstream->pending->data;
2490 if (pend->dts != -1)
2491 firstval = pend->dts;
2492 else if (pend->pts != -1)
2493 firstval = pend->pts;
2496 ("Don't have a first DTS/PTS to use for offset recalculation");
2499 /* 3.2 Add to the offset the report TS for the current DTS */
2500 ts = mpegts_packetizer_pts_to_ts (MPEG_TS_BASE_PACKETIZER (demux),
2501 MPEGTIME_TO_GSTTIME (lastval), demux->program->pcr_pid);
2502 if (ts == GST_CLOCK_TIME_NONE) {
2503 GST_WARNING ("THIS SHOULD NOT HAPPEN !");
2506 ts += MPEGTIME_TO_GSTTIME (lastval - firstval);
2507 /* 3.3 If that offset is bigger than the current offset, store it */
2512 GST_DEBUG ("New initial pcr_offset %" GST_TIME_FORMAT,
2513 GST_TIME_ARGS (offset));
2515 /* 4. Set the offset on the packetizer */
2516 mpegts_packetizer_set_current_pcr_offset (MPEG_TS_BASE_PACKETIZER (demux),
2517 offset, demux->program->pcr_pid);
2519 /* 4. Go over all streams */
2520 for (tmp = demux->program->stream_list; tmp; tmp = tmp->next) {
2521 TSDemuxStream *stream = (TSDemuxStream *) tmp->data;
2523 stream->pending_ts = FALSE;
2524 /* 4.1 Set pending_ts for FALSE */
2526 /* 4.2 Recalculate PTS/DTS (in running time) for pending data */
2527 if (stream->pending) {
2529 for (tmp2 = stream->pending; tmp2; tmp2 = tmp2->next) {
2530 PendingBuffer *pend = (PendingBuffer *) tmp2->data;
2531 if (pend->pts != -1)
2532 GST_BUFFER_PTS (pend->buffer) =
2533 mpegts_packetizer_pts_to_ts (MPEG_TS_BASE_PACKETIZER (demux),
2534 MPEGTIME_TO_GSTTIME (pend->pts), demux->program->pcr_pid);
2535 if (pend->dts != -1)
2536 GST_BUFFER_DTS (pend->buffer) =
2537 mpegts_packetizer_pts_to_ts (MPEG_TS_BASE_PACKETIZER (demux),
2538 MPEGTIME_TO_GSTTIME (pend->dts), demux->program->pcr_pid);
2539 /* 4.2.2 Set first_pts to TS of lowest PTS (for segment) */
2540 if (stream->first_pts == GST_CLOCK_TIME_NONE) {
2541 if (GST_BUFFER_PTS (pend->buffer) != GST_CLOCK_TIME_NONE)
2542 stream->first_pts = GST_BUFFER_PTS (pend->buffer);
2543 else if (GST_BUFFER_DTS (pend->buffer) != GST_CLOCK_TIME_NONE)
2544 stream->first_pts = GST_BUFFER_DTS (pend->buffer);
2548 /* Recalculate PTS/DTS (in running time) for current data */
2549 if (stream->state != PENDING_PACKET_EMPTY) {
2550 if (stream->raw_pts != -1) {
2552 mpegts_packetizer_pts_to_ts (MPEG_TS_BASE_PACKETIZER (demux),
2553 MPEGTIME_TO_GSTTIME (stream->raw_pts), demux->program->pcr_pid);
2554 if (stream->first_pts == GST_CLOCK_TIME_NONE)
2555 stream->first_pts = stream->pts;
2557 if (stream->raw_dts != -1) {
2559 mpegts_packetizer_pts_to_ts (MPEG_TS_BASE_PACKETIZER (demux),
2560 MPEGTIME_TO_GSTTIME (stream->raw_dts), demux->program->pcr_pid);
2561 if (stream->first_pts == GST_CLOCK_TIME_NONE)
2562 stream->first_pts = stream->dts;
2571 gst_ts_demux_parse_pes_header (GstTSDemux * demux, TSDemuxStream * stream,
2572 guint8 * data, guint32 length, guint64 bufferoffset)
2575 PESParsingResult parseres;
2577 GST_MEMDUMP ("Header buffer", data, MIN (length, 32));
2579 parseres = mpegts_parse_pes_header (data, length, &header);
2580 if (G_UNLIKELY (parseres == PES_PARSING_NEED_MORE))
2582 if (G_UNLIKELY (parseres == PES_PARSING_BAD)) {
2583 GST_WARNING ("Error parsing PES header. pid: 0x%x stream_type: 0x%x",
2584 stream->stream.pid, stream->stream.stream_type);
2588 if (stream->target_pes_substream != 0
2589 && header.stream_id_extension != stream->target_pes_substream) {
2590 GST_DEBUG ("Skipping unwanted substream");
2594 gst_ts_demux_record_dts (demux, stream, header.DTS, bufferoffset);
2595 gst_ts_demux_record_pts (demux, stream, header.PTS, bufferoffset);
2596 if (G_UNLIKELY (stream->pending_ts &&
2597 (stream->pts != GST_CLOCK_TIME_NONE
2598 || stream->dts != GST_CLOCK_TIME_NONE))) {
2599 GST_DEBUG ("Got pts/dts update, rechecking all streams");
2600 check_pending_buffers (demux);
2601 } else if (stream->first_pts == GST_CLOCK_TIME_NONE) {
2602 if (GST_CLOCK_TIME_IS_VALID (stream->pts))
2603 stream->first_pts = stream->pts;
2604 else if (GST_CLOCK_TIME_IS_VALID (stream->dts))
2605 stream->first_pts = stream->dts;
2608 GST_DEBUG_OBJECT (demux,
2609 "stream PTS %" GST_TIME_FORMAT " DTS %" GST_TIME_FORMAT,
2610 GST_TIME_ARGS (stream->pts), GST_TIME_ARGS (stream->dts));
2612 /* Remove PES headers */
2613 GST_DEBUG ("Moving data forward by %d bytes (packet_size:%d, have:%d)",
2614 header.header_size, header.packet_length, length);
2615 stream->expected_size = header.packet_length;
2616 if (stream->expected_size) {
2617 if (G_LIKELY (stream->expected_size > header.header_size)) {
2618 stream->expected_size -= header.header_size;
2620 /* next packet will have to complete this one */
2621 GST_WARNING ("invalid header and packet size combination, empty packet");
2622 stream->expected_size = 0;
2625 data += header.header_size;
2626 length -= header.header_size;
2628 /* Create the output buffer */
2629 if (stream->expected_size)
2630 stream->allocated_size = MAX (stream->expected_size, length);
2632 stream->allocated_size = MAX (8192, length);
2634 g_assert (stream->data == NULL);
2635 stream->data = g_malloc (stream->allocated_size);
2636 memcpy (stream->data, data, length);
2637 stream->current_size = length;
2639 stream->state = PENDING_PACKET_BUFFER;
2644 stream->state = PENDING_PACKET_DISCONT;
2649 * * WITH packet->payload != NULL
2650 * * WITH pending/current flushed out if beginning of new PES packet
2653 gst_ts_demux_queue_data (GstTSDemux * demux, TSDemuxStream * stream,
2654 MpegTSPacketizerPacket * packet)
2658 guint8 cc = FLAGS_CONTINUITY_COUNTER (packet->scram_afc_cc);
2660 GST_LOG ("pid: 0x%04x state:%d", stream->stream.pid, stream->state);
2662 size = packet->data_end - packet->payload;
2663 data = packet->payload;
2665 if (stream->continuity_counter == CONTINUITY_UNSET) {
2666 GST_DEBUG ("CONTINUITY: Initialize to %d", cc);
2667 } else if ((cc == stream->continuity_counter + 1 ||
2668 (stream->continuity_counter == MAX_CONTINUITY && cc == 0))) {
2669 GST_LOG ("CONTINUITY: Got expected %d", cc);
2671 if (stream->state != PENDING_PACKET_EMPTY) {
2672 if (packet->payload_unit_start_indicator) {
2673 /* A mismatch is fatal, except if this is the beginning of a new
2674 * frame (from which we can recover) */
2675 if (G_UNLIKELY (stream->data)) {
2676 g_free (stream->data);
2677 stream->data = NULL;
2679 stream->state = PENDING_PACKET_HEADER;
2681 GST_WARNING ("CONTINUITY: Mismatch packet %d, stream %d",
2682 cc, stream->continuity_counter);
2683 stream->state = PENDING_PACKET_DISCONT;
2687 stream->continuity_counter = cc;
2689 if (stream->state == PENDING_PACKET_EMPTY) {
2690 if (G_UNLIKELY (!packet->payload_unit_start_indicator)) {
2691 stream->state = PENDING_PACKET_DISCONT;
2692 GST_DEBUG ("Didn't get the first packet of this PES");
2694 GST_LOG ("EMPTY=>HEADER");
2695 stream->state = PENDING_PACKET_HEADER;
2699 switch (stream->state) {
2700 case PENDING_PACKET_HEADER:
2702 GST_LOG ("HEADER: Parsing PES header");
2704 /* parse the header */
2705 gst_ts_demux_parse_pes_header (demux, stream, data, size, packet->offset);
2708 case PENDING_PACKET_BUFFER:
2710 GST_LOG ("BUFFER: appending data");
2711 if (G_UNLIKELY (stream->current_size + size > stream->allocated_size)) {
2712 GST_LOG ("resizing buffer");
2714 stream->allocated_size = MAX (8192, 2 * stream->allocated_size);
2715 } while (stream->current_size + size > stream->allocated_size);
2716 stream->data = g_realloc (stream->data, stream->allocated_size);
2718 memcpy (stream->data + stream->current_size, data, size);
2719 stream->current_size += size;
2722 case PENDING_PACKET_DISCONT:
2724 GST_LOG ("DISCONT: not storing/pushing");
2725 if (G_UNLIKELY (stream->data)) {
2726 g_free (stream->data);
2727 stream->data = NULL;
2729 stream->continuity_counter = CONTINUITY_UNSET;
2740 calculate_and_push_newsegment (GstTSDemux * demux, TSDemuxStream * stream,
2741 MpegTSBaseProgram * target_program)
2743 MpegTSBase *base = (MpegTSBase *) demux;
2744 GstClockTime lowest_pts = GST_CLOCK_TIME_NONE;
2745 GstClockTime firstts = 0;
2748 GST_DEBUG ("Creating new newsegment for stream %p", stream);
2750 if (target_program == NULL)
2751 target_program = demux->program;
2753 /* Speedup : if we don't need to calculate anything, go straight to pushing */
2754 if (demux->segment_event)
2755 goto push_new_segment;
2757 /* Calculate the 'new_start' value, used for newsegment */
2758 for (tmp = target_program->stream_list; tmp; tmp = tmp->next) {
2759 TSDemuxStream *pstream = (TSDemuxStream *) tmp->data;
2761 if (GST_CLOCK_TIME_IS_VALID (pstream->first_pts)) {
2762 if (!GST_CLOCK_TIME_IS_VALID (lowest_pts)
2763 || pstream->first_pts < lowest_pts)
2764 lowest_pts = pstream->first_pts;
2767 if (GST_CLOCK_TIME_IS_VALID (lowest_pts))
2768 firstts = lowest_pts;
2769 GST_DEBUG ("lowest_pts %" G_GUINT64_FORMAT " => clocktime %" GST_TIME_FORMAT,
2770 lowest_pts, GST_TIME_ARGS (firstts));
2772 if (demux->segment.format != GST_FORMAT_TIME || demux->reset_segment) {
2773 /* It will happen only if it's first program or after flushes. */
2774 GST_DEBUG ("Calculating actual segment");
2775 if (base->segment.format == GST_FORMAT_TIME) {
2776 /* Try to recover segment info from base if it's in TIME format */
2777 demux->segment = base->segment;
2779 /* Start from the first ts/pts */
2781 demux->segment.base + demux->segment.position - demux->segment.start;
2782 gst_segment_init (&demux->segment, GST_FORMAT_TIME);
2783 demux->segment.start = firstts;
2784 demux->segment.stop = GST_CLOCK_TIME_NONE;
2785 demux->segment.position = firstts;
2786 demux->segment.time = firstts;
2787 demux->segment.rate = demux->rate;
2788 demux->segment.base = base;
2790 } else if (demux->segment.start < firstts) {
2791 /* Take into account the offset to the first buffer timestamp */
2792 if (demux->segment.rate > 0) {
2793 demux->segment.start = firstts;
2795 if (GST_CLOCK_TIME_IS_VALID (demux->segment.stop))
2796 demux->segment.stop += firstts - demux->segment.start;
2797 demux->segment.position = firstts;
2801 if (!demux->segment_event) {
2802 demux->segment_event = gst_event_new_segment (&demux->segment);
2804 if (base->last_seek_seqnum != GST_SEQNUM_INVALID)
2805 gst_event_set_seqnum (demux->segment_event, base->last_seek_seqnum);
2809 for (tmp = target_program->stream_list; tmp; tmp = tmp->next) {
2810 stream = (TSDemuxStream *) tmp->data;
2811 if (stream->pad == NULL)
2814 if (demux->segment_event) {
2815 GST_DEBUG_OBJECT (stream->pad, "Pushing newsegment event");
2816 gst_event_ref (demux->segment_event);
2817 gst_pad_push_event (stream->pad, demux->segment_event);
2820 if (demux->global_tags) {
2821 gst_pad_push_event (stream->pad,
2822 gst_event_new_tag (gst_tag_list_ref (demux->global_tags)));
2825 /* Push pending tags */
2826 if (stream->taglist) {
2827 GST_DEBUG_OBJECT (stream->pad, "Sending tags %" GST_PTR_FORMAT,
2829 gst_pad_push_event (stream->pad, gst_event_new_tag (stream->taglist));
2830 stream->taglist = NULL;
2833 stream->need_newsegment = FALSE;
2838 gst_ts_demux_check_and_sync_streams (GstTSDemux * demux, GstClockTime time)
2842 GST_DEBUG_OBJECT (demux,
2843 "Recheck streams and sync to at least: %" GST_TIME_FORMAT,
2844 GST_TIME_ARGS (time));
2846 if (G_UNLIKELY (demux->program == NULL))
2849 /* Go over each stream and update it to at least 'time' time.
2850 * For each stream, the pad stores the buffer counter the last time
2851 * a gap check occurred (gap_ref_buffers) and a gap_ref_pts timestamp
2852 * that is either the PTS from the stream or the PCR the pad was updated
2855 * We can check nb_out_buffers to see if any buffers were pushed since then.
2856 * This means we can detect buffers passing without PTSes fine and still generate
2859 * If there haven't been any buffers pushed on this stream since the last
2860 * gap check, push a gap event updating to the indicated input PCR time
2861 * and update the pad's tracking.
2863 * If there have been buffers pushed, update the reference buffer count
2864 * and but don't push a gap event
2866 for (tmp = demux->program->stream_list; tmp; tmp = tmp->next) {
2867 TSDemuxStream *ps = (TSDemuxStream *) tmp->data;
2868 GST_DEBUG_OBJECT (ps->pad,
2869 "0x%04x, PTS:%" GST_TIME_FORMAT " REFPTS:%" GST_TIME_FORMAT " Gap:%"
2870 GST_TIME_FORMAT " nb_buffers: %d (ref:%d)",
2871 ((MpegTSBaseStream *) ps)->pid, GST_TIME_ARGS (ps->pts),
2872 GST_TIME_ARGS (ps->gap_ref_pts),
2873 GST_TIME_ARGS (ps->pts - ps->gap_ref_pts), ps->nb_out_buffers,
2874 ps->gap_ref_buffers);
2875 if (ps->pad == NULL)
2878 if (ps->nb_out_buffers == ps->gap_ref_buffers && ps->gap_ref_pts != ps->pts) {
2879 /* Do initial setup of pad if needed - segment etc */
2880 GST_DEBUG_OBJECT (ps->pad,
2881 "Stream needs update. Pushing GAP event to TS %" GST_TIME_FORMAT,
2882 GST_TIME_ARGS (time));
2883 if (G_UNLIKELY (ps->need_newsegment))
2884 calculate_and_push_newsegment (demux, ps, NULL);
2886 /* Now send gap event */
2887 gst_pad_push_event (ps->pad, gst_event_new_gap (time, 0));
2890 /* Update GAP tracking vars so we don't re-check this stream for a while */
2891 ps->gap_ref_pts = time;
2892 if (ps->pts != GST_CLOCK_TIME_NONE && ps->pts > time)
2893 ps->gap_ref_pts = ps->pts;
2894 ps->gap_ref_buffers = ps->nb_out_buffers;
2898 static GstBufferList *
2899 parse_opus_access_unit (TSDemuxStream * stream)
2901 GstByteReader reader;
2902 GstBufferList *buffer_list = NULL;
2904 buffer_list = gst_buffer_list_new ();
2905 gst_byte_reader_init (&reader, stream->data, stream->current_size);
2912 gboolean start_trim_flag, end_trim_flag, control_extension_flag;
2913 guint16 start_trim = 0, end_trim = 0;
2914 guint8 *packet_data;
2917 if (!gst_byte_reader_get_uint16_be (&reader, &id))
2920 /* No control header */
2921 if ((id >> 5) != 0x3ff)
2925 if (!gst_byte_reader_get_uint8 (&reader, &b))
2928 } while (b == 0xff);
2930 start_trim_flag = (id >> 4) & 0x1;
2931 end_trim_flag = (id >> 3) & 0x1;
2932 control_extension_flag = (id >> 2) & 0x1;
2934 if (start_trim_flag) {
2935 if (!gst_byte_reader_get_uint16_be (&reader, &start_trim))
2939 if (end_trim_flag) {
2940 if (!gst_byte_reader_get_uint16_be (&reader, &end_trim))
2944 if (control_extension_flag) {
2945 if (!gst_byte_reader_get_uint8 (&reader, &b))
2948 if (!gst_byte_reader_skip (&reader, b))
2952 packet_size = au_size;
2954 /* FIXME: this should be
2955 * packet_size = au_size - gst_byte_reader_get_pos (&reader);
2956 * but ffmpeg and the only available sample stream from obe.tv
2957 * are not including the control header size in au_size
2959 if (gst_byte_reader_get_remaining (&reader) < packet_size)
2961 if (!gst_byte_reader_dup_data (&reader, packet_size, &packet_data))
2964 buffer = gst_buffer_new_wrapped (packet_data, packet_size);
2966 if (start_trim != 0 || end_trim != 0) {
2967 gst_buffer_add_audio_clipping_meta (buffer, GST_FORMAT_DEFAULT,
2968 start_trim, end_trim);
2971 gst_buffer_list_add (buffer_list, buffer);
2972 } while (gst_byte_reader_get_remaining (&reader) > 0);
2974 g_free (stream->data);
2975 stream->data = NULL;
2976 stream->current_size = 0;
2982 GST_ERROR ("Failed to parse Opus access unit");
2983 g_free (stream->data);
2984 stream->data = NULL;
2985 stream->current_size = 0;
2987 gst_buffer_list_unref (buffer_list);
2992 /* interlaced mode is disabled at the moment */
2993 /*#define TSDEMUX_JP2K_SUPPORT_INTERLACE */
2995 parse_jp2k_access_unit (TSDemuxStream * stream)
2997 GstByteReader reader;
3001 guint16 den G_GNUC_UNUSED;
3002 guint16 num G_GNUC_UNUSED;
3003 /* Maximum bitrate box */
3004 guint32 MaxBr G_GNUC_UNUSED;
3005 guint32 AUF[2] = { 0, 0 };
3006 #ifdef TSDEMUX_JP2K_SUPPORT_INTERLACE
3007 /* Field Coding Box */
3008 guint8 Fic G_GNUC_UNUSED = 1;
3009 guint8 Fio G_GNUC_UNUSED = 0;
3010 /* header size equals 38 for non-interlaced, and 48 for interlaced */
3011 guint header_size = stream->jp2kInfos.interlace ? 48 : 38;
3013 /* header size equals 38 for non-interlaced, and 48 for interlaced */
3014 guint header_size = 38;
3017 guint32 HHMMSSFF G_GNUC_UNUSED;
3018 /* Broadcast color box */
3019 guint8 CollC G_GNUC_UNUSED;
3020 guint8 b G_GNUC_UNUSED;
3022 guint data_location;
3023 GstBuffer *retbuf = NULL;
3025 if (stream->current_size < header_size) {
3026 GST_ERROR_OBJECT (stream->pad, "Not enough data for header");
3030 gst_byte_reader_init (&reader, stream->data, stream->current_size);
3032 /* Check for the location of the jp2k magic */
3034 gst_byte_reader_masked_scan_uint32 (&reader, 0xffffffff, 0xff4fff51, 0,
3035 stream->current_size);
3036 GST_DEBUG_OBJECT (stream->pad, "data location %d", data_location);
3037 if (data_location == -1) {
3038 GST_ERROR_OBJECT (stream->pad, "Stream does not contain jp2k magic header");
3042 /* Elementary stream header box 'elsm' == 0x656c736d */
3043 header_tag = gst_byte_reader_get_uint32_be_unchecked (&reader);
3044 if (header_tag != 0x656c736d) {
3045 GST_ERROR_OBJECT (stream->pad, "Expected ELSM box but found box %x instead",
3049 /* Frame rate box 'frat' == 0x66726174 */
3050 header_tag = gst_byte_reader_get_uint32_be_unchecked (&reader);
3051 if (header_tag != 0x66726174) {
3052 GST_ERROR_OBJECT (stream->pad,
3053 "Expected frame rate box, but found box %x instead", header_tag);
3057 den = gst_byte_reader_get_uint16_be_unchecked (&reader);
3058 num = gst_byte_reader_get_uint16_be_unchecked (&reader);
3059 /* Maximum bit rate box 'brat' == 0x62726174 */
3060 header_tag = gst_byte_reader_get_uint32_be_unchecked (&reader);
3061 if (header_tag != 0x62726174) {
3062 GST_ERROR_OBJECT (stream->pad, "Expected brat box but read box %x instead",
3067 MaxBr = gst_byte_reader_get_uint32_be_unchecked (&reader);
3068 AUF[0] = gst_byte_reader_get_uint32_be_unchecked (&reader);
3069 if (stream->jp2kInfos.interlace) {
3070 #ifdef TSDEMUX_JP2K_SUPPORT_INTERLACE
3071 AUF[1] = gst_byte_reader_get_uint32_be_unchecked (&reader);
3072 /* Field Coding Box 'fiel' == 0x6669656c */
3073 header_tag = gst_byte_reader_get_uint32_be_unchecked (&reader);
3074 if (header_tag != 0x6669656c) {
3075 GST_ERROR_OBJECT (stream->pad,
3076 "Expected Field Coding box but found box %x instead", header_tag);
3079 Fic = gst_byte_reader_get_uint8_unchecked (&reader);
3080 Fio = gst_byte_reader_get_uint8_unchecked (&reader);
3082 GST_ERROR_OBJECT (stream->pad, "interlaced mode not supported");
3087 /* Time Code Box 'tcod' == 0x74636f64 */
3088 /* Some progressive streams might have a AUF[1] of value 0 present */
3089 header_tag = gst_byte_reader_get_uint32_be_unchecked (&reader);
3090 if (header_tag == 0 && !stream->jp2kInfos.interlace) {
3091 AUF[1] = header_tag;
3092 header_tag = gst_byte_reader_get_uint32_be_unchecked (&reader);
3093 /* Bump up header size and recheck */
3095 if (stream->current_size < header_size) {
3096 GST_ERROR_OBJECT (stream->pad, "Not enough data for header");
3100 if (header_tag != 0x74636f64) {
3101 GST_ERROR_OBJECT (stream->pad,
3102 "Expected Time code box but found %d box instead", header_tag);
3105 HHMMSSFF = gst_byte_reader_get_uint32_be_unchecked (&reader);
3106 /* Broadcast Color Box 'bcol' == 0x6263686c */
3107 header_tag = gst_byte_reader_get_uint32_be_unchecked (&reader);
3108 if (header_tag != 0x62636f6c) {
3109 GST_ERROR_OBJECT (stream->pad,
3110 "Expected Broadcast color box but found %x box instead", header_tag);
3113 CollC = gst_byte_reader_get_uint8_unchecked (&reader);
3114 b = gst_byte_reader_get_uint8_unchecked (&reader);
3116 /* Check if we have enough data to create a valid buffer */
3117 if ((stream->current_size - data_location) < (AUF[0] + AUF[1])) {
3118 GST_ERROR ("Required size (%d) greater than remaining size in buffer (%d)",
3119 AUF[0] + AUF[1], (stream->current_size - data_location));
3123 retbuf = gst_buffer_new_wrapped_full (0, stream->data, stream->current_size,
3124 data_location, stream->current_size - data_location,
3125 stream->data, g_free);
3126 stream->data = NULL;
3127 stream->current_size = 0;
3131 GST_ERROR ("Failed to parse JP2K access unit");
3132 g_free (stream->data);
3133 stream->data = NULL;
3134 stream->current_size = 0;
3138 static GstFlowReturn
3139 gst_ts_demux_push_pending_data (GstTSDemux * demux, TSDemuxStream * stream,
3140 MpegTSBaseProgram * target_program)
3142 GstFlowReturn res = GST_FLOW_OK;
3143 MpegTSBaseStream *bs = (MpegTSBaseStream *) stream;
3144 GstBuffer *buffer = NULL;
3145 GstBufferList *buffer_list = NULL;
3148 GST_DEBUG_OBJECT (stream->pad,
3149 "stream:%p, pid:0x%04x stream_type:%d state:%d", stream, bs->pid,
3150 bs->stream_type, stream->state);
3152 if (G_UNLIKELY (stream->data == NULL)) {
3153 GST_LOG ("stream->data == NULL");
3157 if (G_UNLIKELY (stream->state == PENDING_PACKET_EMPTY)) {
3158 GST_LOG ("EMPTY: returning");
3162 if (G_UNLIKELY (stream->state != PENDING_PACKET_BUFFER)) {
3163 GST_LOG ("state:%d, returning", stream->state);
3167 if (G_UNLIKELY (demux->program == NULL)) {
3168 GST_LOG_OBJECT (demux, "No program");
3169 g_free (stream->data);
3173 if (stream->needs_keyframe) {
3174 MpegTSBase *base = (MpegTSBase *) demux;
3176 if ((gst_ts_demux_adjust_seek_offset_for_keyframe (stream, stream->data,
3177 stream->current_size)) || demux->last_seek_offset == 0) {
3178 GST_DEBUG_OBJECT (stream->pad,
3179 "Got Keyframe, ready to go at %" GST_TIME_FORMAT,
3180 GST_TIME_ARGS (stream->pts));
3182 if (bs->stream_type == GST_MPEGTS_STREAM_TYPE_PRIVATE_PES_PACKETS &&
3183 bs->registration_id == DRF_ID_OPUS) {
3184 buffer_list = parse_opus_access_unit (stream);
3186 res = GST_FLOW_ERROR;
3190 if (gst_buffer_list_length (buffer_list) == 1) {
3191 buffer = gst_buffer_ref (gst_buffer_list_get (buffer_list, 0));
3192 gst_buffer_list_unref (buffer_list);
3195 } else if (bs->stream_type == GST_MPEGTS_STREAM_TYPE_VIDEO_JP2K) {
3196 buffer = parse_jp2k_access_unit (stream);
3198 res = GST_FLOW_ERROR;
3202 buffer = gst_buffer_new_wrapped (stream->data, stream->current_size);
3205 stream->seeked_pts = stream->pts;
3206 stream->seeked_dts = stream->dts;
3207 stream->needs_keyframe = FALSE;
3209 base->seek_offset = demux->last_seek_offset - 200 * base->packetsize;
3210 if (demux->last_seek_offset < 200 * base->packetsize)
3211 base->seek_offset = 0;
3212 demux->last_seek_offset = base->seek_offset;
3213 mpegts_packetizer_flush (base->packetizer, FALSE);
3214 base->mode = BASE_MODE_SEEKING;
3216 stream->continuity_counter = CONTINUITY_UNSET;
3217 res = GST_FLOW_REWINDING;
3218 g_free (stream->data);
3222 if (bs->stream_type == GST_MPEGTS_STREAM_TYPE_PRIVATE_PES_PACKETS &&
3223 bs->registration_id == DRF_ID_OPUS) {
3224 buffer_list = parse_opus_access_unit (stream);
3226 res = GST_FLOW_ERROR;
3230 if (gst_buffer_list_length (buffer_list) == 1) {
3231 buffer = gst_buffer_ref (gst_buffer_list_get (buffer_list, 0));
3232 gst_buffer_list_unref (buffer_list);
3235 } else if (bs->stream_type == GST_MPEGTS_STREAM_TYPE_VIDEO_JP2K) {
3236 buffer = parse_jp2k_access_unit (stream);
3238 res = GST_FLOW_ERROR;
3242 buffer = gst_buffer_new_wrapped (stream->data, stream->current_size);
3245 if (G_UNLIKELY (stream->pending_ts && !check_pending_buffers (demux))) {
3247 PendingBuffer *pend;
3248 pend = g_slice_new0 (PendingBuffer);
3249 pend->buffer = buffer;
3250 pend->pts = stream->raw_pts;
3251 pend->dts = stream->raw_dts;
3252 stream->pending = g_list_append (stream->pending, pend);
3256 n = gst_buffer_list_length (buffer_list);
3257 for (i = 0; i < n; i++) {
3258 PendingBuffer *pend;
3259 pend = g_slice_new0 (PendingBuffer);
3260 pend->buffer = gst_buffer_ref (gst_buffer_list_get (buffer_list, i));
3261 pend->pts = i == 0 ? stream->raw_pts : -1;
3262 pend->dts = i == 0 ? stream->raw_dts : -1;
3263 stream->pending = g_list_append (stream->pending, pend);
3265 gst_buffer_list_unref (buffer_list);
3267 GST_DEBUG ("Not enough information to push buffers yet, storing buffer");
3272 if (G_UNLIKELY (stream->need_newsegment))
3273 calculate_and_push_newsegment (demux, stream, target_program);
3275 /* FIXME : Push pending buffers if any */
3276 if (G_UNLIKELY (stream->pending)) {
3278 for (tmp = stream->pending; tmp; tmp = tmp->next) {
3279 PendingBuffer *pend = (PendingBuffer *) tmp->data;
3281 GST_DEBUG_OBJECT (stream->pad,
3282 "Pushing pending buffer PTS:%" GST_TIME_FORMAT " DTS:%"
3283 GST_TIME_FORMAT, GST_TIME_ARGS (GST_BUFFER_PTS (pend->buffer)),
3284 GST_TIME_ARGS (GST_BUFFER_DTS (pend->buffer)));
3286 if (stream->discont)
3287 GST_BUFFER_FLAG_SET (pend->buffer, GST_BUFFER_FLAG_DISCONT);
3288 stream->discont = FALSE;
3290 res = gst_pad_push (stream->pad, pend->buffer);
3291 stream->nb_out_buffers += 1;
3292 g_slice_free (PendingBuffer, pend);
3294 g_list_free (stream->pending);
3295 stream->pending = NULL;
3298 if ((GST_CLOCK_TIME_IS_VALID (stream->seeked_pts)
3299 && stream->pts < stream->seeked_pts) ||
3300 (GST_CLOCK_TIME_IS_VALID (stream->seeked_dts) &&
3301 stream->pts < stream->seeked_dts)) {
3302 GST_INFO_OBJECT (stream->pad,
3303 "Droping with PTS: %" GST_TIME_FORMAT " DTS: %" GST_TIME_FORMAT
3304 " after seeking as other stream needed to be seeked further"
3305 "(seeked PTS: %" GST_TIME_FORMAT " DTS: %" GST_TIME_FORMAT ")",
3306 GST_TIME_ARGS (stream->pts), GST_TIME_ARGS (stream->dts),
3307 GST_TIME_ARGS (stream->seeked_pts), GST_TIME_ARGS (stream->seeked_dts));
3309 gst_buffer_unref (buffer);
3311 gst_buffer_list_unref (buffer_list);
3315 GST_DEBUG_OBJECT (stream->pad, "stream->pts %" GST_TIME_FORMAT,
3316 GST_TIME_ARGS (stream->pts));
3318 /* Decorate buffer or first buffer of the buffer list */
3320 buffer = gst_buffer_list_get (buffer_list, 0);
3322 if (GST_CLOCK_TIME_IS_VALID (stream->pts))
3323 GST_BUFFER_PTS (buffer) = GST_BUFFER_DTS (buffer) = stream->pts;
3324 /* DTS = PTS by default, we override it if there's a real DTS */
3325 if (GST_CLOCK_TIME_IS_VALID (stream->dts))
3326 GST_BUFFER_DTS (buffer) = stream->dts;
3328 if (stream->discont)
3329 GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DISCONT);
3330 stream->discont = FALSE;
3335 GST_DEBUG_OBJECT (stream->pad,
3336 "Pushing buffer%s with PTS: %" GST_TIME_FORMAT " , DTS: %"
3337 GST_TIME_FORMAT, (buffer_list ? "list" : ""), GST_TIME_ARGS (stream->pts),
3338 GST_TIME_ARGS (stream->dts));
3340 if (GST_CLOCK_TIME_IS_VALID (stream->dts))
3341 demux->segment.position = stream->dts;
3342 else if (GST_CLOCK_TIME_IS_VALID (stream->pts))
3343 demux->segment.position = stream->pts;
3346 res = gst_pad_push (stream->pad, buffer);
3347 /* Record that a buffer was pushed */
3348 stream->nb_out_buffers += 1;
3350 guint n = gst_buffer_list_length (buffer_list);
3351 res = gst_pad_push_list (stream->pad, buffer_list);
3352 /* Record that a buffer was pushed */
3353 stream->nb_out_buffers += n;
3355 GST_DEBUG_OBJECT (stream->pad, "Returned %s", gst_flow_get_name (res));
3356 res = gst_flow_combiner_update_flow (demux->flowcombiner, res);
3357 GST_DEBUG_OBJECT (stream->pad, "combined %s", gst_flow_get_name (res));
3359 /* GAP / sparse stream tracking */
3360 if (G_UNLIKELY (stream->gap_ref_pts == GST_CLOCK_TIME_NONE))
3361 stream->gap_ref_pts = stream->pts;
3363 /* Look if the stream PTS has advanced 2 seconds since the last
3364 * gap check, and sync streams if it has. The first stream to
3365 * hit this will trigger a gap check */
3366 if (G_UNLIKELY (stream->pts != GST_CLOCK_TIME_NONE &&
3367 stream->pts > stream->gap_ref_pts + 2 * GST_SECOND)) {
3368 if (demux->program->pcr_pid != 0x1fff) {
3369 GstClockTime curpcr =
3370 mpegts_packetizer_get_current_time (MPEG_TS_BASE_PACKETIZER (demux),
3371 demux->program->pcr_pid);
3372 if (curpcr == GST_CLOCK_TIME_NONE || curpcr < 800 * GST_MSECOND)
3374 curpcr -= 800 * GST_MSECOND;
3375 /* Use the current PCR (with a safety margin) to sync against */
3376 gst_ts_demux_check_and_sync_streams (demux, curpcr);
3378 /* If we don't have a PCR track, just use the current stream PTS */
3379 gst_ts_demux_check_and_sync_streams (demux, stream->pts);
3385 /* Reset the PES payload collection, but don't clear the state,
3386 * we might want to keep collecting this PES */
3387 GST_LOG ("Cleared PES data. returning %s", gst_flow_get_name (res));
3388 if (stream->expected_size) {
3389 if (stream->current_size > stream->expected_size)
3390 stream->expected_size = 0;
3392 stream->expected_size -= stream->current_size;
3394 stream->data = NULL;
3395 stream->allocated_size = 0;
3396 stream->current_size = 0;
3401 static GstFlowReturn
3402 gst_ts_demux_handle_packet (GstTSDemux * demux, TSDemuxStream * stream,
3403 MpegTSPacketizerPacket * packet, GstMpegtsSection * section)
3405 GstFlowReturn res = GST_FLOW_OK;
3407 GST_LOG ("pid 0x%04x pusi:%d, afc:%d, cont:%d, payload:%p", packet->pid,
3408 packet->payload_unit_start_indicator, packet->scram_afc_cc & 0x30,
3409 FLAGS_CONTINUITY_COUNTER (packet->scram_afc_cc), packet->payload);
3411 if (G_UNLIKELY (packet->payload_unit_start_indicator) &&
3412 FLAGS_HAS_PAYLOAD (packet->scram_afc_cc)) {
3413 /* Flush previous data */
3414 res = gst_ts_demux_push_pending_data (demux, stream, NULL);
3415 /* Tell the data collecting to expect this header */
3416 stream->state = PENDING_PACKET_HEADER;
3419 if (packet->payload && (res == GST_FLOW_OK || res == GST_FLOW_NOT_LINKED)
3421 gst_ts_demux_queue_data (demux, stream, packet);
3422 GST_LOG ("current_size:%d, expected_size:%d",
3423 stream->current_size, stream->expected_size);
3424 /* Finally check if the data we queued completes a packet, or got too
3425 * large and needs output now */
3426 if ((stream->expected_size && stream->current_size >= stream->expected_size)
3427 || (stream->current_size >= MAX_PES_PAYLOAD)) {
3428 GST_LOG ("pushing packet of size %u", stream->current_size);
3429 res = gst_ts_demux_push_pending_data (demux, stream, NULL);
3433 /* We are rewinding to find a keyframe,
3434 * and didn't want the data to be queued
3436 if (res == GST_FLOW_REWINDING)
3443 gst_ts_demux_flush (MpegTSBase * base, gboolean hard)
3445 GstTSDemux *demux = GST_TS_DEMUX_CAST (base);
3447 gst_ts_demux_flush_streams (demux, hard);
3449 if (demux->segment_event) {
3450 gst_event_unref (demux->segment_event);
3451 demux->segment_event = NULL;
3453 if (demux->global_tags) {
3454 gst_tag_list_unref (demux->global_tags);
3455 demux->global_tags = NULL;
3458 /* For pull mode seeks the current segment needs to be preserved */
3460 gst_segment_init (&demux->segment, GST_FORMAT_UNDEFINED);
3464 static GstFlowReturn
3465 gst_ts_demux_drain (MpegTSBase * base)
3467 GstTSDemux *demux = GST_TS_DEMUX_CAST (base);
3469 GstFlowReturn res = GST_FLOW_OK;
3471 if (!demux->program)
3474 for (tmp = demux->program->stream_list; tmp; tmp = tmp->next) {
3475 TSDemuxStream *stream = (TSDemuxStream *) tmp->data;
3477 res = gst_ts_demux_push_pending_data (demux, stream, NULL);
3478 if (G_UNLIKELY (res != GST_FLOW_OK))
3486 static GstFlowReturn
3487 gst_ts_demux_push (MpegTSBase * base, MpegTSPacketizerPacket * packet,
3488 GstMpegtsSection * section)
3490 GstTSDemux *demux = GST_TS_DEMUX_CAST (base);
3491 TSDemuxStream *stream = NULL;
3492 GstFlowReturn res = GST_FLOW_OK;
3494 if (G_LIKELY (demux->program)) {
3495 stream = (TSDemuxStream *) demux->program->streams[packet->pid];
3498 res = gst_ts_demux_handle_packet (demux, stream, packet, section);
3505 gst_ts_demux_plugin_init (GstPlugin * plugin)
3507 GST_DEBUG_CATEGORY_INIT (ts_demux_debug, "tsdemux", 0,
3508 "MPEG transport stream demuxer");
3511 return gst_element_register (plugin, "tsdemux",
3512 GST_RANK_PRIMARY, GST_TYPE_TS_DEMUX);