identity: Handle seeking with single_segment=True

Identity was ignoring seek and flush events even when using
a single segment. In the end it means that we couldn't compute
buffers running-time and stream time after seeks.

This commits adds support for flushing seeks only as I have no idea
what to do for non flushing ones.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/450>
This commit is contained in:
Thibault Saunier 2020-04-28 22:21:13 -04:00 committed by GStreamer Merge Bot
parent b517b59171
commit cb212c9fd7
2 changed files with 62 additions and 6 deletions

View file

@ -113,6 +113,8 @@ static void gst_identity_get_property (GObject * object, guint prop_id,
static gboolean gst_identity_sink_event (GstBaseTransform * trans,
GstEvent * event);
static gboolean gst_identity_src_event (GstBaseTransform * trans,
GstEvent * event);
static GstFlowReturn gst_identity_transform_ip (GstBaseTransform * trans,
GstBuffer * buf);
static gboolean gst_identity_start (GstBaseTransform * trans);
@ -277,6 +279,7 @@ gst_identity_class_init (GstIdentityClass * klass)
GST_DEBUG_FUNCPTR (gst_identity_change_state);
gstbasetrans_class->sink_event = GST_DEBUG_FUNCPTR (gst_identity_sink_event);
gstbasetrans_class->src_event = GST_DEBUG_FUNCPTR (gst_identity_src_event);
gstbasetrans_class->transform_ip =
GST_DEBUG_FUNCPTR (gst_identity_transform_ip);
gstbasetrans_class->start = GST_DEBUG_FUNCPTR (gst_identity_start);
@ -420,7 +423,14 @@ gst_identity_sink_event (GstBaseTransform * trans, GstEvent * event)
/* This is the first segment, send out a (0, -1) segment */
gst_segment_init (&segment, segment.format);
if (identity->seek_segment.format != GST_FORMAT_UNDEFINED) {
segment.time = identity->seek_segment.time;
segment.base = identity->seek_segment.base;
gst_segment_init (&identity->seek_segment, GST_FORMAT_UNDEFINED);
}
news = gst_event_new_segment (&segment);
GST_EVENT_SEQNUM (news) = GST_EVENT_SEQNUM (event);
gst_pad_event_default (trans->sinkpad, GST_OBJECT_CAST (trans), news);
} else {
@ -459,8 +469,11 @@ gst_identity_sink_event (GstBaseTransform * trans, GstEvent * event)
/* eat up segments */
gst_event_unref (event);
ret = TRUE;
} else {
if (GST_EVENT_TYPE (event) == GST_EVENT_FLUSH_START) {
goto done;
}
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_FLUSH_START:
GST_OBJECT_LOCK (identity);
identity->flushing = TRUE;
g_cond_signal (&identity->blocked_cond);
@ -469,18 +482,60 @@ gst_identity_sink_event (GstBaseTransform * trans, GstEvent * event)
gst_clock_id_unschedule (identity->clock_id);
}
GST_OBJECT_UNLOCK (identity);
} else if (GST_EVENT_TYPE (event) == GST_EVENT_FLUSH_STOP) {
break;
case GST_EVENT_FLUSH_STOP:
GST_OBJECT_LOCK (identity);
identity->flushing = FALSE;
trans->have_segment = FALSE;
GST_OBJECT_UNLOCK (identity);
}
ret = GST_BASE_TRANSFORM_CLASS (parent_class)->sink_event (trans, event);
break;
default:
break;
}
ret = GST_BASE_TRANSFORM_CLASS (parent_class)->sink_event (trans, event);
done:
return ret;
}
static gboolean
gst_identity_src_event (GstBaseTransform * trans, GstEvent * event)
{
GstIdentity *identity = GST_IDENTITY (trans);
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_SEEK:
{
gdouble rate;
GstFormat fmt;
GstSeekFlags flags;
GstSeekType start_type, stop_type;
gint64 start, stop;
gst_event_parse_seek (event, &rate, &fmt, &flags, &start_type,
&start, &stop_type, &stop);
GST_OBJECT_LOCK (identity);
gst_segment_init (&identity->seek_segment, fmt);
if (!gst_segment_do_seek (&identity->seek_segment, rate, fmt,
flags, start_type, start, stop_type, stop, NULL)) {
GST_WARNING_OBJECT (identity, "Could not run seek %" GST_PTR_FORMAT,
event);
GST_OBJECT_UNLOCK (identity);
return FALSE;
}
GST_OBJECT_UNLOCK (identity);
break;
}
default:
break;
}
return GST_BASE_TRANSFORM_CLASS (parent_class)->src_event (trans, event);
}
static void
gst_identity_check_imperfect_timestamp (GstIdentity * identity, GstBuffer * buf)
{

View file

@ -67,6 +67,7 @@ struct _GstIdentity {
gboolean check_imperfect_timestamp;
gboolean check_imperfect_offset;
gboolean single_segment;
GstSegment seek_segment;
GstBufferFlags drop_buffer_flags;
GstClockTime prev_timestamp;
GstClockTime prev_duration;