- 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.
This commit is contained in:
Wim Taymans 2002-12-27 22:57:13 +00:00
parent 222b9c821b
commit a03425c8b3
10 changed files with 64 additions and 47 deletions

View file

@ -282,7 +282,10 @@ gst_fakesink_chain (GstPad *pad, GstBuffer *buf)
} }
if (fakesink->sync && fakesink->clock) { 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) { if (!fakesink->silent) {

View file

@ -749,8 +749,7 @@ gst_element_get_clock (GstElement *element)
/** /**
* gst_element_clock_wait: * gst_element_clock_wait:
* @element: a #GstElement. * @element: a #GstElement.
* @clock: the #GstClock to use. * @id: the #GstClock to use.
* @time: the #GstClockTime to wait for on the clock.
* @jitter: the difference between requested time and actual time. * @jitter: the difference between requested time and actual time.
* *
* Waits for a specific time on the clock. * 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. * Returns: the #GstClockReturn result of the wait operation.
*/ */
GstClockReturn 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; GstClockReturn res;
g_return_val_if_fail (GST_IS_ELEMENT (element), GST_CLOCK_ERROR); g_return_val_if_fail (GST_IS_ELEMENT (element), GST_CLOCK_ERROR);
if (GST_ELEMENT_SCHED (element)) { 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 else
res = GST_CLOCK_TIMEOUT; res = GST_CLOCK_TIMEOUT;
@ -1899,6 +1898,8 @@ gst_element_error (GstElement *element, const gchar *error, ...)
gst_scheduler_error (element->sched, element); gst_scheduler_error (element->sched, element);
} }
gst_element_set_state (element, GST_STATE_PAUSED);
/* cleanup */ /* cleanup */
gst_object_unref (GST_OBJECT (element)); gst_object_unref (GST_OBJECT (element));
g_free (string); 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 static GstElementStateReturn
gst_element_change_state (GstElement *element) gst_element_change_state (GstElement *element)
{ {
@ -2121,17 +2138,23 @@ gst_element_change_state (GstElement *element)
return GST_STATE_SUCCESS; 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_NAME (element),
gst_element_state_get_name (old_state), gst_element_state_get_name (old_state),
gst_element_state_get_name (old_pending), gst_element_state_get_name (old_pending),
GST_STATE_TRANSITION (element)); old_transition);
/* we set the state change early for the negotiation functions */ /* we set the state change early for the negotiation functions */
GST_STATE (element) = old_pending; GST_STATE (element) = old_pending;
GST_STATE_PENDING (element) = GST_STATE_VOID_PENDING; GST_STATE_PENDING (element) = GST_STATE_VOID_PENDING;
switch (old_transition) { 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 */ /* if we are going to paused, we try to negotiate the pads */
case GST_STATE_READY_TO_PAUSED: case GST_STATE_READY_TO_PAUSED:
if (!gst_element_negotiate_pads (element)) if (!gst_element_negotiate_pads (element))

View file

@ -226,8 +226,8 @@ gboolean gst_element_requires_clock (GstElement *element);
gboolean gst_element_provides_clock (GstElement *element); gboolean gst_element_provides_clock (GstElement *element);
GstClock* gst_element_get_clock (GstElement *element); GstClock* gst_element_get_clock (GstElement *element);
void gst_element_set_clock (GstElement *element, GstClock *clock); void gst_element_set_clock (GstElement *element, GstClock *clock);
GstClockReturn gst_element_clock_wait (GstElement *element, GstClock *clock, GstClockReturn gst_element_clock_wait (GstElement *element,
GstClockTime time, GstClockTimeDiff *jitter); GstClockID id, GstClockTimeDiff *jitter);
/* indexs */ /* indexs */
gboolean gst_element_is_indexable (GstElement *element); gboolean gst_element_is_indexable (GstElement *element);
void gst_element_set_index (GstElement *element, GstIndex *index); void gst_element_set_index (GstElement *element, GstIndex *index);

View file

@ -214,7 +214,7 @@ gst_real_pad_init (GstRealPad *pad)
pad->formatsfunc = gst_pad_get_formats_default; pad->formatsfunc = gst_pad_get_formats_default;
pad->querytypefunc = gst_pad_get_query_types_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); gst_probe_dispatcher_init (&pad->probedisp);
} }
@ -2173,7 +2173,7 @@ gst_pad_push (GstPad *pad, GstBuffer *buf)
} }
else { else {
if (!GST_IS_EVENT (buf) && !GST_PAD_IS_ACTIVE (pad)) { 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)); GST_DEBUG_PAD_NAME (pad));
return; return;
} }
@ -2233,6 +2233,7 @@ gst_pad_pull (GstPad *pad)
else { else {
if (peer->gethandler) { if (peer->gethandler) {
GstBuffer *buf; GstBuffer *buf;
gboolean active = GST_PAD_IS_ACTIVE (peer);
GST_DEBUG (GST_CAT_DATAFLOW, "calling gethandler %s of peer pad %s:%s", GST_DEBUG (GST_CAT_DATAFLOW, "calling gethandler %s of peer pad %s:%s",
GST_DEBUG_FUNCPTR_NAME (peer->gethandler), 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))) if (!gst_probe_dispatcher_dispatch (&peer->probedisp, GST_DATA (buf)))
return NULL; 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; 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 */ /* for all pads in the opposite direction that are connected */
if (GST_PAD_DIRECTION (eventpad) != GST_PAD_DIRECTION (pad) 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) { if (GST_PAD_DIRECTION (eventpad) == GST_PAD_SRC) {
/* increase the refcount */ /* increase the refcount */
gst_event_ref (event); 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_rpad = GST_PAD_REALIZE (int_pads->data);
GstRealPad *int_peer = GST_RPAD_PEER (int_rpad); 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); res = dispatch (GST_PAD_CAST (int_peer), data);
if (res) if (res)
break; break;
@ -2795,13 +2801,6 @@ gst_pad_send_event (GstPad *pad, GstEvent *event)
rpad = GST_PAD_REALIZE (pad); 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) if (GST_EVENT_SRC (event) == NULL)
GST_EVENT_SRC (event) = gst_object_ref (GST_OBJECT (rpad)); GST_EVENT_SRC (event) = gst_object_ref (GST_OBJECT (rpad));

View file

@ -641,32 +641,29 @@ gst_scheduler_auto_clock (GstScheduler *sched)
* gst_scheduler_clock_wait: * gst_scheduler_clock_wait:
* @sched: the scheduler * @sched: the scheduler
* @element: the element that wants to wait * @element: the element that wants to wait
* @clock: the clock to use * @id: the clockid to use
* @time: the time to wait for
* @jitter: the time difference between requested time and actual time * @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 * Returns: the status of the operation
*/ */
GstClockReturn GstClockReturn
gst_scheduler_clock_wait (GstScheduler *sched, GstElement *element, GstClock *clock, GstClockTime time, gst_scheduler_clock_wait (GstScheduler *sched, GstElement *element,
GstClockTimeDiff *jitter) GstClockID id, GstClockTimeDiff *jitter)
{ {
GstSchedulerClass *sclass; GstSchedulerClass *sclass;
g_return_val_if_fail (GST_IS_SCHEDULER (sched), GST_CLOCK_ERROR); 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); sclass = GST_SCHEDULER_GET_CLASS (sched);
if (sclass->clock_wait) if (sclass->clock_wait)
return sclass->clock_wait (sched, element, clock, time, jitter); return sclass->clock_wait (sched, element, id, jitter);
else else
{
GstClockID id = gst_clock_new_single_shot_id (clock, time);
return gst_clock_id_wait (id, jitter); return gst_clock_id_wait (id, jitter);
}
return GST_CLOCK_TIMEOUT; return GST_CLOCK_TIMEOUT;
} }

View file

@ -96,7 +96,7 @@ struct _GstSchedulerClass {
void (*pad_disconnect) (GstScheduler *sched, GstPad *srcpad, GstPad *sinkpad); void (*pad_disconnect) (GstScheduler *sched, GstPad *srcpad, GstPad *sinkpad);
void (*pad_select) (GstScheduler *sched, GList *padlist); void (*pad_select) (GstScheduler *sched, GList *padlist);
GstClockReturn (*clock_wait) (GstScheduler *sched, GstElement *element, GstClockReturn (*clock_wait) (GstScheduler *sched, GstElement *element,
GstClock *clock, GstClockTime time, GstClockTimeDiff *jitter); GstClockID id, GstClockTimeDiff *jitter);
GstSchedulerState (*iterate) (GstScheduler *sched); GstSchedulerState (*iterate) (GstScheduler *sched);
/* for debugging */ /* for debugging */
void (*show) (GstScheduler *sched); 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); void gst_scheduler_pad_disconnect (GstScheduler *sched, GstPad *srcpad, GstPad *sinkpad);
GstPad* gst_scheduler_pad_select (GstScheduler *sched, GList *padlist); GstPad* gst_scheduler_pad_select (GstScheduler *sched, GList *padlist);
GstClockReturn gst_scheduler_clock_wait (GstScheduler *sched, GstElement *element, 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); gboolean gst_scheduler_iterate (GstScheduler *sched);
void gst_scheduler_use_clock (GstScheduler *sched, GstClock *clock); void gst_scheduler_use_clock (GstScheduler *sched, GstClock *clock);

View file

@ -140,7 +140,7 @@ gst_system_clock_wait (GstClock *clock, GstClockEntry *entry)
diff = GST_CLOCK_ENTRY_TIME (entry) - current; diff = GST_CLOCK_ENTRY_TIME (entry) - current;
if (ABS (diff) > clock->max_diff) { 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; return GST_CLOCK_ENTRY_EARLY;
} }

View file

@ -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 void gst_basic_scheduler_pad_disconnect (GstScheduler *sched, GstPad *srcpad, GstPad *sinkpad);
static GstPad* gst_basic_scheduler_pad_select (GstScheduler *sched, GList *padlist); static GstPad* gst_basic_scheduler_pad_select (GstScheduler *sched, GList *padlist);
static GstClockReturn gst_basic_scheduler_clock_wait (GstScheduler *sched, GstElement *element, static GstClockReturn gst_basic_scheduler_clock_wait (GstScheduler *sched, GstElement *element,
GstClock *clock, GstClockTime time, GstClockTimeDiff *jitter); GstClockID id, GstClockTimeDiff *jitter);
static GstSchedulerState static GstSchedulerState
gst_basic_scheduler_iterate (GstScheduler *sched); gst_basic_scheduler_iterate (GstScheduler *sched);
@ -1261,12 +1261,8 @@ gst_basic_scheduler_pad_select (GstScheduler * sched, GList * padlist)
static GstClockReturn static GstClockReturn
gst_basic_scheduler_clock_wait (GstScheduler *sched, GstElement *element, 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); return gst_clock_id_wait (id, jitter);
} }

View file

@ -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 void gst_opt_scheduler_pad_disconnect (GstScheduler *sched, GstPad *srcpad, GstPad *sinkpad);
static GstPad* gst_opt_scheduler_pad_select (GstScheduler *sched, GList *padlist); static GstPad* gst_opt_scheduler_pad_select (GstScheduler *sched, GList *padlist);
static GstClockReturn gst_opt_scheduler_clock_wait (GstScheduler *sched, GstElement *element, static GstClockReturn gst_opt_scheduler_clock_wait (GstScheduler *sched, GstElement *element,
GstClock *clock, GstClockTime time, GstClockTimeDiff *jitter); GstClockID id, GstClockTimeDiff *jitter);
static GstSchedulerState static GstSchedulerState
gst_opt_scheduler_iterate (GstScheduler *sched); gst_opt_scheduler_iterate (GstScheduler *sched);
@ -1496,12 +1496,8 @@ gst_opt_scheduler_pad_select (GstScheduler *sched, GList *padlist)
static GstClockReturn static GstClockReturn
gst_opt_scheduler_clock_wait (GstScheduler *sched, GstElement *element, 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); return gst_clock_id_wait (id, jitter);
} }

View file

@ -282,7 +282,10 @@ gst_fakesink_chain (GstPad *pad, GstBuffer *buf)
} }
if (fakesink->sync && fakesink->clock) { 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) { if (!fakesink->silent) {