static void gst_pad_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
-static void handle_pad_block (GstPad * pad);
+static GstFlowReturn handle_pad_block (GstPad * pad);
static GstCaps *gst_pad_get_caps_unlocked (GstPad * pad);
static void gst_pad_set_pad_template (GstPad * pad, GstPadTemplate * templ);
static gboolean gst_pad_activate_default (GstPad * pad);
GST_LOCK (pad);
while (G_UNLIKELY (GST_PAD_IS_BLOCKED (pad)))
- handle_pad_block (pad);
+ if ((ret = handle_pad_block (pad)) != GST_FLOW_OK)
+ goto flushed;
if (G_UNLIKELY ((peer = GST_PAD_PEER (pad)) == NULL))
goto no_peer;
}
return ret;
+flushed:
+ {
+ GST_CAT_DEBUG (GST_CAT_PADS, "%s:%s pad block stopped by flush",
+ GST_DEBUG_PAD_NAME (pad));
+ GST_UNLOCK (pad);
+ return ret;
+ }
no_peer:
{
/* pad has no peer */
*
* MT safe.
*/
-static void
+static GstFlowReturn
handle_pad_block (GstPad * pad)
{
GstPadBlockCallback callback;
gpointer user_data;
+ GstFlowReturn ret = GST_FLOW_OK;
GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
"signal block taken on pad %s:%s", GST_DEBUG_PAD_NAME (pad));
GST_PAD_BLOCK_SIGNAL (pad);
}
- while (GST_PAD_IS_BLOCKED (pad))
+ while (GST_PAD_IS_BLOCKED (pad)) {
GST_PAD_BLOCK_WAIT (pad);
+ if (GST_PAD_IS_FLUSHING (pad))
+ goto flushing;
+ }
GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "got unblocked");
}
gst_object_unref (pad);
+
+ return ret;
+
+flushing:
+ {
+ gst_object_unref (pad);
+ return GST_FLOW_WRONG_STATE;
+ }
}
/**********************************************************************
/* FIXME: this check can go away; pad_set_blocked could be implemented with
* probes completely */
while (G_UNLIKELY (GST_PAD_IS_BLOCKED (pad)))
- handle_pad_block (pad);
+ if ((ret = handle_pad_block (pad)) != GST_FLOW_OK)
+ goto flushed;
/* we emit signals on the pad arg, the peer will have a chance to
* emit in the _chain() function */
return ret;
/* ERROR recovery here */
+flushed:
+ {
+ gst_buffer_unref (buffer);
+ GST_DEBUG_OBJECT (pad, "pad block stopped by flush");
+ GST_UNLOCK (pad);
+ return ret;
+ }
dropped:
{
gst_buffer_unref (buffer);
g_return_val_if_fail (GST_IS_EVENT (event), FALSE);
GST_LOCK (pad);
+ switch (GST_EVENT_TYPE (event)) {
+ case GST_EVENT_FLUSH_START:
+ GST_PAD_SET_FLUSHING (pad);
+ break;
+ case GST_EVENT_FLUSH_STOP:
+ GST_PAD_UNSET_FLUSHING (pad);
+ break;
+ default:
+ break;
+ }
+
+ if (G_UNLIKELY (GST_PAD_IS_BLOCKED (pad))) {
+ if (GST_EVENT_TYPE (event) == GST_EVENT_FLUSH_START) {
+ GST_PAD_BLOCK_SIGNAL (pad);
+ }
+ }
+
if (G_UNLIKELY (GST_PAD_DO_EVENT_SIGNALS (pad) > 0)) {
GST_UNLOCK (pad);