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;
-GstElementDetails gst_bin_details = {
+GstElementDetails gst_bin_details = {
"Generic bin",
"Bin",
"Simple container object",
};
-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 */
static guint gst_bin_signals[LAST_SIGNAL] = { 0 };
GtkType
-gst_bin_get_type (void)
+gst_bin_get_type (void)
{
static GtkType bin_type = 0;
}
static void
-gst_bin_class_init (GstBinClass *klass)
+gst_bin_class_init (GstBinClass *klass)
{
GtkObjectClass *gtkobject_class;
GstElementClass *gstelement_class;
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);
* Returns: new bin
*/
GstElement*
-gst_bin_new (const gchar *name)
+gst_bin_new (const gchar *name)
{
return gst_elementfactory_make ("bin", 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));
*
* 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));
}
-static GstElementStateReturn
-gst_bin_change_state (GstElement *element)
+static GstElementStateReturn
+gst_bin_change_state (GstElement *element)
{
GstBin *bin;
GList *children;
// 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;
}
-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)
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;
*
* 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;
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;
*/
GstElement*
gst_bin_get_by_name (GstBin *bin,
- const gchar *name)
+ const gchar *name)
{
GList *children;
GstElement *child;
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);
* 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);
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;
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;
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));
*
* 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);
*
* 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;
*
* Let the bin figure out how to handle its children.
*/
-void
-gst_bin_schedule (GstBin *bin)
+void
+gst_bin_schedule (GstBin *bin)
{
GstBinClass *oclass;
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;
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;
GList *pads;
GstPad *pad;
GstBuffer *buf = NULL;
+ gint num_scheduled = 0;
GST_DEBUG_ENTER("(\"%s\")", gst_element_get_name (GST_ELEMENT (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
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);
}
}
}
+ 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)));
}
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 {
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 */
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
#endif /* __cplusplus */
-#endif /* __GST_BIN_H__ */
+#endif /* __GST_BIN_H__ */
return element_type;
}
-static void
-gst_element_class_init (GstElementClass *klass)
+static void
+gst_element_class_init (GstElementClass *klass)
{
GtkObjectClass *gtkobject_class;
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;
* Returns: new element
*/
GstElement*
-gst_element_new(void)
+gst_element_new(void)
{
return GST_ELEMENT (gtk_type_new (GST_TYPE_ELEMENT));
}
* 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));
* 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;
* @pad: ghost pad to remove
*
* removes a ghost pad from an element
- *
+ *
*/
void
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;
* 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);
* 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;
*
* 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;
* 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);
*
* 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;
* 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;
* @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);
* 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));
* 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);
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;
if (element->name)
g_free (element->name);
-
+
pads = element->pads;
while (pads) {
pad = GST_PAD (pads->data);
*
* Returns: the new xml node
*/
-xmlNodePtr
+xmlNodePtr
gst_element_save_thyself (GstElement *element,
- xmlNodePtr parent)
+ xmlNodePtr parent)
{
xmlNodePtr self;
GList *pads;
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) &&
* 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;
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) {
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) {
* 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;
}
* Returns: Element's manager
*/
GstElement*
-gst_element_get_manager (GstElement *element)
+gst_element_get_manager (GstElement *element)
{
return element->manager;
}
* 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;
/**
* 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]);
}
/* 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;
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);
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;
}
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) {
}
} while (!GST_ELEMENT_IS_COTHREAD_STOPPING(element));
GST_FLAG_UNSET(element,GST_ELEMENT_COTHREAD_STOPPING);
-
+
GST_DEBUG_LEAVE("(%d,'%s')",argc,name);
return 0;
}
GstRealPad *realpad;
GstBuffer *buf;
G_GNUC_UNUSED const gchar *name = gst_element_get_name (element);
-
+
GST_DEBUG_ENTER("(%d,\"%s\")",argc,name);
do {
GST_DEBUG_LEAVE("");
return 0;
}
-
+
static void
gst_bin_pushfunc_proxy (GstPad *pad, GstBuffer *buf)
{
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)
{
// GstBuffer *buf;
return NULL;
}
-
+
// FIXME!!!
static void
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", ®ion);
cothread_switch (threadstate);
// 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
}
}
-static void gst_bin_schedule_cleanup(GstBin *bin) {
+static void
+gst_bin_schedule_cleanup (GstBin *bin)
+{
GList *chains;
_GstBinChain *chain;
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;
// create a chain structure
chain = g_new0 (_GstBinChain, 1);
+ chain->need_scheduling = TRUE;
// for each pending element, walk the pipeline
do {
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;
// 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));
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);