baseparse: Ensure seqnum consistency

We need all relevant events of a segment to have consistent seqnum:
* GST_EVENT_SEGMENT
* GST_EVENT_EOS

If we are push-based and create a new segment, use the same seqnum
as the upstream event.

If we are pull-based, use the seqnum of that newly created segment
event everywhere
This commit is contained in:
Edward Hervey 2018-06-05 17:02:18 +02:00 committed by Edward Hervey
parent 52d4ae7680
commit d34f046029

View file

@ -343,6 +343,9 @@ struct _GstBaseParsePrivate
GstTagList *parser_tags; GstTagList *parser_tags;
GstTagMergeMode parser_tags_merge_mode; GstTagMergeMode parser_tags_merge_mode;
gboolean tags_changed; gboolean tags_changed;
/* Current segment seqnum */
guint32 segment_seqnum;
}; };
typedef struct _GstBaseParseSeek typedef struct _GstBaseParseSeek
@ -881,6 +884,8 @@ gst_base_parse_reset (GstBaseParse * parse)
g_list_free (parse->priv->detect_buffers); g_list_free (parse->priv->detect_buffers);
parse->priv->detect_buffers = NULL; parse->priv->detect_buffers = NULL;
parse->priv->detect_buffers_size = 0; parse->priv->detect_buffers_size = 0;
parse->priv->segment_seqnum = GST_SEQNUM_INVALID;
GST_OBJECT_UNLOCK (parse); GST_OBJECT_UNLOCK (parse);
} }
@ -1186,14 +1191,16 @@ gst_base_parse_sink_event_default (GstBaseParse * parse, GstEvent * event)
const GstSegment *in_segment; const GstSegment *in_segment;
GstSegment out_segment; GstSegment out_segment;
gint64 offset = 0, next_dts; gint64 offset = 0, next_dts;
guint32 seqnum = gst_event_get_seqnum (event);
parse->priv->segment_seqnum = gst_event_get_seqnum (event);
gst_event_parse_segment (event, &in_segment); gst_event_parse_segment (event, &in_segment);
gst_segment_init (&out_segment, GST_FORMAT_TIME); gst_segment_init (&out_segment, GST_FORMAT_TIME);
out_segment.rate = in_segment->rate; out_segment.rate = in_segment->rate;
out_segment.applied_rate = in_segment->applied_rate; out_segment.applied_rate = in_segment->applied_rate;
GST_DEBUG_OBJECT (parse, "segment %" GST_SEGMENT_FORMAT, in_segment); GST_DEBUG_OBJECT (parse, "New segment %" GST_SEGMENT_FORMAT, in_segment);
GST_DEBUG_OBJECT (parse, "Current segment %" GST_SEGMENT_FORMAT,
&parse->segment);
parse->priv->upstream_format = in_segment->format; parse->priv->upstream_format = in_segment->format;
if (in_segment->format == GST_FORMAT_BYTES) { if (in_segment->format == GST_FORMAT_BYTES) {
@ -1245,7 +1252,7 @@ gst_base_parse_sink_event_default (GstBaseParse * parse, GstEvent * event)
gst_event_unref (event); gst_event_unref (event);
event = gst_event_new_segment (&out_segment); event = gst_event_new_segment (&out_segment);
gst_event_set_seqnum (event, seqnum); gst_event_set_seqnum (event, parse->priv->segment_seqnum);
GST_DEBUG_OBJECT (parse, "Converted incoming segment to TIME. %" GST_DEBUG_OBJECT (parse, "Converted incoming segment to TIME. %"
GST_SEGMENT_FORMAT, in_segment); GST_SEGMENT_FORMAT, in_segment);
@ -1260,7 +1267,7 @@ gst_base_parse_sink_event_default (GstBaseParse * parse, GstEvent * event)
out_segment.time = 0; out_segment.time = 0;
event = gst_event_new_segment (&out_segment); event = gst_event_new_segment (&out_segment);
gst_event_set_seqnum (event, seqnum); gst_event_set_seqnum (event, parse->priv->segment_seqnum);
next_dts = 0; next_dts = 0;
} else { } else {
@ -1271,6 +1278,8 @@ gst_base_parse_sink_event_default (GstBaseParse * parse, GstEvent * event)
gst_event_copy_segment (event, &out_segment); gst_event_copy_segment (event, &out_segment);
} }
GST_DEBUG_OBJECT (parse, "OUT segment %" GST_SEGMENT_FORMAT,
&out_segment);
memcpy (&parse->segment, &out_segment, sizeof (GstSegment)); memcpy (&parse->segment, &out_segment, sizeof (GstSegment));
/* /*
@ -2467,6 +2476,7 @@ gst_base_parse_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
&& last_start > parse->segment.start && last_start > parse->segment.start
&& (!GST_CLOCK_TIME_IS_VALID (parse->segment.stop) && (!GST_CLOCK_TIME_IS_VALID (parse->segment.stop)
|| last_start < parse->segment.stop))) { || last_start < parse->segment.stop))) {
GstEvent *topush;
GST_DEBUG_OBJECT (parse, GST_DEBUG_OBJECT (parse,
"Gap of %" G_GINT64_FORMAT " ns detected in stream " "(%" "Gap of %" G_GINT64_FORMAT " ns detected in stream " "(%"
@ -2476,8 +2486,10 @@ gst_base_parse_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
GST_TIME_ARGS (last_start)); GST_TIME_ARGS (last_start));
/* skip gap FIXME */ /* skip gap FIXME */
gst_pad_push_event (parse->srcpad, topush = gst_event_new_segment (&parse->segment);
gst_event_new_segment (&parse->segment)); if (parse->priv->segment_seqnum != GST_SEQNUM_INVALID)
gst_event_set_seqnum (topush, parse->priv->segment_seqnum);
gst_pad_push_event (parse->srcpad, topush);
parse->segment.position = last_start; parse->segment.position = last_start;
} }
@ -3634,13 +3646,19 @@ pause:
push_eos = TRUE; push_eos = TRUE;
} }
if (push_eos) { if (push_eos) {
GstEvent *topush;
if (parse->priv->estimated_duration <= 0) { if (parse->priv->estimated_duration <= 0) {
gst_base_parse_update_duration (parse); gst_base_parse_update_duration (parse);
} }
/* Push pending events, including SEGMENT events */ /* Push pending events, including SEGMENT events */
gst_base_parse_push_pending_events (parse); gst_base_parse_push_pending_events (parse);
gst_pad_push_event (parse->srcpad, gst_event_new_eos ()); topush = gst_event_new_eos ();
GST_DEBUG_OBJECT (parse, "segment_seqnum:%" G_GUINT32_FORMAT,
parse->priv->segment_seqnum);
if (parse->priv->segment_seqnum != GST_SEQNUM_INVALID)
gst_event_set_seqnum (topush, parse->priv->segment_seqnum);
gst_pad_push_event (parse->srcpad, topush);
} }
gst_object_unref (parse); gst_object_unref (parse);
} }
@ -3743,9 +3761,10 @@ gst_base_parse_sink_activate_mode (GstPad * pad, GstObject * parent,
switch (mode) { switch (mode) {
case GST_PAD_MODE_PULL: case GST_PAD_MODE_PULL:
if (active) { if (active) {
GstEvent *ev = gst_event_new_segment (&parse->segment);
parse->priv->segment_seqnum = gst_event_get_seqnum (ev);
parse->priv->pending_events = parse->priv->pending_events =
g_list_prepend (parse->priv->pending_events, g_list_prepend (parse->priv->pending_events, ev);
gst_event_new_segment (&parse->segment));
result = TRUE; result = TRUE;
} else { } else {
result = gst_pad_stop_task (pad); result = gst_pad_stop_task (pad);