summaryrefslogtreecommitdiff
path: root/gst/gstscheduler.c
diff options
context:
space:
mode:
authorWim Taymans <wim.taymans@gmail.com>2002-03-30 17:05:03 +0000
committerWim Taymans <wim.taymans@gmail.com>2002-03-30 17:05:03 +0000
commitf0326eea5550d26d9d7640578db7780f5e67cad1 (patch)
tree41484534dee1e50c268010ab4b2ff0843927c7ee /gst/gstscheduler.c
parent2ed5aa240c2c7ceddf11f0121539e8e1422fa779 (diff)
downloadgstreamer-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.c214
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