mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-12 03:16:33 +00:00
Yes!, incsched is getting closer.
Original commit message from CVS: Yes!, incsched is getting closer.
This commit is contained in:
parent
3ff90ac8fb
commit
df32997396
14 changed files with 357 additions and 131 deletions
|
@ -71,6 +71,7 @@ libgstincludedir = $(includedir)/gst
|
|||
libgstinclude_HEADERS = \
|
||||
cothreads.h \
|
||||
gst.h \
|
||||
gsttypes.h \
|
||||
gstautoplug.h \
|
||||
gstbin.h \
|
||||
gstbuffer.h \
|
||||
|
|
|
@ -26,6 +26,8 @@
|
|||
|
||||
#include <glib.h>
|
||||
|
||||
#include <gst/gsttypes.h>
|
||||
|
||||
#include <gst/gstinfo.h>
|
||||
#include <gst/gstobject.h>
|
||||
#include <gst/gstpad.h>
|
||||
|
|
118
gst/gstbin.c
118
gst/gstbin.c
|
@ -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));
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
25
gst/gstpad.c
25
gst/gstpad.c
|
@ -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
|
||||
|
|
14
gst/gstpad.h
14
gst/gstpad.h
|
@ -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);
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue