mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-10-02 16:52:42 +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,
|
static gboolean gst_identity_sink_event (GstBaseTransform * trans,
|
||||||
GstEvent * event);
|
GstEvent * event);
|
||||||
|
static gboolean gst_identity_src_event (GstBaseTransform * trans,
|
||||||
|
GstEvent * event);
|
||||||
static GstFlowReturn gst_identity_transform_ip (GstBaseTransform * trans,
|
static GstFlowReturn gst_identity_transform_ip (GstBaseTransform * trans,
|
||||||
GstBuffer * buf);
|
GstBuffer * buf);
|
||||||
static gboolean gst_identity_start (GstBaseTransform * trans);
|
static gboolean gst_identity_start (GstBaseTransform * trans);
|
||||||
|
@ -277,6 +279,7 @@ gst_identity_class_init (GstIdentityClass * klass)
|
||||||
GST_DEBUG_FUNCPTR (gst_identity_change_state);
|
GST_DEBUG_FUNCPTR (gst_identity_change_state);
|
||||||
|
|
||||||
gstbasetrans_class->sink_event = GST_DEBUG_FUNCPTR (gst_identity_sink_event);
|
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 =
|
gstbasetrans_class->transform_ip =
|
||||||
GST_DEBUG_FUNCPTR (gst_identity_transform_ip);
|
GST_DEBUG_FUNCPTR (gst_identity_transform_ip);
|
||||||
gstbasetrans_class->start = GST_DEBUG_FUNCPTR (gst_identity_start);
|
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 */
|
/* This is the first segment, send out a (0, -1) segment */
|
||||||
gst_segment_init (&segment, segment.format);
|
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);
|
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);
|
gst_pad_event_default (trans->sinkpad, GST_OBJECT_CAST (trans), news);
|
||||||
} else {
|
} else {
|
||||||
|
@ -459,8 +469,11 @@ gst_identity_sink_event (GstBaseTransform * trans, GstEvent * event)
|
||||||
/* eat up segments */
|
/* eat up segments */
|
||||||
gst_event_unref (event);
|
gst_event_unref (event);
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
} else {
|
goto done;
|
||||||
if (GST_EVENT_TYPE (event) == GST_EVENT_FLUSH_START) {
|
}
|
||||||
|
|
||||||
|
switch (GST_EVENT_TYPE (event)) {
|
||||||
|
case GST_EVENT_FLUSH_START:
|
||||||
GST_OBJECT_LOCK (identity);
|
GST_OBJECT_LOCK (identity);
|
||||||
identity->flushing = TRUE;
|
identity->flushing = TRUE;
|
||||||
g_cond_signal (&identity->blocked_cond);
|
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_clock_id_unschedule (identity->clock_id);
|
||||||
}
|
}
|
||||||
GST_OBJECT_UNLOCK (identity);
|
GST_OBJECT_UNLOCK (identity);
|
||||||
} else if (GST_EVENT_TYPE (event) == GST_EVENT_FLUSH_STOP) {
|
break;
|
||||||
|
case GST_EVENT_FLUSH_STOP:
|
||||||
GST_OBJECT_LOCK (identity);
|
GST_OBJECT_LOCK (identity);
|
||||||
identity->flushing = FALSE;
|
identity->flushing = FALSE;
|
||||||
|
trans->have_segment = FALSE;
|
||||||
GST_OBJECT_UNLOCK (identity);
|
GST_OBJECT_UNLOCK (identity);
|
||||||
}
|
break;
|
||||||
|
default:
|
||||||
ret = GST_BASE_TRANSFORM_CLASS (parent_class)->sink_event (trans, event);
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ret = GST_BASE_TRANSFORM_CLASS (parent_class)->sink_event (trans, event);
|
||||||
|
|
||||||
|
done:
|
||||||
return ret;
|
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
|
static void
|
||||||
gst_identity_check_imperfect_timestamp (GstIdentity * identity, GstBuffer * buf)
|
gst_identity_check_imperfect_timestamp (GstIdentity * identity, GstBuffer * buf)
|
||||||
{
|
{
|
||||||
|
|
|
@ -67,6 +67,7 @@ struct _GstIdentity {
|
||||||
gboolean check_imperfect_timestamp;
|
gboolean check_imperfect_timestamp;
|
||||||
gboolean check_imperfect_offset;
|
gboolean check_imperfect_offset;
|
||||||
gboolean single_segment;
|
gboolean single_segment;
|
||||||
|
GstSegment seek_segment;
|
||||||
GstBufferFlags drop_buffer_flags;
|
GstBufferFlags drop_buffer_flags;
|
||||||
GstClockTime prev_timestamp;
|
GstClockTime prev_timestamp;
|
||||||
GstClockTime prev_duration;
|
GstClockTime prev_duration;
|
||||||
|
|
Loading…
Reference in a new issue