Yes!, incsched is getting closer.

Original commit message from CVS:
Yes!, incsched is getting closer.
This commit is contained in:
Erik Walthinsen 2001-02-17 07:11:12 +00:00
parent 3ff90ac8fb
commit df32997396
14 changed files with 357 additions and 131 deletions

View file

@ -71,6 +71,7 @@ libgstincludedir = $(includedir)/gst
libgstinclude_HEADERS = \
cothreads.h \
gst.h \
gsttypes.h \
gstautoplug.h \
gstbin.h \
gstbuffer.h \

View file

@ -26,6 +26,8 @@
#include <glib.h>
#include <gst/gsttypes.h>
#include <gst/gstinfo.h>
#include <gst/gstobject.h>
#include <gst/gstpad.h>

View file

@ -156,83 +156,94 @@ gst_bin_new (const gchar *name)
}
static inline void
gst_bin_reset_element_manager (GstElement *element, GstElement *manager)
gst_bin_reset_element_sched (GstElement *element, GstSchedule *sched)
{
GST_INFO_ELEMENT (GST_CAT_PARENTAGE, element, "resetting element's manager");
GST_INFO_ELEMENT (GST_CAT_PARENTAGE, element, "resetting element's scheduler");
// first remove the element from its current manager, if any
if (element->manager)
gst_bin_remove_managed_element (GST_BIN(element->manager), element);
// first remove the element from its current schedule, if any
// if (GST_ELEMENT_SCHED(element))
// GST_SCHEDULE_REMOVE_ELEMENT (GST_ELEMENT_SCHED(element), element);
// then set the new manager
gst_element_set_manager (element,manager);
// and add it to the new manager's list
if (manager)
gst_bin_add_managed_element (GST_BIN(manager), element);
gst_element_set_sched (element,sched);
// and add it to the new scheduler
// if (sched)
// GST_SCHEDULE_ADD_ELEMENT (sched, element);
}
void
gst_bin_set_element_manager (GstElement *element,GstElement *manager)
gst_bin_set_element_sched (GstElement *element,GstSchedule *sched)
{
GstSchedule *realsched = NULL;
GList *children;
GstElement *child;
g_return_if_fail (element != NULL);
g_return_if_fail (GST_IS_ELEMENT(element));
g_return_if_fail (sched != NULL);
g_return_if_fail (GST_IS_SCHEDULE(sched));
GST_INFO (GST_CAT_SCHEDULING, "setting element \"%s\" sched to %p",GST_ELEMENT_NAME(element),
sched);
// if it's actually a Bin
if (GST_IS_BIN(element)) {
// figure out which element is the manager
if (GST_FLAG_IS_SET(element,GST_BIN_FLAG_MANAGER)) {
realsched = GST_ELEMENT_SCHED(element);
GST_INFO_ELEMENT (GST_CAT_PARENTAGE, element, "setting children's schedule to own sched");
} else {
realsched = sched;
GST_INFO_ELEMENT (GST_CAT_PARENTAGE, element, "setting children's schedule to parent's");
GST_SCHEDULE_ADD_ELEMENT (sched, element);
}
// set the children's schedule
children = GST_BIN(element)->children;
while (children) {
child = GST_ELEMENT (children->data);
children = g_list_next(children);
gst_bin_set_element_sched (child, realsched);
}
// otherwise, if it's just a regular old element
} else {
g_print("calling schedule_add_element (%p, \"%s\")\n",sched, GST_ELEMENT_NAME(element));
GST_SCHEDULE_ADD_ELEMENT (sched, element);
}
}
void
gst_bin_unset_element_sched (GstElement *element)
{
GstElement *realmanager = NULL;
GList *children;
GstElement *child;
g_return_if_fail (element != NULL);
g_return_if_fail (GST_IS_ELEMENT(element));
// figure out which element is the manager
if (manager) {
if (GST_FLAG_IS_SET(element,GST_BIN_FLAG_MANAGER)) {
realmanager = element;
GST_INFO_ELEMENT (GST_CAT_PARENTAGE, element, "setting children's manager to self");
} else {
realmanager = manager;
GST_INFO_ELEMENT (GST_CAT_PARENTAGE, element, "setting children's manager to parent");
}
} else {
GST_INFO_ELEMENT (GST_CAT_PARENTAGE, element, "unsetting children's manager");
}
// if it's actually a Bin
if (GST_IS_BIN(element)) {
// set the children's manager
// for each child, remove them from their schedule
children = GST_BIN(element)->children;
while (children) {
child = GST_ELEMENT (children->data);
children = g_list_next(children);
gst_bin_set_element_manager (child, realmanager);
gst_bin_unset_element_sched (child);
}
// otherwise, if it's just a regular old element
} else {
// simply reset the element's manager
gst_bin_reset_element_manager (element, realmanager);
if (GST_ELEMENT_SCHED (element))
GST_SCHEDULE_REMOVE_ELEMENT (GST_ELEMENT_SCHED(element), element);
}
}
void
gst_bin_add_managed_element (GstBin *bin, GstElement *element)
{
GST_INFO_ELEMENT (GST_CAT_PARENTAGE, bin, "adding managed element \"%s\"", GST_ELEMENT_NAME(element));
bin->managed_elements = g_list_prepend (bin->managed_elements, element);
bin->num_managed_elements++;
gst_schedule_add_element (NULL, element);
}
void
gst_bin_remove_managed_element (GstBin *bin, GstElement *element)
{
if (g_list_find (bin->managed_elements, element)) {
GST_INFO_ELEMENT (GST_CAT_PARENTAGE, bin, "removing managed element %s", GST_ELEMENT_NAME(element));
bin->managed_elements = g_list_remove (bin->managed_elements, element);
bin->num_managed_elements--;
}
gst_schedule_remove_element (NULL, element);
}
/**
* gst_bin_add:
@ -269,7 +280,10 @@ gst_bin_add (GstBin *bin,
bin->numchildren++;
///// now we have to deal with manager stuff
gst_bin_set_element_manager (element, GST_ELEMENT(bin));
// we can only do this if there's a scheduler:
// if we're not a manager, and aren't attached to anything, we have no sched (yet)
if (GST_ELEMENT_SCHED(bin) != NULL)
gst_bin_set_element_sched (element, GST_ELEMENT_SCHED(bin));
GST_INFO_ELEMENT (GST_CAT_PARENTAGE, bin, "added child \"%s\"", GST_ELEMENT_NAME (element));
@ -312,7 +326,7 @@ gst_bin_remove (GstBin *bin,
}
// remove this element from the list of managed elements
gst_bin_set_element_manager (element, NULL);
gst_bin_unset_element_sched (element);
// now remove the element from the list of elements
gst_object_unparent (GST_OBJECT (element));

View file

@ -55,8 +55,8 @@ typedef enum {
GST_BIN_FLAG_LAST = GST_ELEMENT_FLAG_LAST + 4,
} GstBinFlags;
typedef struct _GstBin GstBin;
typedef struct _GstBinClass GstBinClass;
//typedef struct _GstBin GstBin;
//typedef struct _GstBinClass GstBinClass;
typedef struct __GstBinChain _GstBinChain;
struct _GstBin {

View file

@ -133,6 +133,7 @@ gst_element_init (GstElement *element)
element->pads = NULL;
element->loopfunc = NULL;
element->threadstate = NULL;
element->sched = NULL;
}
/**
@ -847,8 +848,8 @@ gst_element_save_thyself (GstObject *object,
xmlNewChild (parent, NULL, "version", factory->details->version);
}
if (element->manager)
xmlNewChild(parent, NULL, "manager", GST_ELEMENT_NAME(element->manager));
// if (element->manager)
// xmlNewChild(parent, NULL, "manager", GST_ELEMENT_NAME(element->manager));
// output all args to the element
type = GTK_OBJECT_TYPE (element);
@ -1082,34 +1083,33 @@ gst_element_load_thyself (xmlNodePtr self, GstObject *parent)
}
/**
* gst_element_set_manager:
* gst_element_set_sched:
* @element: Element to set manager of.
* @manager: Element to be the manager.
* @sched: @GstSchedule to set.
*
* Sets the manager of the element. For internal use only, unless you're
* Sets the scheduler of the element. For internal use only, unless you're
* writing a new bin subclass.
*/
void
gst_element_set_manager (GstElement *element,
GstElement *manager)
gst_element_set_sched (GstElement *element,
GstSchedule *sched)
{
if (manager)
GST_INFO_ELEMENT (GST_CAT_PARENTAGE, element, "setting manager to \"%s\"",GST_ELEMENT_NAME(manager));
element->manager = manager;
GST_INFO_ELEMENT (GST_CAT_PARENTAGE, element, "setting scheduler to %p",sched);
element->sched = sched;
}
/**
* gst_element_get_manager:
* gst_element_get_sched:
* @element: Element to get manager of.
*
* Returns the manager of the element.
* Returns the scheduler of the element.
*
* Returns: Element's manager
* Returns: Element's scheduler
*/
GstElement*
gst_element_get_manager (GstElement *element)
GstSchedule*
gst_element_get_sched (GstElement *element)
{
return element->manager;
return element->sched;
}
/**

View file

@ -123,9 +123,10 @@ typedef enum {
#define GST_ELEMENT_NAME(obj) (GST_OBJECT_NAME(obj))
#define GST_ELEMENT_PARENT(obj) (GST_OBJECT_PARENT(obj))
#define GST_ELEMENT_MANAGER(obj) (((GstElement*)(obj))->manager)
#define GST_ELEMENT_SCHED(obj) (((GstElement*)(obj))->sched)
typedef struct _GstElement GstElement;
typedef struct _GstElementClass GstElementClass;
//typedef struct _GstElement GstElement;
//typedef struct _GstElementClass GstElementClass;
typedef struct _GstElementDetails GstElementDetails;
typedef struct _GstElementFactory GstElementFactory;
@ -146,6 +147,7 @@ struct _GstElement {
GList *pads;
GstElement *manager;
GstSchedule *sched;
};
struct _GstElementClass {
@ -199,8 +201,8 @@ const gchar* gst_element_get_name (GstElement *element);
void gst_element_set_parent (GstElement *element, GstObject *parent);
GstObject* gst_element_get_parent (GstElement *element);
void gst_element_set_manager (GstElement *element, GstElement *manager);
GstElement* gst_element_get_manager (GstElement *element);
void gst_element_set_sched (GstElement *element, GstSchedule *sched);
GstSchedule* gst_element_get_sched (GstElement *element);
void gst_element_add_pad (GstElement *element, GstPad *pad);
GstPad* gst_element_get_pad (GstElement *element, const gchar *name);

View file

@ -28,6 +28,8 @@
#include <gst/gsttrace.h>
#include <parser.h>
#include <gst/gsttypes.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
@ -55,8 +57,8 @@ extern "C" {
#define GST_IS_OBJECT_CLASS(obj) \
(GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_OBJECT))
typedef struct _GstObject GstObject;
typedef struct _GstObjectClass GstObjectClass;
//typedef struct _GstObject GstObject;
//typedef struct _GstObjectClass GstObjectClass;
#define GST_OBJECT_FLAG_LAST 4

View file

@ -27,6 +27,7 @@
#include "gstelement.h"
#include "gsttype.h"
#include "gstbin.h"
#include "gstscheduler.h"
/***** Start with the base GstPad class *****/
@ -509,6 +510,9 @@ gst_pad_disconnect (GstPad *srcpad,
gtk_signal_emit(GTK_OBJECT(realsrc), gst_real_pad_signals[REAL_DISCONNECTED], realsink);
gtk_signal_emit(GTK_OBJECT(realsink), gst_real_pad_signals[REAL_DISCONNECTED], realsrc);
// now tell the scheduler
GST_SCHEDULE_PAD_DISCONNECT (realsrc->sched, realsrc, realsink);
GST_INFO (GST_CAT_ELEMENT_PADS, "disconnected %s:%s and %s:%s",
GST_DEBUG_PAD_NAME(srcpad), GST_DEBUG_PAD_NAME(sinkpad));
}
@ -570,6 +574,9 @@ gst_pad_connect (GstPad *srcpad,
gtk_signal_emit(GTK_OBJECT(realsrc), gst_real_pad_signals[REAL_CONNECTED], realsink);
gtk_signal_emit(GTK_OBJECT(realsink), gst_real_pad_signals[REAL_CONNECTED], realsrc);
// now tell the scheduler
GST_SCHEDULE_PAD_CONNECT (realsrc->sched, realsrc, realsink);
GST_INFO (GST_CAT_ELEMENT_PADS, "connected %s:%s and %s:%s",
GST_DEBUG_PAD_NAME(srcpad), GST_DEBUG_PAD_NAME(sinkpad));
}
@ -612,6 +619,24 @@ gst_pad_get_parent (GstPad *pad)
return GST_OBJECT_PARENT (pad);
}
void
gst_pad_set_sched (GstPad *pad, GstSchedule *sched)
{
g_return_if_fail (pad != NULL);
g_return_if_fail (GST_IS_PAD (pad));
GST_RPAD_SCHED(pad) = sched;
}
GstSchedule*
gst_pad_get_sched (GstPad *pad)
{
g_return_val_if_fail (pad != NULL, NULL);
g_return_val_if_fail (GST_IS_PAD (pad), NULL);
return GST_RPAD_SCHED(pad);
}
/**
* gst_pad_add_ghost_pad:
* @pad: the pad to set the ghost parent

View file

@ -56,14 +56,14 @@ extern "C" {
#define GST_IS_GHOST_PAD_CLASS(obj) (GTK_CHECK_CLASS_TYPE ((klass), GST_TYPE_GHOST_PAD))
typedef struct _GstPad GstPad;
typedef struct _GstPadClass GstPadClass;
//typedef struct _GstPad GstPad;
//typedef struct _GstPadClass GstPadClass;
typedef struct _GstRealPad GstRealPad;
typedef struct _GstRealPadClass GstRealPadClass;
typedef struct _GstGhostPad GstGhostPad;
typedef struct _GstGhostPadClass GstGhostPadClass;
typedef struct _GstPadTemplate GstPadTemplate;
typedef struct _GstPadTemplateClass GstPadTemplateClass;
//typedef struct _GstPadTemplate GstPadTemplate;
//typedef struct _GstPadTemplateClass GstPadTemplateClass;
typedef enum {
@ -137,6 +137,8 @@ struct _GstRealPad {
GstPadPullRegionFunction pullregionfunc;
GList *ghostpads;
GstSchedule *sched;
};
struct _GstRealPadClass {
@ -174,6 +176,7 @@ struct _GstGhostPadClass {
#define GST_RPAD_CAPS(pad) (((GstRealPad *)(pad))->caps)
#define GST_RPAD_PEER(pad) (((GstRealPad *)(pad))->peer)
#define GST_RPAD_BUFPEN(pad) (((GstRealPad *)(pad))->bufpen)
#define GST_RPAD_SCHED(pad) (((GstRealPad *)(pad))->sched)
#define GST_RPAD_CHAINFUNC(pad) (((GstRealPad *)(pad))->chainfunc)
#define GST_RPAD_GETFUNC(pad) (((GstRealPad *)(pad))->getfunc)
#define GST_RPAD_GETREGIONFUNC(pad) (((GstRealPad *)(pad))->getregionfunc)
@ -275,6 +278,9 @@ const gchar* gst_pad_get_name (GstPad *pad);
void gst_pad_set_parent (GstPad *pad, GstObject *parent);
GstObject* gst_pad_get_parent (GstPad *pad);
void gst_pad_set_sched (GstPad *pad, GstSchedule *sched);
GstSchedule* gst_pad_get_sched (GstPad *pad);
void gst_pad_add_ghost_pad (GstPad *pad, GstPad *ghostpad);
void gst_pad_remove_ghost_pad (GstPad *pad, GstPad *ghostpad);
GList* gst_pad_get_ghost_pad_list (GstPad *pad);

View file

@ -105,7 +105,9 @@ gst_pipeline_init (GstPipeline *pipeline)
pipeline->src = NULL;
pipeline->sinks = NULL;
gst_element_set_manager(GST_ELEMENT(pipeline),GST_ELEMENT(pipeline));
GST_ELEMENT_SCHED(pipeline) = gst_schedule_new(GST_ELEMENT(pipeline));
g_print("pipeline's scheduler is %p\n",GST_ELEMENT_SCHED(pipeline));
// gst_element_set_manager(GST_ELEMENT(pipeline),GST_ELEMENT(pipeline));
}

View file

@ -747,13 +747,63 @@ void gst_bin_schedule_func(GstBin *bin) {
/*************** INCREMENTAL SCHEDULING CODE STARTS HERE ***************/
static GstSchedule realsched;
static GstSchedule *sched = &realsched;
//static GstSchedule realsched;
//static GstSchedule *sched = &realsched;
static void gst_schedule_class_init (GstScheduleClass *klass);
static void gst_schedule_init (GstSchedule *schedule);
static GstObjectClass *parent_class = NULL;
GtkType gst_schedule_get_type(void) {
static GtkType schedule_type = 0;
if (!schedule_type) {
static const GtkTypeInfo schedule_info = {
"GstSchedule",
sizeof(GstSchedule),
sizeof(GstScheduleClass),
(GtkClassInitFunc)gst_schedule_class_init,
(GtkObjectInitFunc)gst_schedule_init,
(GtkArgSetFunc)NULL,
(GtkArgGetFunc)NULL,
(GtkClassInitFunc)NULL,
};
schedule_type = gtk_type_unique(GST_TYPE_OBJECT,&schedule_info);
}
return schedule_type;
}
static void
gst_schedule_class_init (GstScheduleClass *klass)
{
parent_class = gtk_type_class(GST_TYPE_OBJECT);
}
static void
gst_schedule_init (GstSchedule *schedule)
{
schedule->add_element = GST_DEBUG_FUNCPTR(gst_schedule_add_element);
schedule->remove_element = GST_DEBUG_FUNCPTR(gst_schedule_remove_element);
schedule->pad_connect = GST_DEBUG_FUNCPTR(gst_schedule_pad_connect);
schedule->pad_disconnect = GST_DEBUG_FUNCPTR(gst_schedule_pad_disconnect);
}
GstSchedule*
gst_schedule_new(GstElement *parent)
{
GstSchedule *sched = GST_SCHEDULE (gtk_type_new (GST_TYPE_SCHEDULE));
sched->parent = parent;
return sched;
}
/* this function will look at a pad and determine if the peer parent is
* a possible candidate for connecting up in the same chain. */
GstElement *gst_schedule_check_pad (GstSchedule *schedule, GstPad *pad) {
GstElement *gst_schedule_check_pad (GstSchedule *sched, GstPad *pad) {
GstRealPad *peer;
GstElement *peerelement;
@ -800,7 +850,7 @@ void
gst_schedule_chain_destroy (GstScheduleChain *chain)
{
chain->sched->chains = g_list_remove (chain->sched->chains, chain);
sched->num_chains--;
chain->sched->num_chains--;
g_list_free (chain->elements);
g_free (chain);
@ -816,7 +866,7 @@ gst_schedule_chain_add_element (GstScheduleChain *chain, GstElement *element)
}
void
gst_schedule_chain_elements (GstSchedule *schedule, GstElement *element1, GstElement *element2)
gst_schedule_chain_elements (GstSchedule *sched, GstElement *element1, GstElement *element2)
{
GList *chains;
GstScheduleChain *chain;
@ -853,11 +903,11 @@ gst_schedule_chain_elements (GstSchedule *schedule, GstElement *element1, GstEle
} else if ((chain1 != NULL) && (chain2 != NULL)) {
GST_INFO (GST_CAT_SCHEDULING, "joining two existing chains together");
// take the contents of chain2 and merge them into chain1
chain1->elements = g_list_concat (chain1->elements, chain2->elements);
chain1->elements = g_list_concat (chain1->elements, g_list_copy(chain2->elements));
chain1->num_elements += chain2->num_elements;
// FIXME chain changed here
g_free(chain2);
gst_schedule_chain_destroy(chain2);
// otherwise one has a chain already, the other doesn't
} else {
@ -872,18 +922,22 @@ gst_schedule_chain_elements (GstSchedule *schedule, GstElement *element1, GstEle
}
void
gst_schedule_pad_connect_callback (GstPad *pad, GstPad *peer, GstSchedule *sched)
gst_schedule_pad_connect_callback (GstPad *srcpad, GstPad *sinkpad, GstSchedule *sched)
{
GstElement *peerelement;
GST_INFO (GST_CAT_SCHEDULING, "have pad connected callback on %s:%s",GST_DEBUG_PAD_NAME(pad));
GST_INFO (GST_CAT_SCHEDULING, "have pad connected callback on %s:%s",GST_DEBUG_PAD_NAME(srcpad));
if ((peerelement = gst_schedule_check_pad(sched,pad))) {
if ((peerelement = gst_schedule_check_pad(sched,srcpad))) {
GST_INFO (GST_CAT_SCHEDULING, "peer is in same schedule, chaining together");
gst_schedule_chain_elements (sched, GST_ELEMENT(GST_PAD_PARENT(pad)), peerelement);
gst_schedule_chain_elements (sched, GST_ELEMENT(GST_PAD_PARENT(srcpad)), peerelement);
}
}
void gst_schedule_pad_connect (GstSchedule *sched, GstPad *srcpad, GstPad *sinkpad) {
gst_schedule_pad_connect_callback(srcpad,sinkpad,sched);
}
// find the chain within the schedule that holds the element, if any
GstScheduleChain *
gst_schedule_find_chain (GstSchedule *sched, GstElement *element)
@ -922,9 +976,9 @@ gst_schedule_chain_recursive_add (GstScheduleChain *chain, GstElement *element)
pads = g_list_next (pads);
// if it's a potential peer
if ((peerelement = gst_schedule_check_pad (sched, pad))) {
if ((peerelement = gst_schedule_check_pad (chain->sched, pad))) {
// if it's not already in a chain, add it to this one
if (gst_schedule_find_chain (sched, peerelement) == NULL) {
if (gst_schedule_find_chain (chain->sched, peerelement) == NULL) {
gst_schedule_chain_recursive_add (chain, peerelement);
}
}
@ -959,19 +1013,27 @@ gst_schedule_pad_disconnect_callback (GstPad *pad, GstPad *peer, GstSchedule *sc
// now create a new chain to hold element1 and build it from scratch
chain1 = gst_schedule_chain_new (sched);
gst_schedule_chain_recursive_add (chain1, element1);
return;
// this is an ugly hack to handle elements left over
if (chain1->num_elements == 1)
gst_schedule_chain_destroy(chain1);
// check the other element to see if it landed in the newly created chain
if (gst_schedule_find_chain (sched, element2) == NULL) {
// if not in chain, create chain and build from scratch
chain2 = gst_schedule_chain_new (sched);
gst_schedule_chain_recursive_add (chain2, element2);
// this is an ugly hack to handle elements left over
if (chain2->num_elements == 1)
gst_schedule_chain_destroy(chain2);
}
}
void gst_schedule_pad_disconnect (GstSchedule *sched, GstPad *srcpad, GstPad *sinkpad) {
gst_schedule_pad_disconnect_callback(srcpad,sinkpad,sched);
}
void
gst_schedule_add_element (GstSchedule *schedule, GstElement *element)
gst_schedule_add_element (GstSchedule *sched, GstElement *element)
{
GList *pads;
GstPad *pad;
@ -987,12 +1049,21 @@ gst_schedule_add_element (GstSchedule *schedule, GstElement *element)
sched->elements = g_list_prepend (sched->elements, element);
sched->num_elements++;
// set the sched pointer in the element itself
gst_element_set_sched (element, sched);
// now look through the pads and see what we need to do
pads = element->pads;
while (pads) {
pad = GST_PAD(pads->data);
pads = g_list_next(pads);
// we only operate on real pads
if (!GST_IS_REAL_PAD(pad)) continue;
// set the pad's sched pointer
gst_pad_set_sched (pad, sched);
// if the peer element is a candidate
if ((peerelement = gst_schedule_check_pad(sched,pad))) {
GST_INFO (GST_CAT_SCHEDULING, "peer is in same schedule, chaining together");
@ -1002,13 +1073,13 @@ gst_schedule_add_element (GstSchedule *schedule, GstElement *element)
// now we have to attach a signal to each pad
// FIXME this is stupid
gtk_signal_connect(pad,"connected",GTK_SIGNAL_FUNC(gst_schedule_pad_connect_callback),sched);
gtk_signal_connect(pad,"disconnected",GTK_SIGNAL_FUNC(gst_schedule_pad_disconnect_callback),sched);
// gtk_signal_connect(pad,"connected",GTK_SIGNAL_FUNC(gst_schedule_pad_connect_callback),sched);
// gtk_signal_connect(pad,"disconnected",GTK_SIGNAL_FUNC(gst_schedule_pad_disconnect_callback),sched);
}
}
void
gst_schedule_remove_element (GstSchedule *schedule, GstElement *element)
gst_schedule_remove_element (GstSchedule *sched, GstElement *element)
{
GList *chains;
GstScheduleChain *chain;
@ -1034,7 +1105,48 @@ gst_schedule_remove_element (GstSchedule *schedule, GstElement *element)
}
}
// unset the scheduler
gst_element_set_sched (element, NULL);
sched->elements = g_list_remove (sched->elements, element);
sched->num_elements--;
}
}
void
gst_schedule_show (GstSchedule *sched)
{
GList *chains, *elements;
GstElement *element;
GstScheduleChain *chain;
g_return_if_fail(sched != NULL);
g_return_if_fail(GST_IS_SCHEDULE(sched));
g_print("schedule has %d elements in it: ",sched->num_elements);
elements = sched->elements;
while (elements) {
element = GST_ELEMENT(elements->data);
elements = g_list_next(elements);
g_print("%s, ",GST_ELEMENT_NAME(element));
}
g_print("\n");
g_print("schedule has %d chains in it\n",sched->num_chains);
chains = sched->chains;
while (chains) {
chain = (GstScheduleChain *)(chains->data);
chains = g_list_next(chains);
elements = chain->elements;
while (elements) {
element = GST_ELEMENT(elements->data);
elements = g_list_next(elements);
g_print("%s, ",GST_ELEMENT_NAME(element));
}
g_print("\n");
}
}

View file

@ -33,10 +33,25 @@ extern "C" {
#endif /* __cplusplus */
#define GST_TYPE_SCHEDULE \
(gst_schedule_get_type())
#define GST_SCHEDULE(obj) \
(GTK_CHECK_CAST((obj),GST_TYPE_SCHEDULE,GstSchedule))
#define GST_SCHEDULE_CLASS(klass) \
(GTK_CHECK_CLASS_CAST((klass),GST_TYPE_SCHEDULE,GstScheduleClass))
#define GST_IS_SCHEDULE(obj) \
(GTK_CHECK_TYPE((obj),GST_TYPE_SCHEDULE))
#define GST_IS_SCHEDULE_CLASS(klass) \
(GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_SCHEDULE))
//typedef struct _GstSchedule GstSchedule;
//typedef struct _GstScheduleClass GstScheduleClass;
typedef struct _GstScheduleChain GstScheduleChain;
typedef struct _GstSchedule GstSchedule;
struct _GstSchedule {
GstObject object;
GstElement *parent;
GList *elements;
@ -44,8 +59,28 @@ struct _GstSchedule {
GList *chains;
gint num_chains;
void (*add_element) (GstSchedule *sched, GstElement *element);
void (*remove_element) (GstSchedule *sched, GstElement *element);
void (*pad_connect) (GstSchedule *sched, GstPad *srcpad, GstPad *sinkpad);
void (*pad_disconnect) (GstSchedule *sched, GstPad *srcpad, GstPad *sinkpad);
};
struct _GstScheduleClass {
GstObjectClass parent_class;
};
#define GST_SCHEDULE_ADD_ELEMENT(sched,element) \
((sched)->add_element((sched),(element)))
#define GST_SCHEDULE_REMOVE_ELEMENT(sched,element) \
((sched)->remove_element((sched),(element)))
#define GST_SCHEDULE_PAD_CONNECT(sched,srcpad,sinkpad) \
((sched)->pad_connect((sched),(srcpad),(sinkpad)))
#define GST_SCHEDULE_PAD_DISCONNECT(sched,srcpad,sinkpad) \
((sched)->pad_disconnect((sched),(srcpad),(sinkpad)))
struct _GstScheduleChain {
GstSchedule *sched;
@ -61,8 +96,15 @@ struct _GstScheduleChain {
void gst_bin_schedule_func(GstBin *bin);
void gst_schedule_add_element(GstSchedule *schedule,GstElement *element);
void gst_schedule_remove_element(GstSchedule *schedule,GstElement *element);
GtkType gst_schedule_get_type (void);
GstSchedule * gst_schedule_new (GstElement *parent);
void gst_schedule_add_element (GstSchedule *sched, GstElement *element);
void gst_schedule_remove_element (GstSchedule *sched, GstElement *element);
void gst_schedule_pad_connect (GstSchedule *sched, GstPad *srcpad, GstPad *sinkpad);
void gst_schedule_pad_disconnect (GstSchedule *sched, GstPad *srcpad, GstPad *sinkpad);
void gst_schedule_show (GstSchedule *sched);
#ifdef __cplusplus

View file

@ -135,7 +135,7 @@ gst_thread_init (GstThread *thread)
thread->lock = g_mutex_new();
thread->cond = g_cond_new();
gst_element_set_manager(GST_ELEMENT(thread),GST_ELEMENT(thread));
// gst_element_set_manager(GST_ELEMENT(thread),GST_ELEMENT(thread));
}
static void

View file

@ -3,7 +3,7 @@
int main(int argc,char *argv[]) {
GstBin *thread, *bin;
GstElement *src, *identity, *sink;
GstElement *src, *identity, *sink, *identity2;
gst_init(&argc,&argv);
gst_info_set_categories(-1);
@ -15,47 +15,65 @@ int main(int argc,char *argv[]) {
src = gst_elementfactory_make("fakesrc","src");
identity = gst_elementfactory_make("identity","identity");
sink = gst_elementfactory_make("fakesink","sink");
identity2 = gst_elementfactory_make("identity","identity2");
g_print("\n\nConnecting:\n");
g_print("\nAdding src to thread:\n");
gst_bin_add(thread,src);
gst_schedule_show(GST_ELEMENT_SCHED(thread));
g_print("\nAdding identity to thread:\n");
gst_bin_add(thread,identity);
gst_schedule_show(GST_ELEMENT_SCHED(thread));
g_print("\nRemoving identity from thread:\n");
gst_bin_remove(thread, identity);
gst_schedule_show(GST_ELEMENT_SCHED(thread));
g_print("\nAdding identity to thread:\n");
gst_bin_add(thread,identity);
gst_schedule_show(GST_ELEMENT_SCHED(thread));
g_print("\nConnecting src to identity:\n");
gst_element_connect(src,"src",identity,"sink");
gst_schedule_show(GST_ELEMENT_SCHED(thread));
g_print("\n\nAssembling things:\n");
g_print("\nAdding src to bin:\n");
gst_bin_add(bin,src);
g_print("there are %d managed elements in bin\n",bin->num_managed_elements);
g_print("\nDisconnecting src from identity:\n");
gst_element_disconnect(src,"src",identity,"sink");
gst_schedule_show(GST_ELEMENT_SCHED(thread));
g_print("\nAdding identity to bin:\n");
gst_bin_add(bin,identity);
g_print("there are %d managed elements in bin\n",bin->num_managed_elements);
g_print("\nConnecting src to identity:\n");
gst_element_connect(src,"src",identity,"sink");
gst_schedule_show(GST_ELEMENT_SCHED(thread));
g_print("\nAdding sink to bin:\n");
gst_bin_add(bin,sink);
g_print("there are %d managed elements in bin\n",bin->num_managed_elements);
gst_schedule_show(GST_ELEMENT_SCHED(bin));
g_print("\nAdding bin to thread:\n");
gst_bin_add(thread, GST_ELEMENT(bin));
gst_schedule_show(GST_ELEMENT_SCHED(thread));
g_print("\nConnecting identity to sink:\n");
gst_element_connect(identity,"src",sink,"sink");
gst_schedule_show(GST_ELEMENT_SCHED(thread));
g_print("\nDisconnecting sink:\n");
gst_element_disconnect(identity,"src",sink,"sink");
gst_schedule_show(GST_ELEMENT_SCHED(thread));
// g_print("schedule has %d chains now\n",bin->sched->num_chains);
g_print("\nAdding identity2 to bin:\n");
gst_bin_add(bin, identity2);
gst_schedule_show(GST_ELEMENT_SCHED(thread));
// g_print("\nRemoving sink from bin:\n");
// gst_bin_remove(bin,sink);
// g_print("there are %d managed elements in bin\n",bin->num_managed_elements);
g_print("\nConnecting identity2 to sink\n");
gst_element_connect(identity2,"src",sink,"sink");
gst_schedule_show(GST_ELEMENT_SCHED(thread));
// g_print("\nAdding bin to thread:\n");
// gst_bin_add(thread,bin);
// g_print("there are %d managed elements in thread now\n",thread->num_managed_elements);
// g_print("there are %d managed elements in bin now\n",bin->num_managed_elements);
g_print("\nConnecting identity to identity2\n");
gst_element_connect(identity,"src",identity2,"sink");
gst_schedule_show(GST_ELEMENT_SCHED(thread));
/*
g_print("\n\nSaving xml:\n");
xmlSaveFile("threadsync.gst", gst_xml_write(GST_ELEMENT(thread)));
*/
// g_print("\n\nSetting state to READY:\n");
// gst_element_set_state(thread,GST_STATE_READY);
sleep(1);
g_print("\nDisconnecting identity to identity2\n");
gst_element_disconnect(identity,"src",identity2,"sink");
gst_schedule_show(GST_ELEMENT_SCHED(thread));
}