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
This commit is contained in:
Edward Hervey 2013-06-17 08:15:54 +02:00
parent 8b00e02f16
commit e66d543f00
3 changed files with 46 additions and 0 deletions

View file

@ -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);

View file

@ -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);
}

View file

@ -52,6 +52,9 @@ struct _MpegTSParse2 {
GstPad *srcpad;
GList *srcpads;
/* state */
gboolean first;
};
struct _MpegTSParse2Class {