mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-03-07 20:31:20 +00:00
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:
parent
b517b59171
commit
cb212c9fd7
2 changed files with 62 additions and 6 deletions
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue