From f0326eea5550d26d9d7640578db7780f5e67cad1 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Sat, 30 Mar 2002 17:05:03 +0000 Subject: - 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. --- gst/gstscheduler.c | 214 +++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 193 insertions(+), 21 deletions(-) (limited to 'gst/gstscheduler.c') 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,10 +179,47 @@ 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 @@ -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 -- cgit v1.2.1