diff --git a/gst/elements/gstfakesink.c b/gst/elements/gstfakesink.c index 20abe3913f..886cd065e3 100644 --- a/gst/elements/gstfakesink.c +++ b/gst/elements/gstfakesink.c @@ -282,7 +282,10 @@ gst_fakesink_chain (GstPad *pad, GstBuffer *buf) } if (fakesink->sync && fakesink->clock) { - gst_element_clock_wait (GST_ELEMENT (fakesink), fakesink->clock, GST_BUFFER_TIMESTAMP (buf), NULL); + GstClockID id = gst_clock_new_single_shot_id (fakesink->clock, GST_BUFFER_TIMESTAMP (buf)); + + gst_element_clock_wait (GST_ELEMENT (fakesink), id, NULL); + gst_clock_id_free (id); } if (!fakesink->silent) { diff --git a/gst/gstelement.c b/gst/gstelement.c index 397a2b5ea6..de8f57e855 100644 --- a/gst/gstelement.c +++ b/gst/gstelement.c @@ -749,8 +749,7 @@ gst_element_get_clock (GstElement *element) /** * gst_element_clock_wait: * @element: a #GstElement. - * @clock: the #GstClock to use. - * @time: the #GstClockTime to wait for on the clock. + * @id: the #GstClock to use. * @jitter: the difference between requested time and actual time. * * Waits for a specific time on the clock. @@ -758,14 +757,14 @@ gst_element_get_clock (GstElement *element) * Returns: the #GstClockReturn result of the wait operation. */ GstClockReturn -gst_element_clock_wait (GstElement *element, GstClock *clock, GstClockTime time, GstClockTimeDiff *jitter) +gst_element_clock_wait (GstElement *element, GstClockID id, GstClockTimeDiff *jitter) { GstClockReturn res; g_return_val_if_fail (GST_IS_ELEMENT (element), GST_CLOCK_ERROR); if (GST_ELEMENT_SCHED (element)) { - res = gst_scheduler_clock_wait (GST_ELEMENT_SCHED (element), element, clock, time, jitter); + res = gst_scheduler_clock_wait (GST_ELEMENT_SCHED (element), element, id, jitter); } else res = GST_CLOCK_TIMEOUT; @@ -1899,6 +1898,8 @@ gst_element_error (GstElement *element, const gchar *error, ...) gst_scheduler_error (element->sched, element); } + gst_element_set_state (element, GST_STATE_PAUSED); + /* cleanup */ gst_object_unref (GST_OBJECT (element)); g_free (string); @@ -2100,6 +2101,22 @@ gst_element_clear_pad_caps (GstElement *element) } } +static void +gst_element_pads_activate (GstElement *element, gboolean active) +{ + GList *pads = element->pads; + + while (pads) { + GstPad *pad = GST_PAD_CAST (pads->data); + pads = g_list_next (pads); + + if (!GST_IS_REAL_PAD (pad)) + continue; + + gst_pad_set_active (pad, active); + } +} + static GstElementStateReturn gst_element_change_state (GstElement *element) { @@ -2121,17 +2138,23 @@ gst_element_change_state (GstElement *element) return GST_STATE_SUCCESS; } - GST_INFO (GST_CAT_STATES, "%s default handler sets state from %s to %s %d", + GST_INFO (GST_CAT_STATES, "%s default handler sets state from %s to %s %04x", GST_ELEMENT_NAME (element), gst_element_state_get_name (old_state), gst_element_state_get_name (old_pending), - GST_STATE_TRANSITION (element)); + old_transition); /* we set the state change early for the negotiation functions */ GST_STATE (element) = old_pending; GST_STATE_PENDING (element) = GST_STATE_VOID_PENDING; switch (old_transition) { + case GST_STATE_PLAYING_TO_PAUSED: + gst_element_pads_activate (element, FALSE); + break; + case GST_STATE_PAUSED_TO_PLAYING: + gst_element_pads_activate (element, TRUE); + break; /* if we are going to paused, we try to negotiate the pads */ case GST_STATE_READY_TO_PAUSED: if (!gst_element_negotiate_pads (element)) diff --git a/gst/gstelement.h b/gst/gstelement.h index 13296f9135..564214c5a2 100644 --- a/gst/gstelement.h +++ b/gst/gstelement.h @@ -226,8 +226,8 @@ gboolean gst_element_requires_clock (GstElement *element); gboolean gst_element_provides_clock (GstElement *element); GstClock* gst_element_get_clock (GstElement *element); void gst_element_set_clock (GstElement *element, GstClock *clock); -GstClockReturn gst_element_clock_wait (GstElement *element, GstClock *clock, - GstClockTime time, GstClockTimeDiff *jitter); +GstClockReturn gst_element_clock_wait (GstElement *element, + GstClockID id, GstClockTimeDiff *jitter); /* indexs */ gboolean gst_element_is_indexable (GstElement *element); void gst_element_set_index (GstElement *element, GstIndex *index); diff --git a/gst/gstpad.c b/gst/gstpad.c index 0c48aeef46..a59c9d6720 100644 --- a/gst/gstpad.c +++ b/gst/gstpad.c @@ -214,7 +214,7 @@ gst_real_pad_init (GstRealPad *pad) pad->formatsfunc = gst_pad_get_formats_default; pad->querytypefunc = gst_pad_get_query_types_default; - /* GST_FLAG_SET (pad, GST_PAD_DISABLED); */ + GST_FLAG_SET (pad, GST_PAD_DISABLED); gst_probe_dispatcher_init (&pad->probedisp); } @@ -2173,7 +2173,7 @@ gst_pad_push (GstPad *pad, GstBuffer *buf) } else { if (!GST_IS_EVENT (buf) && !GST_PAD_IS_ACTIVE (pad)) { - g_warning ("push on pad %s:%s but it is unusable", + g_warning ("push on pad %s:%s but it is not active", GST_DEBUG_PAD_NAME (pad)); return; } @@ -2233,6 +2233,7 @@ gst_pad_pull (GstPad *pad) else { if (peer->gethandler) { GstBuffer *buf; + gboolean active = GST_PAD_IS_ACTIVE (peer); GST_DEBUG (GST_CAT_DATAFLOW, "calling gethandler %s of peer pad %s:%s", GST_DEBUG_FUNCPTR_NAME (peer->gethandler), @@ -2244,6 +2245,11 @@ gst_pad_pull (GstPad *pad) if (!gst_probe_dispatcher_dispatch (&peer->probedisp, GST_DATA (buf))) return NULL; + if (!GST_IS_EVENT (buf) && !active) { + g_warning ("pull on pad %s:%s but it is not active", + GST_DEBUG_PAD_NAME (peer)); + return NULL; + } return buf; } @@ -2670,7 +2676,7 @@ gst_pad_event_default_dispatch (GstPad *pad, GstElement *element, /* for all pads in the opposite direction that are connected */ if (GST_PAD_DIRECTION (eventpad) != GST_PAD_DIRECTION (pad) - && GST_PAD_IS_USABLE (eventpad)) { + && GST_PAD_IS_CONNECTED (eventpad)) { if (GST_PAD_DIRECTION (eventpad) == GST_PAD_SRC) { /* increase the refcount */ gst_event_ref (event); @@ -2762,7 +2768,7 @@ gst_pad_dispatcher (GstPad *pad, GstPadDispatcherFunction dispatch, GstRealPad *int_rpad = GST_PAD_REALIZE (int_pads->data); GstRealPad *int_peer = GST_RPAD_PEER (int_rpad); - if (int_peer && GST_PAD_IS_USABLE (int_peer)) { + if (int_peer) { res = dispatch (GST_PAD_CAST (int_peer), data); if (res) break; @@ -2795,13 +2801,6 @@ gst_pad_send_event (GstPad *pad, GstEvent *event) rpad = GST_PAD_REALIZE (pad); - /* don't send events on usuable pads */ - if (GST_PAD_IS_SINK (rpad) && !GST_PAD_IS_ACTIVE (rpad)) { - GST_DEBUG (GST_CAT_EVENT, "pad %s:%s is not usable", - GST_DEBUG_PAD_NAME (rpad)); - return FALSE; - } - if (GST_EVENT_SRC (event) == NULL) GST_EVENT_SRC (event) = gst_object_ref (GST_OBJECT (rpad)); diff --git a/gst/gstscheduler.c b/gst/gstscheduler.c index 9e19b24ebb..b1775c29da 100644 --- a/gst/gstscheduler.c +++ b/gst/gstscheduler.c @@ -641,32 +641,29 @@ gst_scheduler_auto_clock (GstScheduler *sched) * gst_scheduler_clock_wait: * @sched: the scheduler * @element: the element that wants to wait - * @clock: the clock to use - * @time: the time to wait for + * @id: the clockid to use * @jitter: the time difference between requested time and actual time * - * Wait till the clock reaches a specific time + * Wait till the clock reaches a specific time. The ClockID can + * be obtained from #gst_clock_new_single_shot_id. * * Returns: the status of the operation */ GstClockReturn -gst_scheduler_clock_wait (GstScheduler *sched, GstElement *element, GstClock *clock, GstClockTime time, - GstClockTimeDiff *jitter) +gst_scheduler_clock_wait (GstScheduler *sched, GstElement *element, + GstClockID id, GstClockTimeDiff *jitter) { GstSchedulerClass *sclass; g_return_val_if_fail (GST_IS_SCHEDULER (sched), GST_CLOCK_ERROR); + g_return_val_if_fail (id != NULL, GST_CLOCK_ERROR); sclass = GST_SCHEDULER_GET_CLASS (sched); if (sclass->clock_wait) - return sclass->clock_wait (sched, element, clock, time, jitter); - else - { - GstClockID id = gst_clock_new_single_shot_id (clock, time); - + return sclass->clock_wait (sched, element, id, jitter); + else return gst_clock_id_wait (id, jitter); - } return GST_CLOCK_TIMEOUT; } diff --git a/gst/gstscheduler.h b/gst/gstscheduler.h index bcb83ee32a..99f4755a43 100644 --- a/gst/gstscheduler.h +++ b/gst/gstscheduler.h @@ -96,7 +96,7 @@ struct _GstSchedulerClass { void (*pad_disconnect) (GstScheduler *sched, GstPad *srcpad, GstPad *sinkpad); void (*pad_select) (GstScheduler *sched, GList *padlist); GstClockReturn (*clock_wait) (GstScheduler *sched, GstElement *element, - GstClock *clock, GstClockTime time, GstClockTimeDiff *jitter); + GstClockID id, GstClockTimeDiff *jitter); GstSchedulerState (*iterate) (GstScheduler *sched); /* for debugging */ void (*show) (GstScheduler *sched); @@ -130,7 +130,7 @@ void gst_scheduler_pad_connect (GstScheduler *sched, GstPad *srcpad, GstPad *s void gst_scheduler_pad_disconnect (GstScheduler *sched, GstPad *srcpad, GstPad *sinkpad); GstPad* gst_scheduler_pad_select (GstScheduler *sched, GList *padlist); GstClockReturn gst_scheduler_clock_wait (GstScheduler *sched, GstElement *element, - GstClock *clock, GstClockTime time, GstClockTimeDiff *jitter); + GstClockID id, GstClockTimeDiff *jitter); gboolean gst_scheduler_iterate (GstScheduler *sched); void gst_scheduler_use_clock (GstScheduler *sched, GstClock *clock); diff --git a/gst/gstsystemclock.c b/gst/gstsystemclock.c index e32f8aeff9..0297f57482 100644 --- a/gst/gstsystemclock.c +++ b/gst/gstsystemclock.c @@ -140,7 +140,7 @@ gst_system_clock_wait (GstClock *clock, GstClockEntry *entry) diff = GST_CLOCK_ENTRY_TIME (entry) - current; if (ABS (diff) > clock->max_diff) { - g_warning ("abnormal clock request diff: %lld > %lld", diff, clock->max_diff); + g_warning ("abnormal clock request diff: ABS(%lld) > %lld", diff, clock->max_diff); return GST_CLOCK_ENTRY_EARLY; } diff --git a/gst/schedulers/gstbasicscheduler.c b/gst/schedulers/gstbasicscheduler.c index e3118220d8..50352d9c88 100644 --- a/gst/schedulers/gstbasicscheduler.c +++ b/gst/schedulers/gstbasicscheduler.c @@ -123,7 +123,7 @@ static void gst_basic_scheduler_pad_connect (GstScheduler *sched, GstPad * static void gst_basic_scheduler_pad_disconnect (GstScheduler *sched, GstPad *srcpad, GstPad *sinkpad); static GstPad* gst_basic_scheduler_pad_select (GstScheduler *sched, GList *padlist); static GstClockReturn gst_basic_scheduler_clock_wait (GstScheduler *sched, GstElement *element, - GstClock *clock, GstClockTime time, GstClockTimeDiff *jitter); + GstClockID id, GstClockTimeDiff *jitter); static GstSchedulerState gst_basic_scheduler_iterate (GstScheduler *sched); @@ -1261,12 +1261,8 @@ gst_basic_scheduler_pad_select (GstScheduler * sched, GList * padlist) static GstClockReturn gst_basic_scheduler_clock_wait (GstScheduler *sched, GstElement *element, - GstClock *clock, GstClockTime time, GstClockTimeDiff *jitter) + GstClockID id, GstClockTimeDiff *jitter) { - GstClockID id; - - id = gst_clock_new_single_shot_id (clock, time); - return gst_clock_id_wait (id, jitter); } diff --git a/gst/schedulers/gstoptimalscheduler.c b/gst/schedulers/gstoptimalscheduler.c index 3fda03668a..390061c0f9 100644 --- a/gst/schedulers/gstoptimalscheduler.c +++ b/gst/schedulers/gstoptimalscheduler.c @@ -205,7 +205,7 @@ static void gst_opt_scheduler_pad_connect (GstScheduler *sched, GstPad *sr static void gst_opt_scheduler_pad_disconnect (GstScheduler *sched, GstPad *srcpad, GstPad *sinkpad); static GstPad* gst_opt_scheduler_pad_select (GstScheduler *sched, GList *padlist); static GstClockReturn gst_opt_scheduler_clock_wait (GstScheduler *sched, GstElement *element, - GstClock *clock, GstClockTime time, GstClockTimeDiff *jitter); + GstClockID id, GstClockTimeDiff *jitter); static GstSchedulerState gst_opt_scheduler_iterate (GstScheduler *sched); @@ -1496,12 +1496,8 @@ gst_opt_scheduler_pad_select (GstScheduler *sched, GList *padlist) static GstClockReturn gst_opt_scheduler_clock_wait (GstScheduler *sched, GstElement *element, - GstClock *clock, GstClockTime time, GstClockTimeDiff *jitter) + GstClockID id, GstClockTimeDiff *jitter) { - GstClockID id; - - id = gst_clock_new_single_shot_id (clock, time); - return gst_clock_id_wait (id, jitter); } diff --git a/plugins/elements/gstfakesink.c b/plugins/elements/gstfakesink.c index 20abe3913f..886cd065e3 100644 --- a/plugins/elements/gstfakesink.c +++ b/plugins/elements/gstfakesink.c @@ -282,7 +282,10 @@ gst_fakesink_chain (GstPad *pad, GstBuffer *buf) } if (fakesink->sync && fakesink->clock) { - gst_element_clock_wait (GST_ELEMENT (fakesink), fakesink->clock, GST_BUFFER_TIMESTAMP (buf), NULL); + GstClockID id = gst_clock_new_single_shot_id (fakesink->clock, GST_BUFFER_TIMESTAMP (buf)); + + gst_element_clock_wait (GST_ELEMENT (fakesink), id, NULL); + gst_clock_id_free (id); } if (!fakesink->silent) {