mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 12:11:13 +00:00
queue: don't fail in _sink_event for sticky events
Implement the same behaviour as gst_pad_push_event when pushing sticky events fails, that is don't fail immediately but fail when data flow resumes and upstream can aggregate properly. This fixes segment seeks with decodebin and unlinked audio or video branches. Fixes: https://bugzilla.gnome.org/show_bug.cgi?id=687899
This commit is contained in:
parent
d8413cd0a2
commit
c257b19ead
2 changed files with 77 additions and 1 deletions
|
@ -771,7 +771,17 @@ gst_queue_handle_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
|
||||||
default:
|
default:
|
||||||
if (GST_EVENT_IS_SERIALIZED (event)) {
|
if (GST_EVENT_IS_SERIALIZED (event)) {
|
||||||
/* serialized events go in the queue */
|
/* serialized events go in the queue */
|
||||||
GST_QUEUE_MUTEX_LOCK_CHECK (queue, out_flushing);
|
GST_QUEUE_MUTEX_LOCK (queue);
|
||||||
|
if (queue->srcresult != GST_FLOW_OK) {
|
||||||
|
/* Errors in sticky event pushing are no problem and ignored here
|
||||||
|
* as they will cause more meaningful errors during data flow.
|
||||||
|
* For EOS events, that are not followed by data flow, we still
|
||||||
|
* return FALSE here though.
|
||||||
|
*/
|
||||||
|
if (!GST_EVENT_IS_STICKY (event) ||
|
||||||
|
GST_EVENT_TYPE (event) == GST_EVENT_EOS)
|
||||||
|
goto out_flow_error;
|
||||||
|
}
|
||||||
/* refuse more events on EOS */
|
/* refuse more events on EOS */
|
||||||
if (queue->eos)
|
if (queue->eos)
|
||||||
goto out_eos;
|
goto out_eos;
|
||||||
|
@ -802,6 +812,15 @@ out_eos:
|
||||||
gst_event_unref (event);
|
gst_event_unref (event);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
out_flow_error:
|
||||||
|
{
|
||||||
|
GST_CAT_LOG_OBJECT (queue_dataflow, queue,
|
||||||
|
"refusing event, we have a downstream flow error: %s",
|
||||||
|
gst_flow_get_name (queue->srcresult));
|
||||||
|
GST_QUEUE_MUTEX_UNLOCK (queue);
|
||||||
|
gst_event_unref (event);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
|
|
@ -630,6 +630,62 @@ GST_START_TEST (test_time_level_task_not_started)
|
||||||
|
|
||||||
GST_END_TEST;
|
GST_END_TEST;
|
||||||
|
|
||||||
|
GST_START_TEST (test_sticky_not_linked)
|
||||||
|
{
|
||||||
|
GstEvent *event;
|
||||||
|
GstSegment segment;
|
||||||
|
gboolean ret;
|
||||||
|
GstFlowReturn flow_ret;
|
||||||
|
|
||||||
|
GST_DEBUG ("starting");
|
||||||
|
|
||||||
|
g_object_set (queue, "max-size-buffers", 1, NULL);
|
||||||
|
|
||||||
|
UNDERRUN_LOCK ();
|
||||||
|
fail_unless (gst_element_set_state (queue,
|
||||||
|
GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
|
||||||
|
"could not set to playing");
|
||||||
|
UNDERRUN_WAIT ();
|
||||||
|
UNDERRUN_UNLOCK ();
|
||||||
|
|
||||||
|
gst_pad_push_event (mysrcpad, gst_event_new_stream_start ("test"));
|
||||||
|
|
||||||
|
gst_segment_init (&segment, GST_FORMAT_TIME);
|
||||||
|
segment.start = 1 * GST_SECOND;
|
||||||
|
segment.stop = 5 * GST_SECOND;
|
||||||
|
segment.time = 0;
|
||||||
|
segment.position = 1 * GST_SECOND;
|
||||||
|
|
||||||
|
event = gst_event_new_segment (&segment);
|
||||||
|
ret = gst_pad_push_event (mysrcpad, event);
|
||||||
|
fail_unless (ret == TRUE);
|
||||||
|
|
||||||
|
/* the first few buffers can return OK as they are queued and gst_queue_loop
|
||||||
|
* is woken up, tries to push and sets ->srcresult to NOT_LINKED
|
||||||
|
*/
|
||||||
|
flow_ret = GST_FLOW_OK;
|
||||||
|
while (flow_ret != GST_FLOW_NOT_LINKED)
|
||||||
|
flow_ret = gst_pad_push (mysrcpad, gst_buffer_new ());
|
||||||
|
|
||||||
|
/* send a new sticky event so that it will be pushed on the next gst_pad_push
|
||||||
|
*/
|
||||||
|
event = gst_event_new_segment (&segment);
|
||||||
|
ret = gst_pad_push_event (mysrcpad, event);
|
||||||
|
fail_unless (ret == TRUE);
|
||||||
|
|
||||||
|
/* make sure that gst_queue_sink_event doesn't return FALSE if the queue is
|
||||||
|
* unlinked, as that would make gst_pad_push return ERROR
|
||||||
|
*/
|
||||||
|
flow_ret = gst_pad_push (mysrcpad, gst_buffer_new ());
|
||||||
|
fail_unless_equals_int (flow_ret, GST_FLOW_NOT_LINKED);
|
||||||
|
|
||||||
|
GST_DEBUG ("stopping");
|
||||||
|
fail_unless (gst_element_set_state (queue,
|
||||||
|
GST_STATE_NULL) == GST_STATE_CHANGE_SUCCESS, "could not set to null");
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_END_TEST;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
static gboolean
|
static gboolean
|
||||||
event_equals_newsegment (GstEvent * event, gboolean update, gdouble rate,
|
event_equals_newsegment (GstEvent * event, gboolean update, gdouble rate,
|
||||||
|
@ -773,6 +829,7 @@ queue_suite (void)
|
||||||
#if 0
|
#if 0
|
||||||
tcase_add_test (tc_chain, test_newsegment);
|
tcase_add_test (tc_chain, test_newsegment);
|
||||||
#endif
|
#endif
|
||||||
|
tcase_add_test (tc_chain, test_sticky_not_linked);
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue