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);
GstConcatPad *spad = GST_CONCAT_PAD_CAST (pad);
gboolean ret = TRUE;
gboolean adjust_base;
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)) {
case GST_EVENT_STREAM_START:{
if (!gst_concat_pad_wait (spad, self)) {
ret = FALSE;
gst_event_unref (event);
} else {
ret = gst_pad_event_default (pad, parent, event);
gst_event_replace (&event, NULL);
}
break;
}
case GST_EVENT_SEGMENT:{
gboolean adjust_base;
/* Drop segment event, we create our own one */
gst_event_copy_segment (event, &spad->segment);
gst_event_unref (event);
gst_event_replace (&event, NULL);
g_mutex_lock (&self->lock);
adjust_base = self->adjust_base;
if (self->format == GST_FORMAT_UNDEFINED) {
if (spad->segment.format != GST_FORMAT_TIME
&& spad->segment.format != GST_FORMAT_BYTES) {
@ -572,7 +572,6 @@ gst_concat_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
ret = FALSE;
} else {
GstSegment segment = spad->segment;
GstEvent *topush;
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);
gst_event_set_seqnum (topush, gst_event_get_seqnum (event));
event = gst_event_new_segment (&segment);
gst_event_set_seqnum (event, gst_event_get_seqnum (event));
g_mutex_unlock (&self->lock);
gst_pad_push_event (self->srcpad, topush);
}
break;
}
case GST_EVENT_EOS:{
gst_event_unref (event);
gst_event_replace (&event, NULL);
if (!gst_concat_pad_wait (spad, self)) {
ret = FALSE;
@ -631,7 +628,7 @@ gst_concat_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
gst_concat_notify_active_pad (self);
if (!next) {
gst_pad_push_event (self->srcpad, gst_event_new_eos ());
event = gst_event_new_eos ();
} else {
gst_element_post_message (GST_ELEMENT_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;
g_mutex_unlock (&self->lock);
if (forward)
ret = gst_pad_event_default (pad, parent, event);
else
gst_event_unref (event);
if (!forward)
gst_event_replace (&event, NULL);
break;
}
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->last_stop = GST_CLOCK_TIME_NONE;
}
ret = gst_pad_event_default (pad, parent, event);
} else {
gst_event_unref (event);
gst_event_replace (&event, NULL);
}
break;
}
default:{
/* Wait for other serialized events before forwarding */
if (GST_EVENT_IS_SERIALIZED (event) && !gst_concat_pad_wait (spad, self)) {
gst_event_unref (event);
gst_event_replace (&event, NULL);
ret = FALSE;
} else {
ret = gst_pad_event_default (pad, parent, event);
}
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;
}
@ -727,13 +734,12 @@ gst_concat_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
GstConcat *self = GST_CONCAT (parent);
gboolean ret = TRUE;
GstPad *sinkpad = NULL;
GST_LOG_OBJECT (pad, "received event %" GST_PTR_FORMAT, event);
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_SEEK:{
GstPad *sinkpad = NULL;
g_mutex_lock (&self->lock);
if ((sinkpad = self->current_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);
}
g_mutex_unlock (&self->lock);
if (sinkpad) {
ret = gst_pad_push_event (sinkpad, event);
gst_object_unref (sinkpad);
} else {
gst_event_unref (event);
if (!sinkpad) {
gst_event_replace (&event, NULL);
ret = FALSE;
}
break;
}
case GST_EVENT_QOS:{
GstQOSType type;
GstClockTimeDiff diff;
GstClockTime timestamp;
gdouble proportion;
GstPad *sinkpad = NULL;
g_mutex_lock (&self->lock);
@ -763,21 +762,9 @@ gst_concat_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
gst_object_ref (sinkpad);
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
&& timestamp > self->current_start_offset) {
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);
if (!sinkpad) {
gst_event_replace (&event, NULL);
ret = FALSE;
}
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");
self->current_start_offset = 0;
}
ret = gst_pad_event_default (pad, parent, event);
break;
}
default:
ret = gst_pad_event_default (pad, parent, event);
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;
}