Commit a03425c8 authored by Wim Taymans's avatar Wim Taymans

- disable pads when going to PAUSED, we want to make sure no data is passing...

- disable pads when going to PAUSED, we want to make sure no data is passing when an element is not PLAYING.

Original commit message from CVS:
- disable pads when going to PAUSED, we want to make sure no data is
passing when an element is not PLAYING.
- changed the clock sync API, element should now get a ClockID first and
sync on that. This makes it possible to cancel clock requests.
parent 222b9c82
......@@ -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) {
......
......@@ -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))
......
......@@ -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);
......
......@@ -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));
......
......@@ -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;
}
......
......@@ -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);
......
......@@ -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;
}
......
......@@ -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);
}
......
......@@ -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);
}
......
......@@ -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) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment