diff options
author | Wim Taymans <wim.taymans@gmail.com> | 2002-03-30 17:05:03 +0000 |
---|---|---|
committer | Wim Taymans <wim.taymans@gmail.com> | 2002-03-30 17:05:03 +0000 |
commit | f0326eea5550d26d9d7640578db7780f5e67cad1 (patch) | |
tree | 41484534dee1e50c268010ab4b2ff0843927c7ee /gst/gstscheduler.c | |
parent | 2ed5aa240c2c7ceddf11f0121539e8e1422fa779 (diff) | |
download | gstreamer-f0326eea5550d26d9d7640578db7780f5e67cad1.tar.gz |
- Remove the propsprivate header file
Original commit message from CVS:
- Remove the propsprivate header file
- Added new API for properties.
- Moved the clock distribution to the scheduler.
- Removed the lock from GstCaps
- Added boxed types for Caps/Props
- Simplified the clock, new systemclock implementation
- Removed deprecated element_info/send_event functions
- First step at exposing more info in the pad_connect functions
- Queue cleanup
- Make the scheduler aware of other schedulers inside it
- Added the _SELF_SCHEDULABLE flag to gstthread
- Removed _get_widget from _utils, changed to new props API
- Make fakesink sync on timestamps when requested
- Removed the offset notify from filesrc
- Added a fast scheduler
- some scheduler cleanups.
Diffstat (limited to 'gst/gstscheduler.c')
-rw-r--r-- | gst/gstscheduler.c | 214 |
1 files changed, 193 insertions, 21 deletions
diff --git a/gst/gstscheduler.c b/gst/gstscheduler.c index 9e7b7ffa3c..977f2c2471 100644 --- a/gst/gstscheduler.c +++ b/gst/gstscheduler.c @@ -24,6 +24,7 @@ #include "gst_private.h" +#include "gstsystemclock.h" #include "gstscheduler.h" static void gst_scheduler_class_init (GstSchedulerClass *klass); @@ -67,6 +68,13 @@ gst_scheduler_class_init (GstSchedulerClass *klass) static void gst_scheduler_init (GstScheduler *sched) { + sched->clock_providers = NULL; + sched->clock_receivers = NULL; + sched->schedulers = NULL; + sched->state = GST_SCHEDULER_STATE_NONE; + sched->parent = NULL; + sched->parent_sched = NULL; + sched->clock = NULL; } /** @@ -171,11 +179,48 @@ gst_scheduler_add_element (GstScheduler *sched, GstElement *element) g_return_if_fail (GST_IS_SCHEDULER (sched)); g_return_if_fail (GST_IS_ELEMENT (element)); + if (element->getclockfunc) { + sched->clock_providers = g_list_prepend (sched->clock_providers, element); + } + if (element->setclockfunc) { + sched->clock_receivers = g_list_prepend (sched->clock_receivers, element); + } + if (CLASS (sched)->add_element) CLASS (sched)->add_element (sched, element); } /** + * gst_scheduler_remove_element: + * @sched: the schedulerr + * @element: the element to remov + * + * Remove an element from the schedulerr. + */ +void +gst_scheduler_remove_element (GstScheduler *sched, GstElement *element) +{ + GList *pads; + + g_return_if_fail (GST_IS_SCHEDULER (sched)); + g_return_if_fail (GST_IS_ELEMENT (element)); + + sched->clock_providers = g_list_remove (sched->clock_providers, element); + sched->clock_receivers = g_list_remove (sched->clock_receivers, element); + + if (CLASS (sched)->remove_element) + CLASS (sched)->remove_element (sched, element); + + for (pads = element->pads; pads; pads = pads->next) { + GstPad *pad = GST_PAD (pads->data); + + if (GST_IS_REAL_PAD (pad)) { + gst_pad_unset_sched (GST_PAD (pads->data)); + } + } +} + +/** * gst_scheduler_state_transition: * @sched: the scheduler * @element: the element with the state transition @@ -192,39 +237,66 @@ gst_scheduler_state_transition (GstScheduler *sched, GstElement *element, gint t g_return_val_if_fail (GST_IS_SCHEDULER (sched), GST_STATE_FAILURE); g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_FAILURE); + if (element == sched->parent && sched->parent_sched == NULL) { + + switch (transition) { + case GST_STATE_READY_TO_PAUSED: + { + GstClock *clock = gst_scheduler_get_clock (sched); + + if (clock) + gst_clock_reset (clock); + + sched->current_clock = clock; + break; + } + case GST_STATE_PAUSED_TO_PLAYING: + { + gst_scheduler_set_clock (sched, sched->current_clock); + if (sched->current_clock) + gst_clock_activate (sched->current_clock, TRUE); + break; + } + case GST_STATE_PLAYING_TO_PAUSED: + if (sched->current_clock) + gst_clock_activate (sched->current_clock, FALSE); + break; + } + } + if (CLASS (sched)->state_transition) return CLASS (sched)->state_transition (sched, element, transition); return GST_STATE_SUCCESS; } -/** - * gst_scheduler_remove_element: - * @sched: the schedulerr - * @element: the element to remov - * - * Remove an element from the schedulerr. - */ void -gst_scheduler_remove_element (GstScheduler *sched, GstElement *element) +gst_scheduler_add_scheduler (GstScheduler *sched, GstScheduler *sched2) { - GList *pads; - g_return_if_fail (GST_IS_SCHEDULER (sched)); - g_return_if_fail (GST_IS_ELEMENT (element)); + g_return_if_fail (GST_IS_SCHEDULER (sched2)); - if (CLASS (sched)->remove_element) - CLASS (sched)->remove_element (sched, element); - - for (pads = element->pads; pads; pads = pads->next) { - GstPad *pad = GST_PAD (pads->data); - - if (GST_IS_REAL_PAD (pad)) { - gst_pad_unset_sched (GST_PAD (pads->data)); - } - } + sched->schedulers = g_list_prepend (sched->schedulers, sched2); + sched2->parent_sched = sched; + + if (CLASS (sched)->add_scheduler) + CLASS (sched)->add_scheduler (sched, sched2); } +void +gst_scheduler_remove_scheduler (GstScheduler *sched, GstScheduler *sched2) +{ + g_return_if_fail (GST_IS_SCHEDULER (sched)); + g_return_if_fail (GST_IS_SCHEDULER (sched2)); + + sched->schedulers = g_list_remove (sched->schedulers, sched2); + sched2->parent_sched = NULL; + + if (CLASS (sched)->remove_scheduler) + CLASS (sched)->remove_scheduler (sched, sched2); +} + + /** * gst_scheduler_lock_element: * @sched: the scheduler @@ -315,6 +387,106 @@ gst_scheduler_interrupt (GstScheduler *sched, GstElement *element) return FALSE; } +GstClock* +gst_scheduler_get_clock (GstScheduler *sched) +{ + GstClock *clock = NULL; + + if (GST_FLAG_IS_SET (sched, GST_SCHEDULER_FLAG_FIXED_CLOCK)) { + clock = sched->clock; + } + else { + if (sched->schedulers) { + GList *schedulers = sched->schedulers; + + while (schedulers) { + GstScheduler *scheduler = GST_SCHEDULER (schedulers->data); + + clock = gst_scheduler_get_clock (scheduler); + if (clock) + break; + + schedulers = g_list_next (schedulers); + } + } + if (!clock && sched->clock_providers) { + clock = gst_element_get_clock (GST_ELEMENT (sched->clock_providers->data)); + } + if (!clock && sched->parent_sched == NULL) { + clock = gst_system_clock_obtain (); + } + } + + return clock; +} + +void +gst_scheduler_use_clock (GstScheduler *sched, GstClock *clock) +{ + g_return_if_fail (sched != NULL); + g_return_if_fail (GST_IS_SCHEDULER (sched)); + + GST_FLAG_SET (sched, GST_SCHEDULER_FLAG_FIXED_CLOCK); + sched->clock = clock; +} + +void +gst_scheduler_set_clock (GstScheduler *sched, GstClock *clock) +{ + GList *receivers; + GList *schedulers; + + g_return_if_fail (sched != NULL); + g_return_if_fail (GST_IS_SCHEDULER (sched)); + + receivers = sched->clock_receivers; + schedulers = sched->schedulers; + + sched->current_clock = clock; + + while (receivers) { + GstElement *element = GST_ELEMENT (receivers->data); + + gst_element_set_clock (element, clock); + receivers = g_list_next (receivers); + } + while (schedulers) { + GstScheduler *scheduler = GST_SCHEDULER (schedulers->data); + + gst_scheduler_set_clock (scheduler, clock); + schedulers = g_list_next (schedulers); + } +} + +void +gst_scheduler_auto_clock (GstScheduler *sched) +{ + g_return_if_fail (sched != NULL); + g_return_if_fail (GST_IS_SCHEDULER (sched)); + + GST_FLAG_UNSET (sched, GST_SCHEDULER_FLAG_FIXED_CLOCK); + sched->clock = NULL; +} + +/** + * gst_scheduler_clock_wait: + * @sched: the scheduler + * + * Perform one iteration on the schedulerr. + * + * Returns: a boolean indicating something usefull has happened. + */ +GstClockReturn +gst_scheduler_clock_wait (GstScheduler *sched, GstElement *element, GstClock *clock, GstClockTime time) +{ + g_return_val_if_fail (GST_IS_SCHEDULER (sched), GST_CLOCK_ERROR); + + if (CLASS (sched)->clock_wait) + return CLASS (sched)->clock_wait (sched, element, clock, time); + + return GST_CLOCK_TIMEOUT; +} + /** * gst_scheduler_iterate: * @sched: the scheduler |