concat: adjust running time offsets on events

When concat adjusts the base of the segments it forwards
downstream, it needs to also adjust the running time offsets,
as GstPad does when an offset is set by the application on a pad.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/823>
This commit is contained in:
Mathieu Duponchelle 2021-05-11 21:16:01 +02:00 committed by Tim-Philipp Müller
parent 96800c0b4a
commit 53c68d92d8

View file

@ -522,28 +522,28 @@ gst_concat_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
GstConcat *self = GST_CONCAT (parent); GstConcat *self = GST_CONCAT (parent);
GstConcatPad *spad = GST_CONCAT_PAD_CAST (pad); GstConcatPad *spad = GST_CONCAT_PAD_CAST (pad);
gboolean ret = TRUE; gboolean ret = TRUE;
gboolean adjust_base;
GST_LOG_OBJECT (pad, "received event %" GST_PTR_FORMAT, event); GST_LOG_OBJECT (pad, "received event %" GST_PTR_FORMAT, event);
g_mutex_lock (&self->lock);
adjust_base = self->adjust_base;
g_mutex_unlock (&self->lock);
switch (GST_EVENT_TYPE (event)) { switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_STREAM_START:{ case GST_EVENT_STREAM_START:{
if (!gst_concat_pad_wait (spad, self)) { if (!gst_concat_pad_wait (spad, self)) {
ret = FALSE; ret = FALSE;
gst_event_unref (event); gst_event_replace (&event, NULL);
} else {
ret = gst_pad_event_default (pad, parent, event);
} }
break; break;
} }
case GST_EVENT_SEGMENT:{ case GST_EVENT_SEGMENT:{
gboolean adjust_base;
/* Drop segment event, we create our own one */ /* Drop segment event, we create our own one */
gst_event_copy_segment (event, &spad->segment); gst_event_copy_segment (event, &spad->segment);
gst_event_unref (event); gst_event_replace (&event, NULL);
g_mutex_lock (&self->lock); g_mutex_lock (&self->lock);
adjust_base = self->adjust_base;
if (self->format == GST_FORMAT_UNDEFINED) { if (self->format == GST_FORMAT_UNDEFINED) {
if (spad->segment.format != GST_FORMAT_TIME if (spad->segment.format != GST_FORMAT_TIME
&& spad->segment.format != GST_FORMAT_BYTES) { && spad->segment.format != GST_FORMAT_BYTES) {
@ -572,7 +572,6 @@ gst_concat_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
ret = FALSE; ret = FALSE;
} else { } else {
GstSegment segment = spad->segment; GstSegment segment = spad->segment;
GstEvent *topush;
g_mutex_lock (&self->lock); g_mutex_lock (&self->lock);
@ -606,17 +605,15 @@ gst_concat_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
} }
} }
} }
topush = gst_event_new_segment (&segment); event = gst_event_new_segment (&segment);
gst_event_set_seqnum (topush, gst_event_get_seqnum (event)); gst_event_set_seqnum (event, gst_event_get_seqnum (event));
g_mutex_unlock (&self->lock); g_mutex_unlock (&self->lock);
gst_pad_push_event (self->srcpad, topush);
} }
break; break;
} }
case GST_EVENT_EOS:{ case GST_EVENT_EOS:{
gst_event_unref (event); gst_event_replace (&event, NULL);
if (!gst_concat_pad_wait (spad, self)) { if (!gst_concat_pad_wait (spad, self)) {
ret = FALSE; ret = FALSE;
@ -631,7 +628,7 @@ gst_concat_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
gst_concat_notify_active_pad (self); gst_concat_notify_active_pad (self);
if (!next) { if (!next) {
gst_pad_push_event (self->srcpad, gst_event_new_eos ()); event = gst_event_new_eos ();
} else { } else {
gst_element_post_message (GST_ELEMENT_CAST (self), gst_element_post_message (GST_ELEMENT_CAST (self),
gst_message_new_duration_changed (GST_OBJECT_CAST (self))); gst_message_new_duration_changed (GST_OBJECT_CAST (self)));
@ -650,10 +647,8 @@ gst_concat_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
forward = TRUE; forward = TRUE;
g_mutex_unlock (&self->lock); g_mutex_unlock (&self->lock);
if (forward) if (!forward)
ret = gst_pad_event_default (pad, parent, event); gst_event_replace (&event, NULL);
else
gst_event_unref (event);
break; break;
} }
case GST_EVENT_FLUSH_STOP:{ case GST_EVENT_FLUSH_STOP:{
@ -678,24 +673,36 @@ gst_concat_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
self->current_start_offset = 0; self->current_start_offset = 0;
self->last_stop = GST_CLOCK_TIME_NONE; self->last_stop = GST_CLOCK_TIME_NONE;
} }
ret = gst_pad_event_default (pad, parent, event);
} else { } else {
gst_event_unref (event); gst_event_replace (&event, NULL);
} }
break; break;
} }
default:{ default:{
/* Wait for other serialized events before forwarding */ /* Wait for other serialized events before forwarding */
if (GST_EVENT_IS_SERIALIZED (event) && !gst_concat_pad_wait (spad, self)) { if (GST_EVENT_IS_SERIALIZED (event) && !gst_concat_pad_wait (spad, self)) {
gst_event_unref (event); gst_event_replace (&event, NULL);
ret = FALSE; ret = FALSE;
} else {
ret = gst_pad_event_default (pad, parent, event);
} }
break; break;
} }
} }
if (event) {
g_mutex_lock (&self->lock);
if (self->adjust_base && self->format == GST_FORMAT_TIME) {
gint64 offset;
event = gst_event_make_writable (event);
offset = gst_event_get_running_time_offset (event);
offset += self->current_start_offset;
gst_event_set_running_time_offset (event, offset);
}
g_mutex_unlock (&self->lock);
ret = gst_pad_event_default (pad, parent, event);
}
return ret; return ret;
} }
@ -727,13 +734,12 @@ gst_concat_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
{ {
GstConcat *self = GST_CONCAT (parent); GstConcat *self = GST_CONCAT (parent);
gboolean ret = TRUE; gboolean ret = TRUE;
GstPad *sinkpad = NULL;
GST_LOG_OBJECT (pad, "received event %" GST_PTR_FORMAT, event); GST_LOG_OBJECT (pad, "received event %" GST_PTR_FORMAT, event);
switch (GST_EVENT_TYPE (event)) { switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_SEEK:{ case GST_EVENT_SEEK:{
GstPad *sinkpad = NULL;
g_mutex_lock (&self->lock); g_mutex_lock (&self->lock);
if ((sinkpad = self->current_sinkpad)) if ((sinkpad = self->current_sinkpad))
gst_object_ref (sinkpad); gst_object_ref (sinkpad);
@ -742,20 +748,13 @@ gst_concat_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
sinkpad = gst_object_ref (self->sinkpads->data); sinkpad = gst_object_ref (self->sinkpads->data);
} }
g_mutex_unlock (&self->lock); g_mutex_unlock (&self->lock);
if (sinkpad) { if (!sinkpad) {
ret = gst_pad_push_event (sinkpad, event); gst_event_replace (&event, NULL);
gst_object_unref (sinkpad);
} else {
gst_event_unref (event);
ret = FALSE; ret = FALSE;
} }
break; break;
} }
case GST_EVENT_QOS:{ case GST_EVENT_QOS:{
GstQOSType type;
GstClockTimeDiff diff;
GstClockTime timestamp;
gdouble proportion;
GstPad *sinkpad = NULL; GstPad *sinkpad = NULL;
g_mutex_lock (&self->lock); g_mutex_lock (&self->lock);
@ -763,21 +762,9 @@ gst_concat_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
gst_object_ref (sinkpad); gst_object_ref (sinkpad);
g_mutex_unlock (&self->lock); g_mutex_unlock (&self->lock);
if (sinkpad) {
gst_event_parse_qos (event, &type, &proportion, &diff, &timestamp);
gst_event_unref (event);
if (timestamp != GST_CLOCK_TIME_NONE if (!sinkpad) {
&& timestamp > self->current_start_offset) { gst_event_replace (&event, NULL);
timestamp -= self->current_start_offset;
event = gst_event_new_qos (type, proportion, diff, timestamp);
ret = gst_pad_push_event (self->current_sinkpad, event);
} else {
ret = FALSE;
}
gst_object_unref (sinkpad);
} else {
gst_event_unref (event);
ret = FALSE; ret = FALSE;
} }
break; break;
@ -791,15 +778,34 @@ gst_concat_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
"resetting start offset to 0 after flushing with reset_time = TRUE"); "resetting start offset to 0 after flushing with reset_time = TRUE");
self->current_start_offset = 0; self->current_start_offset = 0;
} }
ret = gst_pad_event_default (pad, parent, event);
break; break;
} }
default: default:
ret = gst_pad_event_default (pad, parent, event);
break; break;
} }
if (event) {
g_mutex_lock (&self->lock);
if (self->adjust_base && self->format == GST_FORMAT_TIME) {
gint64 offset;
event = gst_event_make_writable (event);
offset = gst_event_get_running_time_offset (event);
offset -= self->current_start_offset;
gst_event_set_running_time_offset (event, offset);
}
g_mutex_unlock (&self->lock);
if (sinkpad)
ret = gst_pad_push_event (sinkpad, event);
else
ret = gst_pad_event_default (pad, parent, event);
}
if (sinkpad)
gst_object_unref (sinkpad);
return ret; return ret;
} }