A very small change to make eos somewhat work. no inner bins are checked.
authorWim Taymans <wim.taymans@gmail.com>
Sat, 20 Jan 2001 03:10:44 +0000 (03:10 +0000)
committerWim Taymans <wim.taymans@gmail.com>
Sat, 20 Jan 2001 03:10:44 +0000 (03:10 +0000)
Original commit message from CVS:
A very small change to make eos somewhat work. no inner bins are checked.
When an element fires EOS, the chain with that element is removed from
the scheduler (marked inactive). If all chains are inactive, the bin
fires EOS.

gst/cothreads.c
gst/gstbin.c
gst/gstbin.h
gst/gstelement.c
gst/gstelement.h
gst/gstpad.c
gst/gstscheduler.c

index 1c54093ac29c474cf49b703233c438c3ba79d9b8..8a938f1dffe6ec9d8ca0bc5db399a457083d18e9 100644 (file)
@@ -263,7 +263,7 @@ cothread_switch (cothread_state *thread)
   if (current == thread) goto selfswitch;
 
   // find the number of the thread to switch to
-  GST_INFO (GST_CAT_COTHREAD_SWITCH,"switching from cothread %d to to cothread #%d\n",
+  GST_INFO (GST_CAT_COTHREAD_SWITCH,"switching from cothread %d to to cothread #%d",
             ctx->current,thread->threadnum);
   ctx->current = thread->threadnum;
 
index ac657f897d09a09dbfb914ca0236abb31a43eca2..0e74010b6ec337a4bc105374e725b2800d174d05 100644 (file)
@@ -30,7 +30,7 @@
 
 
 
-GstElementDetails gst_bin_details = { 
+GstElementDetails gst_bin_details = {
   "Generic bin",
   "Bin",
   "Simple container object",
@@ -40,19 +40,19 @@ GstElementDetails gst_bin_details = {
 };
 
 
-static void                    gst_bin_real_destroy            (GtkObject *object);
+static void                    gst_bin_real_destroy            (GtkObject *object);
 
-static GstElementStateReturn   gst_bin_change_state            (GstElement *element);
-static GstElementStateReturn   gst_bin_change_state_norecurse  (GstBin *bin);
-static gboolean                gst_bin_change_state_type       (GstBin *bin,
-                                                                GstElementState state,
-                                                                GtkType type);
+static GstElementStateReturn   gst_bin_change_state            (GstElement *element);
+static GstElementStateReturn   gst_bin_change_state_norecurse  (GstBin *bin);
+static gboolean                        gst_bin_change_state_type       (GstBin *bin,
+                                                                GstElementState state,
+                                                                GtkType type);
 
-static void                    gst_bin_create_plan_func        (GstBin *bin);
-static void                    gst_bin_iterate_func            (GstBin *bin);
+static void                    gst_bin_create_plan_func        (GstBin *bin);
+static void                    gst_bin_iterate_func            (GstBin *bin);
 
-static xmlNodePtr              gst_bin_save_thyself            (GstElement *element, xmlNodePtr parent);
-static void                    gst_bin_restore_thyself         (GstElement *element, xmlNodePtr parent, 
+static xmlNodePtr              gst_bin_save_thyself            (GstElement *element, xmlNodePtr parent);
+static void                    gst_bin_restore_thyself         (GstElement *element, xmlNodePtr parent,
                                                                 GHashTable *elements);
 
 /* Bin signals and args */
@@ -75,7 +75,7 @@ static GstElementClass *parent_class = NULL;
 static guint gst_bin_signals[LAST_SIGNAL] = { 0 };
 
 GtkType
-gst_bin_get_type (void) 
+gst_bin_get_type (void)
 {
   static GtkType bin_type = 0;
 
@@ -96,7 +96,7 @@ gst_bin_get_type (void)
 }
 
 static void
-gst_bin_class_init (GstBinClass *klass) 
+gst_bin_class_init (GstBinClass *klass)
 {
   GtkObjectClass *gtkobject_class;
   GstElementClass *gstelement_class;
@@ -113,20 +113,20 @@ gst_bin_class_init (GstBinClass *klass)
                     GST_TYPE_ELEMENT);
   gtk_object_class_add_signals (gtkobject_class, gst_bin_signals, LAST_SIGNAL);
 
-  klass->change_state_type =           gst_bin_change_state_type;
-  klass->create_plan =                         gst_bin_create_plan_func;
-  klass->schedule =                    gst_bin_schedule_func;
-  klass->iterate =                     gst_bin_iterate_func;
+  klass->change_state_type =           gst_bin_change_state_type;
+  klass->create_plan =                 gst_bin_create_plan_func;
+  klass->schedule =                    gst_bin_schedule_func;
+  klass->iterate =                     gst_bin_iterate_func;
 
-  gstelement_class->change_state =     gst_bin_change_state;
-  gstelement_class->save_thyself =     gst_bin_save_thyself;
-  gstelement_class->restore_thyself =  gst_bin_restore_thyself;
+  gstelement_class->change_state =     gst_bin_change_state;
+  gstelement_class->save_thyself =     gst_bin_save_thyself;
+  gstelement_class->restore_thyself =  gst_bin_restore_thyself;
 
-  gtkobject_class->destroy =           gst_bin_real_destroy;
+  gtkobject_class->destroy =           gst_bin_real_destroy;
 }
 
-static void 
-gst_bin_init (GstBin *bin) 
+static void
+gst_bin_init (GstBin *bin)
 {
   // in general, we prefer to use cothreads for most things
   GST_FLAG_SET (bin, GST_BIN_FLAG_PREFER_COTHREADS);
@@ -148,7 +148,7 @@ gst_bin_init (GstBin *bin)
  * Returns: new bin
  */
 GstElement*
-gst_bin_new (const gchar *name) 
+gst_bin_new (const gchar *name)
 {
   return gst_elementfactory_make ("bin", name);
 }
@@ -161,9 +161,9 @@ gst_bin_new (const gchar *name)
  * Add the given element to the bin.  Set the elements parent, and thus
  * add a reference.
  */
-void 
-gst_bin_add (GstBin *bin, 
-            GstElement *element) 
+void
+gst_bin_add (GstBin *bin,
+            GstElement *element)
 {
   g_return_if_fail (bin != NULL);
   g_return_if_fail (GST_IS_BIN (bin));
@@ -194,9 +194,9 @@ gst_bin_add (GstBin *bin,
  *
  * Remove the element from its associated bin, unparenting as well.
  */
-void 
+void
 gst_bin_remove (GstBin *bin,
-               GstElement *element) 
+               GstElement *element)
 {
   g_return_if_fail (bin != NULL);
   g_return_if_fail (GST_IS_BIN (bin));
@@ -226,8 +226,8 @@ gst_bin_remove (GstBin *bin,
 }
 
 
-static GstElementStateReturn 
-gst_bin_change_state (GstElement *element) 
+static GstElementStateReturn
+gst_bin_change_state (GstElement *element)
 {
   GstBin *bin;
   GList *children;
@@ -271,7 +271,7 @@ gst_bin_change_state (GstElement *element)
 //  g_print("<-- \"%s\"\n",gst_object_get_name(GST_OBJECT(bin)));
 
   switch (GST_STATE_TRANSITION (element)) {
-    case GST_STATE_NULL_TO_READY:        
+    case GST_STATE_NULL_TO_READY:
     {
       GstObject *parent;
 
@@ -290,8 +290,8 @@ gst_bin_change_state (GstElement *element)
 }
 
 
-static GstElementStateReturn 
-gst_bin_change_state_norecurse (GstBin *bin) 
+static GstElementStateReturn
+gst_bin_change_state_norecurse (GstBin *bin)
 {
 
   if (GST_ELEMENT_CLASS (parent_class)->change_state)
@@ -300,10 +300,10 @@ gst_bin_change_state_norecurse (GstBin *bin)
     return GST_STATE_FAILURE;
 }
 
-static gboolean 
+static gboolean
 gst_bin_change_state_type(GstBin *bin,
                           GstElementState state,
-                          GtkType type) 
+                          GtkType type)
 {
   GList *children;
   GstElement *child;
@@ -344,10 +344,10 @@ gst_bin_change_state_type(GstBin *bin,
  *
  * Returns: indication if the state change was successfull
  */
-gboolean 
+gboolean
 gst_bin_set_state_type (GstBin *bin,
                         GstElementState state,
-                        GtkType type) 
+                        GtkType type)
 {
   GstBinClass *oclass;
 
@@ -364,8 +364,8 @@ gst_bin_set_state_type (GstBin *bin,
   return TRUE;
 }
 
-static void 
-gst_bin_real_destroy (GtkObject *object) 
+static void
+gst_bin_real_destroy (GtkObject *object)
 {
   GstBin *bin = GST_BIN (object);
   GList *children;
@@ -394,7 +394,7 @@ gst_bin_real_destroy (GtkObject *object)
  */
 GstElement*
 gst_bin_get_by_name (GstBin *bin,
-                    const gchar *name) 
+                    const gchar *name)
 {
   GList *children;
   GstElement *child;
@@ -412,7 +412,7 @@ gst_bin_get_by_name (GstBin *bin,
       return child;
     if (GST_IS_BIN (child)) {
       GstElement *res = gst_bin_get_by_name (GST_BIN (child), name);
-      if (res) 
+      if (res)
         return res;
     }
     children = g_list_next (children);
@@ -430,7 +430,7 @@ gst_bin_get_by_name (GstBin *bin,
  * Returns: a GList of elements
  */
 GList*
-gst_bin_get_list (GstBin *bin) 
+gst_bin_get_list (GstBin *bin)
 {
   g_return_val_if_fail (bin != NULL, NULL);
   g_return_val_if_fail (GST_IS_BIN (bin), NULL);
@@ -438,9 +438,9 @@ gst_bin_get_list (GstBin *bin)
   return bin->children;
 }
 
-static xmlNodePtr 
-gst_bin_save_thyself (GstElement *element, 
-                     xmlNodePtr parent) 
+static xmlNodePtr
+gst_bin_save_thyself (GstElement *element,
+                     xmlNodePtr parent)
 {
   GstBin *bin = GST_BIN (element);
   xmlNodePtr childlist;
@@ -463,10 +463,10 @@ gst_bin_save_thyself (GstElement *element,
   return childlist;
 }
 
-static void 
-gst_bin_restore_thyself (GstElement *element, 
-                        xmlNodePtr parent, 
-                        GHashTable *elements) 
+static void
+gst_bin_restore_thyself (GstElement *element,
+                        xmlNodePtr parent,
+                        GHashTable *elements)
 {
   GstBin *bin = GST_BIN (element);
   xmlNodePtr field = parent->xmlChildrenNode;
@@ -490,12 +490,12 @@ gst_bin_restore_thyself (GstElement *element,
 
     field = field->next;
   }
-  
+
 }
 
-void 
-gst_bin_use_cothreads (GstBin *bin, 
-                      gboolean enabled) 
+void
+gst_bin_use_cothreads (GstBin *bin,
+                      gboolean enabled)
 {
   g_return_if_fail (GST_IS_BIN (bin));
 
@@ -508,15 +508,15 @@ gst_bin_use_cothreads (GstBin *bin,
  *
  * Iterates over the elements in this bin.
  */
-void 
-gst_bin_iterate (GstBin *bin) 
+void
+gst_bin_iterate (GstBin *bin)
 {
   GstBinClass *oclass;
 
   GST_DEBUG_ENTER("(\"%s\")",gst_element_get_name(GST_ELEMENT(bin)));
 
   oclass = GST_BIN_CLASS (GTK_OBJECT (bin)->klass);
-  
+
   if (oclass->iterate)
     (oclass->iterate) (bin);
 
@@ -529,8 +529,8 @@ gst_bin_iterate (GstBin *bin)
  *
  * Let the bin figure out how to handle its children.
  */
-void 
-gst_bin_create_plan (GstBin *bin) 
+void
+gst_bin_create_plan (GstBin *bin)
 {
   GstBinClass *oclass;
 
@@ -546,8 +546,8 @@ gst_bin_create_plan (GstBin *bin)
  *
  * Let the bin figure out how to handle its children.
  */
-void 
-gst_bin_schedule (GstBin *bin) 
+void
+gst_bin_schedule (GstBin *bin)
 {
   GstBinClass *oclass;
 
@@ -560,11 +560,11 @@ gst_bin_schedule (GstBin *bin)
 typedef struct {
   gulong offset;
   gulong size;
-} region_struct; 
+} region_struct;
 
 
 static void
-gst_bin_create_plan_func (GstBin *bin) 
+gst_bin_create_plan_func (GstBin *bin)
 {
   GstElement *manager;
   GList *elements;
@@ -701,8 +701,8 @@ gst_bin_create_plan_func (GstBin *bin)
   GST_DEBUG_LEAVE("(\"%s\")",gst_element_get_name(GST_ELEMENT(bin)));
 }
 
-static void 
-gst_bin_iterate_func (GstBin *bin) 
+static void
+gst_bin_iterate_func (GstBin *bin)
 {
   GList *chains;
   _GstBinChain *chain;
@@ -711,6 +711,7 @@ gst_bin_iterate_func (GstBin *bin)
   GList *pads;
   GstPad *pad;
   GstBuffer *buf = NULL;
+  gint num_scheduled = 0;
 
   GST_DEBUG_ENTER("(\"%s\")", gst_element_get_name (GST_ELEMENT (bin)));
 
@@ -724,6 +725,8 @@ gst_bin_iterate_func (GstBin *bin)
     chain = (_GstBinChain *)(chains->data);
     chains = g_list_next (chains);
 
+    if (!chain->need_scheduling) continue;
+
     if (chain->need_cothreads) {
       // all we really have to do is switch to the first child
       // FIXME this should be lots more intelligent about where to start
@@ -756,7 +759,7 @@ gst_bin_iterate_func (GstBin *bin)
             pad = GST_PAD (pads->data);
             if (GST_RPAD_DIRECTION(pad) == GST_PAD_SRC) {
               GST_DEBUG (0,"calling getfunc of %s:%s\n",GST_DEBUG_PAD_NAME(pad));
-              if (GST_REAL_PAD(pad)->getfunc == NULL) 
+              if (GST_REAL_PAD(pad)->getfunc == NULL)
                 fprintf(stderr, "error, no getfunc in \"%s\"\n", gst_element_get_name (entry));
               else
                 buf = (GST_REAL_PAD(pad)->getfunc)(pad);
@@ -767,33 +770,13 @@ gst_bin_iterate_func (GstBin *bin)
         }
       }
     }
+    num_scheduled++;
   }
 
-  GST_DEBUG_LEAVE("(%s)", gst_element_get_name (GST_ELEMENT (bin)));
-}
-
-static void
-gst_bin_eos_func (GstBin *bin, GstElement *element)
-{
-  gst_element_signal_eos (GST_ELEMENT (bin));
-}
-
-void
-gst_bin_add_eos_provider (GstBin *bin, GstElement *element) 
-{
-  g_return_if_fail (bin != NULL);
-  g_return_if_fail (GST_IS_BIN (bin));
-  
-  bin->eos_providers = g_list_prepend (bin->eos_providers, element);
-  gtk_signal_connect_object (GTK_OBJECT (element), "eos", gst_bin_eos_func, GTK_OBJECT (bin));
-}
-
-void
-gst_bin_remove_eos_provider (GstBin *bin, GstElement *element) 
-{
-  g_return_if_fail (bin != NULL);
-  g_return_if_fail (GST_IS_BIN (bin));
+  if (!num_scheduled) {
+    gst_element_signal_eos (GST_ELEMENT (bin));
+  }
 
-  bin->eos_providers = g_list_remove (bin->eos_providers, element);
+  GST_DEBUG_LEAVE("(%s)", gst_element_get_name (GST_ELEMENT (bin)));
 }
 
index cb04dfe8e0504924cfff4916f34f668245c5afd5..077a1a3a2dd737d7e905cf3a88c26db20c948767 100644 (file)
@@ -86,18 +86,18 @@ struct _GstBinClass {
   GstElementClass parent_class;
 
   /* signals */
-  void                 (*object_added)         (GstObject *object, GstObject *child);
-  void                 (*object_removed)       (GstObject *object, GstObject *child);
+  void         (*object_added)         (GstObject *object, GstObject *child);
+  void         (*object_removed)       (GstObject *object, GstObject *child);
 
   /* change the state of elements of the given type */
-  gboolean     (*change_state_type)    (GstBin *bin,
-                                        GstElementState state,
-                                        GtkType type);
+  gboolean     (*change_state_type)    (GstBin *bin,
+                                        GstElementState state,
+                                        GtkType type);
   /* create a plan for the execution of the bin */
-  void                 (*create_plan)          (GstBin *bin);
-  void                 (*schedule)             (GstBin *bin);
+  void         (*create_plan)          (GstBin *bin);
+  void         (*schedule)             (GstBin *bin);
   /* run a full iteration of operation */
-  void         (*iterate)              (GstBin *bin);
+  void         (*iterate)              (GstBin *bin);
 };
 
 struct __GstBinChain {
@@ -107,22 +107,18 @@ struct __GstBinChain {
   GList *entries;
 
   gboolean need_cothreads;
-};  
+  gboolean need_scheduling;
+};
 
 
-GtkType        gst_bin_get_type                (void);
+GtkType                gst_bin_get_type                (void);
 GstElement*    gst_bin_new                     (const gchar *name);
-#define        gst_bin_destroy(bin)            gst_object_destroy(GST_OBJECT(bin))
+#define                gst_bin_destroy(bin)            gst_object_destroy(GST_OBJECT(bin))
 
 /* add and remove elements from the bin */
-void           gst_bin_add                     (GstBin *bin,
-                                                GstElement *element);
-void           gst_bin_remove                  (GstBin *bin,
-                                                GstElement *element);
-
-void           gst_bin_add_eos_provider        (GstBin *bin,
+void           gst_bin_add                     (GstBin *bin,
                                                 GstElement *element);
-void           gst_bin_remove_eos_provider     (GstBin *bin,
+void           gst_bin_remove                  (GstBin *bin,
                                                 GstElement *element);
 
 /* retrieve a single element or the list of children */
@@ -130,16 +126,16 @@ GstElement*       gst_bin_get_by_name             (GstBin *bin,
                                                 const gchar *name);
 GList*         gst_bin_get_list                (GstBin *bin);
 
-void           gst_bin_create_plan             (GstBin *bin);
-void           gst_bin_schedule                (GstBin *bin);
-gboolean       gst_bin_set_state_type          (GstBin *bin,
+void           gst_bin_create_plan             (GstBin *bin);
+void           gst_bin_schedule                (GstBin *bin);
+gboolean       gst_bin_set_state_type          (GstBin *bin,
                                                 GstElementState state,
                                                 GtkType type);
 
-void           gst_bin_iterate                 (GstBin *bin);
+void           gst_bin_iterate                 (GstBin *bin);
 
 /* hack FIXME */
-void           gst_bin_use_cothreads           (GstBin *bin,
+void           gst_bin_use_cothreads           (GstBin *bin,
                                                 gboolean enabled);
 
 #ifdef __cplusplus
@@ -147,5 +143,5 @@ void                gst_bin_use_cothreads           (GstBin *bin,
 #endif /* __cplusplus */
 
 
-#endif /* __GST_BIN_H__ */     
+#endif /* __GST_BIN_H__ */
 
index 9f80b434cdd91d852a37d741030a74d0551cccaa..835a181fad9ea99f6f182bf1fd1cc8472eff6dbc 100644 (file)
@@ -73,8 +73,8 @@ GtkType gst_element_get_type(void) {
   return element_type;
 }
 
-static void 
-gst_element_class_init (GstElementClass *klass) 
+static void
+gst_element_class_init (GstElementClass *klass)
 {
   GtkObjectClass *gtkobject_class;
 
@@ -116,8 +116,8 @@ gst_element_class_init (GstElementClass *klass)
   gtkobject_class->destroy = gst_element_real_destroy;
 }
 
-static void 
-gst_element_init (GstElement *element) 
+static void
+gst_element_init (GstElement *element)
 {
   element->current_state = GST_STATE_NULL;
   element->pending_state = -1;
@@ -137,7 +137,7 @@ gst_element_init (GstElement *element)
  * Returns: new element
  */
 GstElement*
-gst_element_new(void) 
+gst_element_new(void)
 {
   return GST_ELEMENT (gtk_type_new (GST_TYPE_ELEMENT));
 }
@@ -150,8 +150,8 @@ gst_element_new(void)
  * Add a pad (connection point) to the element, setting the parent of the
  * pad to the element (and thus adding a reference).
  */
-void 
-gst_element_add_pad (GstElement *element, GstPad *pad) 
+void
+gst_element_add_pad (GstElement *element, GstPad *pad)
 {
   g_return_if_fail (element != NULL);
   g_return_if_fail (GST_IS_ELEMENT (element));
@@ -184,8 +184,8 @@ gst_element_add_pad (GstElement *element, GstPad *pad)
  * Create a ghost pad from the given pad, and add it to the list of pads
  * for this element.
  */
-void 
-gst_element_add_ghost_pad (GstElement *element, GstPad *pad, gchar *name) 
+void
+gst_element_add_ghost_pad (GstElement *element, GstPad *pad, gchar *name)
 {
   GstPad *ghostpad;
 
@@ -216,7 +216,7 @@ gst_element_add_ghost_pad (GstElement *element, GstPad *pad, gchar *name)
  * @pad: ghost pad to remove
  *
  * removes a ghost pad from an element
- * 
+ *
  */
 void
 gst_element_remove_ghost_pad (GstElement *element, GstPad *pad)
@@ -240,7 +240,7 @@ gst_element_remove_ghost_pad (GstElement *element, GstPad *pad)
  * Returns: requested pad if found, otherwise NULL.
  */
 GstPad*
-gst_element_get_pad (GstElement *element, const gchar *name) 
+gst_element_get_pad (GstElement *element, const gchar *name)
 {
   GList *walk;
 
@@ -278,7 +278,7 @@ gst_element_get_pad (GstElement *element, const gchar *name)
  * Returns: GList of pads
  */
 GList*
-gst_element_get_pad_list (GstElement *element) 
+gst_element_get_pad_list (GstElement *element)
 {
   g_return_val_if_fail (element != NULL, NULL);
   g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
@@ -416,9 +416,9 @@ gst_element_request_pad_by_name (GstElement *element, const gchar *name)
  * child of the parent of the other element.  If they have different
  * parents, the connection fails.
  */
-void 
+void
 gst_element_connect (GstElement *src, const gchar *srcpadname,
-                     GstElement *dest, const gchar *destpadname) 
+                     GstElement *dest, const gchar *destpadname)
 {
   GstPad *srcpad,*destpad;
   GstObject *srcparent,*destparent;
@@ -466,9 +466,9 @@ gst_element_connect (GstElement *src, const gchar *srcpadname,
  *
  * Disconnect the two named pads of the source and destination elements.
  */
-void 
+void
 gst_element_disconnect (GstElement *src, const gchar *srcpadname,
-                        GstElement *dest, const gchar *destpadname) 
+                        GstElement *dest, const gchar *destpadname)
 {
   GstPad *srcpad,*destpad;
 
@@ -503,8 +503,8 @@ gst_element_disconnect (GstElement *src, const gchar *srcpadname,
  * This function is used internally by elements to signal an error
  * condition.  It results in the "error" signal.
  */
-void 
-gst_element_error (GstElement *element, const gchar *error) 
+void
+gst_element_error (GstElement *element, const gchar *error)
 {
   g_error("GstElement: error in element '%s': %s\n", element->name, error);
 
@@ -524,8 +524,8 @@ gst_element_error (GstElement *element, const gchar *error)
  *
  * Returns: whether or not the state was successfully set.
  */
-gint 
-gst_element_set_state (GstElement *element, GstElementState state) 
+gint
+gst_element_set_state (GstElement *element, GstElementState state)
 {
   GstElementClass *oclass;
   GstElementState curpending;
@@ -576,13 +576,13 @@ gst_element_set_state (GstElement *element, GstElementState state)
  * Returns: the factory used for creating this element
  */
 GstElementFactory*
-gst_element_get_factory (GstElement *element) 
+gst_element_get_factory (GstElement *element)
 {
   GstElementClass *oclass;
 
   g_return_val_if_fail (element != NULL, NULL);
   g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
-  
+
   oclass = GST_ELEMENT_CLASS (GTK_OBJECT (element)->klass);
 
   return oclass->elementfactory;
@@ -593,13 +593,13 @@ gst_element_get_factory (GstElement *element)
  * @element: element to change state of
  *
  * Changes the state of the element, but more importantly fires off a signal
- * indicating the new state.  
+ * indicating the new state.
  * The element will have no pending states anymore.
  *
  * Returns: whether or not the state change was successfully set.
  */
-GstElementStateReturn 
-gst_element_change_state (GstElement *element) 
+GstElementStateReturn
+gst_element_change_state (GstElement *element)
 {
   g_return_val_if_fail (element != NULL, GST_STATE_FAILURE);
   g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_FAILURE);
@@ -623,8 +623,8 @@ gst_element_change_state (GstElement *element)
  * Set the name of the element, getting rid of the old name if there was
  * one.
  */
-void 
-gst_element_set_name (GstElement *element, const gchar *name) 
+void
+gst_element_set_name (GstElement *element, const gchar *name)
 {
   g_return_if_fail (element != NULL);
   g_return_if_fail (GST_IS_ELEMENT (element));
@@ -645,7 +645,7 @@ gst_element_set_name (GstElement *element, const gchar *name)
  * Returns: name of the element
  */
 const gchar*
-gst_element_get_name (GstElement *element) 
+gst_element_get_name (GstElement *element)
 {
   g_return_val_if_fail (element != NULL, NULL);
   g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
@@ -653,8 +653,8 @@ gst_element_get_name (GstElement *element)
   return element->name;
 }
 
-static void 
-gst_element_real_destroy (GtkObject *object) 
+static void
+gst_element_real_destroy (GtkObject *object)
 {
   GstElement *element = GST_ELEMENT (object);
   GList *pads;
@@ -664,7 +664,7 @@ gst_element_real_destroy (GtkObject *object)
 
   if (element->name)
     g_free (element->name);
-  
+
   pads = element->pads;
   while (pads) {
     pad = GST_PAD (pads->data);
@@ -701,9 +701,9 @@ static gchar *_gst_element_type_names[] = {
  *
  * Returns: the new xml node
  */
-xmlNodePtr 
+xmlNodePtr
 gst_element_save_thyself (GstElement *element,
-                         xmlNodePtr parent) 
+                         xmlNodePtr parent)
 {
   xmlNodePtr self;
   GList *pads;
@@ -730,7 +730,7 @@ gst_element_save_thyself (GstElement *element,
     guint num_args,i;
 
     args = gtk_object_query_args (type, &flags, &num_args);
-    
+
     for (i=0; i<num_args; i++) {
       if ((args[i].type > GTK_TYPE_NONE) &&
           //(args[i].type <= GTK_TYPE_STRING) &&
@@ -814,8 +814,8 @@ gst_element_save_thyself (GstElement *element,
  * Returns: the new element
  */
 GstElement*
-gst_element_load_thyself (xmlNodePtr parent, 
-                         GHashTable *elements) 
+gst_element_load_thyself (xmlNodePtr parent,
+                         GHashTable *elements)
 {
   xmlNodePtr children = parent->xmlChildrenNode;
   GstElement *element;
@@ -844,7 +844,7 @@ gst_element_load_thyself (xmlNodePtr parent,
 
   g_hash_table_insert (elements, g_strdup (gst_element_get_name (element)), element);
 
-  // we have the element now, set the arguments 
+  // we have the element now, set the arguments
   children = parent->xmlChildrenNode;
 
   while (children) {
@@ -879,49 +879,49 @@ gst_element_load_thyself (xmlNodePtr parent,
              gint i;
              sscanf (value, "%d", &i);
               gtk_object_set (GTK_OBJECT (element), name, i, NULL);
-             break; 
+             break;
            }
             case GTK_TYPE_LONG: {
              glong i;
              sscanf (value, "%ld", &i);
               gtk_object_set (GTK_OBJECT (element), name, i, NULL);
-             break; 
+             break;
            }
             case GTK_TYPE_ULONG: {
              gulong i;
              sscanf (value, "%lu", &i);
               gtk_object_set (GTK_OBJECT (element), name, i, NULL);
-             break; 
+             break;
            }
             case GTK_TYPE_BOOL: {
              gboolean i = FALSE;
              if (!strcmp ("true", value)) i = TRUE;
               gtk_object_set (GTK_OBJECT (element), name, i, NULL);
-             break; 
+             break;
            }
             case GTK_TYPE_CHAR: {
              gchar i;
              sscanf (value, "%c", &i);
               gtk_object_set (GTK_OBJECT (element), name, i, NULL);
-             break; 
+             break;
            }
             case GTK_TYPE_UCHAR: {
              guchar i;
              sscanf (value, "%c", &i);
               gtk_object_set (GTK_OBJECT (element), name, i, NULL);
-             break; 
+             break;
            }
             case GTK_TYPE_FLOAT: {
              gfloat i;
              sscanf (value, "%f", &i);
               gtk_object_set (GTK_OBJECT (element), name, i, NULL);
-             break; 
+             break;
            }
             case GTK_TYPE_DOUBLE: {
              gdouble i;
              sscanf (value, "%g", (float *)&i);
               gtk_object_set (GTK_OBJECT (element), name, i, NULL);
-             break; 
+             break;
            }
             default:
              if (info->type == GST_TYPE_FILENAME) {
@@ -960,9 +960,9 @@ gst_element_load_thyself (xmlNodePtr parent,
  * Sets the manager of the element.  For internal use only, unless you're
  * writing a new bin subclass.
  */
-void 
+void
 gst_element_set_manager (GstElement *element,
-                        GstElement *manager) 
+                        GstElement *manager)
 {
   element->manager = manager;
 }
@@ -976,7 +976,7 @@ gst_element_set_manager (GstElement *element,
  * Returns: Element's manager
  */
 GstElement*
-gst_element_get_manager (GstElement *element) 
+gst_element_get_manager (GstElement *element)
 {
   return element->manager;
 }
@@ -994,9 +994,9 @@ gst_element_get_manager (GstElement *element)
  * exit.  Assuming the loop function itself is the only one who will cause
  * a new loopfunc to be assigned, this should be no problem.
  */
-void 
+void
 gst_element_set_loop_function(GstElement *element,
-                              GstElementLoopFunction loop) 
+                              GstElementLoopFunction loop)
 {
   /* set the loop function */
   element->loopfunc = loop;
@@ -1008,31 +1008,15 @@ gst_element_set_loop_function(GstElement *element,
 /**
  * gst_element_signal_eos:
  * @element: element to trigger the eos signal of
- * 
+ *
  * Throws the eos signal to indicate that the end of the stream is reached.
  */
 void
 gst_element_signal_eos (GstElement *element)
-{  
-  g_return_if_fail (element != NULL);
-  g_return_if_fail (GST_IS_ELEMENT (element));
-
-  gtk_signal_emit (GTK_OBJECT (element), gst_element_signals[EOS]);
-}
-
-void
-gst_element_announce_eos (GstElement *element, gboolean success)
 {
   g_return_if_fail (element != NULL);
   g_return_if_fail (GST_IS_ELEMENT (element));
-  
-  GST_DEBUG(GST_CAT_ELEMENT_PADS,"element '%s' announce eos\n", gst_element_get_name (element));
 
-  if (success) {
-    gst_bin_add_eos_provider (GST_BIN (gst_element_get_manager (element)), element);
-  }
-  else {
-    gst_bin_remove_eos_provider (GST_BIN (gst_element_get_manager (element)), element);
-  }
+  gtk_signal_emit (GTK_OBJECT (element), gst_element_signals[EOS]);
 }
 
index 2617eb40e57edec5b513c3467d9d2f8e765196e3..c67602898e9b02e1b89d8a9d53030010119fcb72 100644 (file)
@@ -110,12 +110,16 @@ typedef enum {
   /* the element has to be scheduled as a cothread for any sanity */
   GST_ELEMENT_USE_COTHREAD,
 
+  // if this element is in EOS
+  GST_ELEMENT_EOS,
+
   /* use some padding for future expansion */
   GST_ELEMENT_FLAG_LAST                = GST_OBJECT_FLAG_LAST + 8,
 } GstElementFlags;
 
 #define GST_ELEMENT_IS_THREAD_SUGGESTED(obj)   (GST_FLAG_IS_SET(obj,GST_ELEMENT_THREAD_SUGGESTED))
 #define GST_ELEMENT_IS_COTHREAD_STOPPING(obj)  (GST_FLAG_IS_SET(obj,GST_ELEMENT_COTHREAD_STOPPING))
+#define GST_ELEMENT_IS_EOS(obj)                        (GST_FLAG_IS_SET(obj,GST_ELEMENT_EOS))
 
 
 typedef struct _GstElement GstElement;
@@ -215,7 +219,6 @@ void                        gst_element_connect             (GstElement *src, const gchar *srcpadname,
 void                   gst_element_disconnect          (GstElement *src, const gchar *srcpadname,
                                                         GstElement *dest, const gchar *destpadname);
 
-void                   gst_element_announce_eos        (GstElement *element, gboolean success);
 void                   gst_element_signal_eos          (GstElement *element);
 
 
index 5dbbe65b00aec786a030d01faa78c5318c90ad05..f1067b74649c27ab831a5775c2275232dc993203 100644 (file)
@@ -1175,10 +1175,7 @@ gst_pad_set_eos(GstPad *pad)
 
   GST_INFO (GST_CAT_PADS,"attempting to set EOS on src pad %s:%s",GST_DEBUG_PAD_NAME(pad));
 
-  gst_element_announce_eos (GST_ELEMENT (pad->parent), TRUE);
-
   if (!gst_pad_eos(GST_REAL_PAD(pad))) {
-    gst_element_announce_eos (GST_ELEMENT (pad->parent), FALSE);
     return FALSE;
   }
 
index c69e2c4a851711b81aa6ab4c0a69b3d5695912f2..e7fca52cbb00be7852726336a4dc2f72fbe78c16 100644 (file)
@@ -62,7 +62,7 @@ gst_bin_chain_wrapper (int argc,char *argv[])
     pads = element->pads;
     while (pads) {
       pad = GST_PAD (pads->data);
-      pads = g_list_next (pads);   
+      pads = g_list_next (pads);
       if (!GST_IS_REAL_PAD(pad)) continue;
       realpad = GST_REAL_PAD(pad);
       if (GST_RPAD_DIRECTION(realpad) == GST_PAD_SINK) {
@@ -75,7 +75,7 @@ gst_bin_chain_wrapper (int argc,char *argv[])
     }
   } while (!GST_ELEMENT_IS_COTHREAD_STOPPING(element));
   GST_FLAG_UNSET(element,GST_ELEMENT_COTHREAD_STOPPING);
-  
+
   GST_DEBUG_LEAVE("(%d,'%s')",argc,name);
   return 0;
 }
@@ -88,7 +88,7 @@ gst_bin_src_wrapper (int argc,char *argv[])
   GstRealPad *realpad;
   GstBuffer *buf;
   G_GNUC_UNUSED const gchar *name = gst_element_get_name (element);
-  
+
   GST_DEBUG_ENTER("(%d,\"%s\")",argc,name);
 
   do {
@@ -121,7 +121,7 @@ gst_bin_src_wrapper (int argc,char *argv[])
   GST_DEBUG_LEAVE("");
   return 0;
 }
-                                
+
 static void
 gst_bin_pushfunc_proxy (GstPad *pad, GstBuffer *buf)
 {
@@ -149,9 +149,9 @@ gst_bin_pullfunc_proxy (GstPad *pad)
   GST_DEBUG (0,"done switching\n");
   buf = GST_RPAD_BUFPEN(pad);
   GST_RPAD_BUFPEN(pad) = NULL;
-  return buf; 
+  return buf;
 }
-  
+
 static GstBuffer *
 gst_bin_chainfunc_proxy (GstPad *pad)
 {
@@ -159,7 +159,7 @@ gst_bin_chainfunc_proxy (GstPad *pad)
 //  GstBuffer *buf;
   return NULL;
 }
-  
+
 // FIXME!!!
 static void
 gst_bin_pullregionfunc_proxy (GstPad *pad,
@@ -168,12 +168,12 @@ gst_bin_pullregionfunc_proxy (GstPad *pad,
 {
 //  region_struct region;
   cothread_state *threadstate;
-    
+
   GST_DEBUG_ENTER("%s:%s,%ld,%ld",GST_DEBUG_PAD_NAME(pad),offset,size);
-      
+
 //  region.offset = offset;
 //  region.size = size;
-  
+
 //  threadstate = GST_ELEMENT(pad->parent)->threadstate;
 //  cothread_set_data (threadstate, "region", &region);
   cothread_switch (threadstate);
@@ -194,7 +194,7 @@ gst_schedule_cothreaded_chain (GstBin *bin, _GstBinChain *chain) {
   // first create thread context
   if (bin->threadcontext == NULL) {
     GST_DEBUG (0,"initializing cothread context\n");
-    bin->threadcontext = cothread_init ();   
+    bin->threadcontext = cothread_init ();
   }
 
   // walk through all the chain's elements
@@ -303,7 +303,9 @@ gst_schedule_chained_chain (GstBin *bin, _GstBinChain *chain) {
   }
 }
 
-static void gst_bin_schedule_cleanup(GstBin *bin) {
+static void
+gst_bin_schedule_cleanup (GstBin *bin)
+{
   GList *chains;
   _GstBinChain *chain;
 
@@ -322,6 +324,13 @@ static void gst_bin_schedule_cleanup(GstBin *bin) {
   bin->chains = NULL;
 }
 
+static void
+gst_scheduler_handle_eos (GstElement *element, _GstBinChain *chain)
+{
+  GST_DEBUG (0,"chain removed from scheduler, EOS from element \"%s\"\n", gst_element_get_name (element));
+  chain->need_scheduling = FALSE;
+}
+
 void gst_bin_schedule_func(GstBin *bin) {
   GList *elements;
   GstElement *element;
@@ -361,6 +370,7 @@ void gst_bin_schedule_func(GstBin *bin) {
 
     // create a chain structure
     chain = g_new0 (_GstBinChain, 1);
+    chain->need_scheduling = TRUE;
 
     // for each pending element, walk the pipeline
     do {
@@ -372,6 +382,7 @@ void gst_bin_schedule_func(GstBin *bin) {
       GST_DEBUG (0,"adding '%s' to chain\n",gst_element_get_name(element));
       chain->elements = g_list_prepend (chain->elements, element);
       chain->num_elements++;
+      gtk_signal_connect (GTK_OBJECT (element), "eos", gst_scheduler_handle_eos, chain);
       // set the cothreads flag as appropriate
       if (GST_FLAG_IS_SET (element, GST_ELEMENT_USE_COTHREAD))
         chain->need_cothreads = TRUE;
@@ -380,7 +391,7 @@ void gst_bin_schedule_func(GstBin *bin) {
 
       // if we're managed by the current bin, and we're not decoupled,
       // go find all the peers and add them to the list of elements to check
-      if ((element->manager == GST_ELEMENT(bin)) && 
+      if ((element->manager == GST_ELEMENT(bin)) &&
           !GST_FLAG_IS_SET (element, GST_ELEMENT_DECOUPLED)) {
         // remove ourselves from the outer list of all managed elements
 //        GST_DEBUG (0,"removing '%s' from list of possible elements\n",gst_element_get_name(element));
@@ -400,7 +411,7 @@ void gst_bin_schedule_func(GstBin *bin) {
           if (!GST_IS_REAL_PAD(pad)) continue;
           GST_DEBUG (0,"have pad %s:%s\n",GST_DEBUG_PAD_NAME(pad));
 
-if (GST_RPAD_PEER(pad) == NULL) GST_ERROR(pad,"peer is null!");
+         if (GST_RPAD_PEER(pad) == NULL) GST_ERROR(pad,"peer is null!");
           g_assert(GST_RPAD_PEER(pad) != NULL);
           g_assert(GST_PAD(GST_RPAD_PEER(pad))->parent != NULL);