Provide intrastructure to not have to pass NULL buffers on errors and interrupts, this should fix some issues with th...

Original commit message from CVS:
Provide intrastructure to not have to pass NULL buffers on errors and
interrupts, this should fix some issues with the optimal scheduler.
This commit is contained in:
Wim Taymans 2003-01-08 21:33:20 +00:00
parent b005b541c8
commit e8b63df877
7 changed files with 59 additions and 15 deletions

View file

@ -265,10 +265,18 @@ gst_identity_loop (GstElement *element)
buf = gst_pad_pull (identity->sinkpad); buf = gst_pad_pull (identity->sinkpad);
if (GST_IS_EVENT (buf)) { if (GST_IS_EVENT (buf)) {
gst_pad_event_default (identity->sinkpad, GST_EVENT (buf)); GstEvent *event = GST_EVENT (buf);
}
gst_identity_chain (identity->sinkpad, buf); if (GST_EVENT_IS_INTERRUPT (event)) {
gst_event_unref (event);
}
else {
gst_pad_event_default (identity->sinkpad, event);
}
}
else {
gst_identity_chain (identity->sinkpad, buf);
}
} }
static void static void

View file

@ -45,7 +45,8 @@ typedef enum {
GST_EVENT_SIZE, GST_EVENT_SIZE,
GST_EVENT_RATE, GST_EVENT_RATE,
GST_EVENT_FILLER, GST_EVENT_FILLER,
GST_EVENT_TS_OFFSET GST_EVENT_TS_OFFSET,
GST_EVENT_INTERRUPT
} GstEventType; } GstEventType;
extern GType _gst_event_type; extern GType _gst_event_type;
@ -58,6 +59,8 @@ extern GType _gst_event_type;
#define GST_EVENT_TIMESTAMP(event) (GST_EVENT(event)->timestamp) #define GST_EVENT_TIMESTAMP(event) (GST_EVENT(event)->timestamp)
#define GST_EVENT_SRC(event) (GST_EVENT(event)->src) #define GST_EVENT_SRC(event) (GST_EVENT(event)->src)
#define GST_EVENT_IS_INTERRUPT(event) (GST_EVENT_TYPE (event) == GST_EVENT_INTERRUPT)
#define GST_SEEK_FORMAT_SHIFT 0 #define GST_SEEK_FORMAT_SHIFT 0
#define GST_SEEK_METHOD_SHIFT 16 #define GST_SEEK_METHOD_SHIFT 16
#define GST_SEEK_FLAGS_SHIFT 20 #define GST_SEEK_FLAGS_SHIFT 20

View file

