From e66d543f004a2d06a77f67fd4473918117f7a77b Mon Sep 17 00:00:00 2001 From: Edward Hervey Date: Mon, 17 Jun 2013 08:15:54 +0200 Subject: [PATCH] tsparse: Ensure initial events are sent in the right order First send stream-start, then caps, then segment. The segment we push is from upstream in push-mode. If we work in pull-mode then we initialize the base segment to BYTES. https://bugzilla.gnome.org/show_bug.cgi?id=702422 --- gst/mpegtsdemux/mpegtsbase.c | 3 +++ gst/mpegtsdemux/mpegtsparse.c | 40 +++++++++++++++++++++++++++++++++++ gst/mpegtsdemux/mpegtsparse.h | 3 +++ 3 files changed, 46 insertions(+) diff --git a/gst/mpegtsdemux/mpegtsbase.c b/gst/mpegtsdemux/mpegtsbase.c index 8914e4fef2..6f0804359b 100644 --- a/gst/mpegtsdemux/mpegtsbase.c +++ b/gst/mpegtsdemux/mpegtsbase.c @@ -1314,6 +1314,8 @@ mpegts_base_sink_event (GstPad * pad, GstObject * parent, GstEvent * event) switch (GST_EVENT_TYPE (event)) { case GST_EVENT_SEGMENT: gst_event_copy_segment (event, &base->segment); + GST_DEBUG_OBJECT (base, "Received segment %" GST_SEGMENT_FORMAT, + &base->segment); /* Check if we need to switch PCR/PTS handling */ if (base->segment.format == GST_FORMAT_TIME) { base->packetizer->calculate_offset = FALSE; @@ -1773,6 +1775,7 @@ mpegts_base_sink_activate_mode (GstPad * pad, GstObject * parent, /* When working pull-based, we always use offsets for estimation */ base->packetizer->calculate_offset = TRUE; base->packetizer->calculate_skew = FALSE; + gst_segment_init (&base->segment, GST_FORMAT_BYTES); res = gst_pad_start_task (pad, (GstTaskFunction) mpegts_base_loop, base, NULL); diff --git a/gst/mpegtsdemux/mpegtsparse.c b/gst/mpegtsdemux/mpegtsparse.c index d1bd7bf2eb..5b2b6c70f1 100644 --- a/gst/mpegtsdemux/mpegtsparse.c +++ b/gst/mpegtsdemux/mpegtsparse.c @@ -149,6 +149,7 @@ mpegts_parse_init (MpegTSParse2 * parse) GST_MPEGTS_BASE (parse)->program_size = sizeof (MpegTSParseProgram); parse->srcpad = gst_pad_new_from_static_template (&src_template, "src"); + parse->first = TRUE; gst_element_add_pad (GST_ELEMENT (parse), parse->srcpad); } @@ -178,6 +179,33 @@ mpegts_parse_reset (MpegTSBase * base) /* SIT */ MPEGTS_BIT_SET (base->known_psi, 0x1f); + GST_MPEGTS_PARSE (base)->first = TRUE; +} + +static void +prepare_src_pad (MpegTSBase * base, MpegTSParse2 * parse) +{ + if (base->packetizer->know_packet_size) { + gchar *stream_id; + GstCaps *caps; + + stream_id = + gst_pad_create_stream_id (parse->srcpad, GST_ELEMENT_CAST (base), + "multi-program"); + gst_pad_push_event (parse->srcpad, gst_event_new_stream_start (stream_id)); + g_free (stream_id); + + caps = gst_caps_new_simple ("video/mpegts", + "systemstream", G_TYPE_BOOLEAN, TRUE, + "packetsize", G_TYPE_INT, base->packetizer->packet_size, NULL); + + gst_pad_set_caps (parse->srcpad, caps); + gst_caps_unref (caps); + + gst_pad_push_event (parse->srcpad, gst_event_new_segment (&base->segment)); + + parse->first = FALSE; + } } static gboolean @@ -186,6 +214,15 @@ push_event (MpegTSBase * base, GstEvent * event) MpegTSParse2 *parse = (MpegTSParse2 *) base; GList *tmp; + if (G_UNLIKELY (parse->first)) { + /* We will send the segment when really starting */ + if (G_UNLIKELY (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT)) { + gst_event_unref (event); + return TRUE; + } + prepare_src_pad (base, parse); + } + for (tmp = parse->srcpads; tmp; tmp = tmp->next) { GstPad *pad = (GstPad *) tmp->data; if (pad) { @@ -471,6 +508,9 @@ mpegts_parse_input_done (MpegTSBase * base, GstBuffer * buffer) { MpegTSParse2 *parse = GST_MPEGTS_PARSE (base); + if (G_UNLIKELY (parse->first)) + prepare_src_pad (base, parse); + return gst_pad_push (parse->srcpad, buffer); } diff --git a/gst/mpegtsdemux/mpegtsparse.h b/gst/mpegtsdemux/mpegtsparse.h index d04c66dbad..50b8eb529b 100644 --- a/gst/mpegtsdemux/mpegtsparse.h +++ b/gst/mpegtsdemux/mpegtsparse.h @@ -52,6 +52,9 @@ struct _MpegTSParse2 { GstPad *srcpad; GList *srcpads; + + /* state */ + gboolean first; }; struct _MpegTSParse2Class {