@ -2193,7 +2193,8 @@ gst_pad_pull (GstPad *pad)
GST_DEBUG_ENTER("(%s:%s)",GST_DEBUG_PAD_NAME(pad)); GST_DEBUG_ENTER("(%s:%s)",GST_DEBUG_PAD_NAME(pad));
g_return_val_if_fail (GST_PAD_DIRECTION (pad) == GST_PAD_SINK, NULL); g_return_val_if_fail (GST_PAD_DIRECTION (pad) == GST_PAD_SINK,
GST_BUFFER (gst_event_new (GST_EVENT_INTERRUPT)));
peer = GST_RPAD_PEER (pad); peer = GST_RPAD_PEER (pad);
@ -2204,6 +2205,7 @@ gst_pad_pull (GstPad *pad)
GST_PAD_NAME (pad), NULL); GST_PAD_NAME (pad), NULL);
} }
else { else {
restart:
if (peer->gethandler) { if (peer->gethandler) {
GstBuffer *buf; GstBuffer *buf;
gboolean active = GST_PAD_IS_ACTIVE (peer); gboolean active = GST_PAD_IS_ACTIVE (peer);
@ -2216,12 +2218,12 @@ gst_pad_pull (GstPad *pad)
if (buf) { if (buf) {
if (!gst_probe_dispatcher_dispatch (&peer->probedisp, GST_DATA (buf))) if (!gst_probe_dispatcher_dispatch (&peer->probedisp, GST_DATA (buf)))
return NULL; goto restart;
if (!GST_IS_EVENT (buf) && !active) { if (!GST_IS_EVENT (buf) && !active) {
g_warning ("pull on pad %s:%s but it is not active", g_warning ("pull on pad %s:%s but it is not active",
GST_DEBUG_PAD_NAME (peer)); GST_DEBUG_PAD_NAME (peer));
return NULL; return GST_BUFFER (gst_event_new (GST_EVENT_INTERRUPT));
} }
return buf; return buf;
} }
@ -2239,7 +2241,7 @@ gst_pad_pull (GstPad *pad)
NULL); NULL);
} }
} }
return NULL; return GST_BUFFER (gst_event_new (GST_EVENT_INTERRUPT));
} }
/** /**

View file

@ -485,7 +485,7 @@ restart:
GST_DEBUG_ELEMENT (GST_CAT_DATAFLOW, queue, "interrupted!!"); GST_DEBUG_ELEMENT (GST_CAT_DATAFLOW, queue, "interrupted!!");
g_mutex_unlock (queue->qlock); g_mutex_unlock (queue->qlock);
if (gst_scheduler_interrupt (gst_pad_get_scheduler (queue->srcpad), GST_ELEMENT (queue))) if (gst_scheduler_interrupt (gst_pad_get_scheduler (queue->srcpad), GST_ELEMENT (queue)))
return NULL; return GST_BUFFER (gst_event_new (GST_EVENT_INTERRUPT));
goto restart; goto restart;
} }
if (GST_STATE (queue) != GST_STATE_PLAYING) { if (GST_STATE (queue) != GST_STATE_PLAYING) {

View file

@ -60,6 +60,7 @@ typedef enum {
GST_OPT_SCHEDULER_STATE_STOPPED, GST_OPT_SCHEDULER_STATE_STOPPED,
GST_OPT_SCHEDULER_STATE_ERROR, GST_OPT_SCHEDULER_STATE_ERROR,
GST_OPT_SCHEDULER_STATE_RUNNING, GST_OPT_SCHEDULER_STATE_RUNNING,
GST_OPT_SCHEDULER_STATE_INTERRUPTED
} GstOptSchedulerState; } GstOptSchedulerState;
struct _GstOptScheduler { struct _GstOptScheduler {
@ -768,8 +769,13 @@ get_group_schedule_function (int argc, char *argv[])
GST_DEBUG_PAD_NAME (pad), group); GST_DEBUG_PAD_NAME (pad), group);
buffer = GST_RPAD_GETFUNC (pad) (pad); buffer = GST_RPAD_GETFUNC (pad) (pad);
if (buffer) if (buffer) {
if (GST_EVENT_IS_INTERRUPT (buffer)) {
gst_event_unref (GST_EVENT (buffer));
break;
}
gst_pad_push (pad, buffer); gst_pad_push (pad, buffer);
}
} }
group->flags &= ~GST_OPT_SCHEDULER_GROUP_RUNNING; group->flags &= ~GST_OPT_SCHEDULER_GROUP_RUNNING;
@ -879,9 +885,14 @@ gst_opt_scheduler_get_wrapper (GstPad *srcpad)
else { else {
g_warning ("deadlock detected, disabling group %p", group); g_warning ("deadlock detected, disabling group %p", group);
group_error_handler (group); group_error_handler (group);
return NULL; return GST_BUFFER (gst_event_new (GST_EVENT_INTERRUPT));
} }
#endif #endif
/* if the scheduler interrupted, make sure we send an INTERRUPTED event to the
* > * loop based element */
if (osched->state == GST_OPT_SCHEDULER_STATE_INTERRUPTED) {
return GST_BUFFER (gst_event_new (GST_EVENT_INTERRUPT));
}
if (GST_PAD_BUFLIST (srcpad)) { if (GST_PAD_BUFLIST (srcpad)) {
buffer = (GstBuffer *) GST_PAD_BUFLIST (srcpad)->data; buffer = (GstBuffer *) GST_PAD_BUFLIST (srcpad)->data;
@ -1219,10 +1230,18 @@ gst_opt_scheduler_yield (GstScheduler *sched, GstElement *element)
static gboolean static gboolean
gst_opt_scheduler_interrupt (GstScheduler *sched, GstElement *element) gst_opt_scheduler_interrupt (GstScheduler *sched, GstElement *element)
{ {
GST_INFO (GST_CAT_SCHEDULING, "interrupt from \"%s\"",
GST_ELEMENT_NAME (element));
#ifdef USE_COTHREADS #ifdef USE_COTHREADS
do_cothread_switch (do_cothread_get_main (((GstOptScheduler*)sched)->context)); do_cothread_switch (do_cothread_get_main (((GstOptScheduler*)sched)->context));
return FALSE; return FALSE;
#else #else
{
GstOptScheduler *osched = GST_OPT_SCHEDULER_CAST (sched);
osched->state = GST_OPT_SCHEDULER_STATE_INTERRUPTED;
}
return TRUE; return TRUE;
#endif #endif
} }
@ -1564,6 +1583,10 @@ gst_opt_scheduler_iterate (GstScheduler *sched)
schedule_chain (chain); schedule_chain (chain);
scheduled = TRUE; scheduled = TRUE;
} }
/* don't schedule any more chains when interrupted or in error */
if (osched->state != GST_OPT_SCHEDULER_STATE_RUNNING)
break;
} }
/* at this point it's possible that the scheduler state is /* at this point it's possible that the scheduler state is

View file

@ -265,10 +265,18 @@ gst_identity_loop (GstElement *element)
buf = gst_pad_pull (identity->sinkpad); buf = gst_pad_pull (identity->sinkpad);
if (GST_IS_EVENT (buf)) { if (GST_IS_EVENT (buf)) {
gst_pad_event_default (identity->sinkpad, GST_EVENT (buf)); GstEvent *event = GST_EVENT (buf);
}
gst_identity_chain (identity->sinkpad, buf); if (GST_EVENT_IS_INTERRUPT (event)) {
gst_event_unref (event);
}
else {
gst_pad_event_default (identity->sinkpad, event);
}
}
else {
gst_identity_chain (identity->sinkpad, buf);
}
} }
static void static void

View file

@ -485,7 +485,7 @@ restart:
GST_DEBUG_ELEMENT (GST_CAT_DATAFLOW, queue, "interrupted!!"); GST_DEBUG_ELEMENT (GST_CAT_DATAFLOW, queue, "interrupted!!");
g_mutex_unlock (queue->qlock); g_mutex_unlock (queue->qlock);
if (gst_scheduler_interrupt (gst_pad_get_scheduler (queue->srcpad), GST_ELEMENT (queue))) if (gst_scheduler_interrupt (gst_pad_get_scheduler (queue->srcpad), GST_ELEMENT (queue)))
return NULL; return GST_BUFFER (gst_event_new (GST_EVENT_INTERRUPT));
goto restart; goto restart;
} }
if (GST_STATE (queue) != GST_STATE_PLAYING) { if (GST_STATE (queue) != GST_STATE_PLAYING) {