Commit bbb97999 authored by Wim Taymans's avatar Wim Taymans

Cleanup in gsttypes.c: removed the crazy GList of GHashTables, since the...

Cleanup in gsttypes.c: removed the crazy GList of GHashTables, since the autoplugger will use the GstCaps and element...

Original commit message from CVS:
Cleanup in gsttypes.c:
removed the crazy GList of GHashTables, since the autoplugger will
use the GstCaps and elementfactories instead of the type system.
We don't maintain a list anymore of the elements for the specific
removed unused code in XML loading/saving.

Cleanup in gstelementfactory:
removed the register/unregister methods, register is now implicit when
gst_elementfactory_new is called. _unregister is now _destroy.
Removed logic to register/unregister the types in gsttypes.
added methods to query if the factory can src/sink a GstCaps
Make sure the elementfactory is set in the element_class when a new
element is registered with gst_elementfactory_new.

gst.c: properly register the basic bins
gst_pipeline: use new gstautoplug (next checkin)
gstprops: fixed an error in compatibility check
registry test program changes
plugins: misc changes for the new caps system.
parent 510430d1
......@@ -21,6 +21,7 @@ libgst_la_SOURCES = \
gst.c \
$(GSTOBJECT_SRCS) \
gstpad.c \
gstautoplug.c \
gstbuffer.c \
gstbufferpool.c \
gstclock.c \
......@@ -53,6 +54,7 @@ libgstinclude_HEADERS = \
gstlog.h \
$(GSTOBJECT_INCLUDES) \
gstpad.h \
gstautoplug.h \
gstbuffer.h \
gstbufferpool.h \
gstclock.h \
......@@ -83,7 +85,7 @@ noinst_HEADERS = \
gsti386.h \
gstppc.h
CFLAGS += -O6 -Wall
CFLAGS += -g -O6 -Wall
libgst_la_LIBADD = $(GLIB_LIBS) $(GTK_LIBS) $(XML_LIBS)
libgst_la_LDFLAGS = -version-info $(STREAMER_CURRENT):$(STREAMER_REVISION):$(STREAMER_AGE)
......
......@@ -53,12 +53,9 @@ gst_init (int *argc, char **argv[])
_gst_buffer_initialize ();
/* register some standard builtin types */
gst_elementfactory_register (gst_elementfactory_new ("bin",
gst_bin_get_type (), &gst_bin_details));
gst_elementfactory_register (gst_elementfactory_new ("pipeline",
gst_pipeline_get_type (), &gst_pipeline_details));
gst_elementfactory_register (gst_elementfactory_new("thread",
gst_thread_get_type (), &gst_thread_details));
gst_elementfactory_new ("bin", gst_bin_get_type (), &gst_bin_details);
gst_elementfactory_new ("pipeline", gst_pipeline_get_type (), &gst_pipeline_details);
gst_elementfactory_new("thread", gst_thread_get_type (), &gst_thread_details);
_gst_trace_on = 0;
if (_gst_trace_on) {
......
......@@ -114,7 +114,6 @@ gst_bin_class_init (GstBinClass *klass)
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->elementfactory = gst_elementfactory_find("bin");
gtkobject_class->destroy = gst_bin_real_destroy;
}
......
......@@ -117,8 +117,10 @@ gst_caps_check_compatibility (GstCaps *fromcaps, GstCaps *tocaps)
g_return_val_if_fail (fromcaps != NULL, FALSE);
g_return_val_if_fail (tocaps != NULL, FALSE);
if (fromcaps->id != tocaps->id)
if (fromcaps->id != tocaps->id) {
//g_print ("gstcaps: mime types wrong\n");
return FALSE;
}
if (tocaps->properties) {
GstPropsEntry *entry = (GstPropsEntry *)tocaps->properties;
......@@ -127,13 +129,13 @@ gst_caps_check_compatibility (GstCaps *fromcaps, GstCaps *tocaps)
return gst_props_check_compatibility (fromcaps->properties, tocaps->properties);
}
else {
g_print ("gstcaps: no source caps\n");
//g_print ("gstcaps: no source caps\n");
return FALSE;
}
}
else {
// assume it accepts everything
g_print ("gstcaps: no caps\n");
//g_print ("gstcaps: no caps\n");
return TRUE;
}
}
......
......@@ -191,25 +191,33 @@ xmlNodePtr gst_element_save_thyself (GstElement *element, xmlNodePtr parent);
GstElement* gst_element_load_thyself (xmlNodePtr parent, GHashTable *elements);
GstElementFactory* gst_elementfactory_new (gchar *name,GtkType type,
GstElementDetails *details);
void gst_elementfactory_register (GstElementFactory *elementfactory);
void gst_elementfactory_unregister (GstElementFactory *elementfactory);
/*
*
* factories stuff
*
**/
GstElementFactory* gst_elementfactory_new (gchar *name,GtkType type,
GstElementDetails *details);
void gst_elementfactory_destroy (GstElementFactory *elementfactory);
void gst_elementfactory_add_padtemplate (GstElementFactory *elementfactory,
GstPadTemplate *pad);
GstPadTemplate *pad);
GstElementFactory* gst_elementfactory_find (gchar *name);
GList* gst_elementfactory_get_list (void);
GstElementFactory* gst_elementfactory_find (gchar *name);
GList* gst_elementfactory_get_list (void);
gboolean gst_elementfactory_can_src_caps (GstElementFactory *factory,
GstCaps *caps);
gboolean gst_elementfactory_can_sink_caps (GstElementFactory *factory,
GstCaps *caps);
GstElement* gst_elementfactory_create (GstElementFactory *factory,
gchar *name);
GstElement* gst_elementfactory_create (GstElementFactory *factory,
gchar *name);
// FIXME this name is wrong, probably so is the one above it
GstElement* gst_elementfactory_make (gchar *factoryname, gchar *name);
GstElement* gst_elementfactory_make (gchar *factoryname, gchar *name);
xmlNodePtr gst_elementfactory_save_thyself (GstElementFactory *factory, xmlNodePtr parent);
GstElementFactory* gst_elementfactory_load_thyself (xmlNodePtr parent);
xmlNodePtr gst_elementfactory_save_thyself (GstElementFactory *factory, xmlNodePtr parent);
GstElementFactory* gst_elementfactory_load_thyself (xmlNodePtr parent);
#ifdef __cplusplus
}
......
......@@ -33,21 +33,6 @@ _gst_elementfactory_initialize (void)
_gst_elementfactories = NULL;
}
/**
* gst_elementfactory_register:
* @elementfactory: factory to register
*
* Adds the elementfactory to the global list, so it can be retrieved by
* name.
*/
void
gst_elementfactory_register (GstElementFactory *elementfactory)
{
g_return_if_fail(elementfactory != NULL);
_gst_elementfactories = g_list_prepend (_gst_elementfactories, elementfactory);
}
/**
* gst_elementfactory_unregister:
* @elementfactory: factory to register
......@@ -55,33 +40,10 @@ gst_elementfactory_register (GstElementFactory *elementfactory)
* Removes the elementfactory from the global list.
*/
void
gst_elementfactory_unregister (GstElementFactory *factory)
gst_elementfactory_destroy (GstElementFactory *factory)
{
GList *padtemplates;
g_return_if_fail (factory != NULL);
padtemplates = factory->padtemplates;
while (padtemplates) {
GstPadTemplate *padfactory = (GstPadTemplate *)padtemplates->data;
GstCaps *caps = padfactory->caps;
if (caps) {
switch (padfactory->direction) {
case GST_PAD_SRC:
_gst_type_remove_src (caps->id, factory);
break;
case GST_PAD_SINK:
_gst_type_remove_sink (caps->id, factory);
break;
default:
break;
}
}
padtemplates = g_list_next (padtemplates);
}
_gst_elementfactories = g_list_remove (_gst_elementfactories, factory);
g_free (factory);
......@@ -144,11 +106,19 @@ gst_elementfactory_new (gchar *name, GtkType type,
GstElementDetails *details)
{
GstElementFactory *factory = g_new0(GstElementFactory, 1);
GstElementClass *gstelement_class;
factory->name = g_strdup(name);
factory->type = type;
factory->details = details;
factory->padtemplates = NULL;
gstelement_class = (GstElementClass*) gtk_type_class (GST_TYPE_ELEMENT);
gstelement_class->elementfactory = factory;
_gst_elementfactories = g_list_prepend (_gst_elementfactories, factory);
return factory;
}
......@@ -233,28 +203,58 @@ void
gst_elementfactory_add_padtemplate (GstElementFactory *factory,
GstPadTemplate *template)
{
GstCaps *caps;
g_return_if_fail(factory != NULL);
g_return_if_fail(template != NULL);
factory->padtemplates = g_list_append (factory->padtemplates, template);
}
caps = template->caps;
if (caps) {
switch (template->direction) {
case GST_PAD_SRC:
_gst_type_add_src (caps->id, factory);
break;
case GST_PAD_SINK:
_gst_type_add_sink (caps->id, factory);
break;
default:
g_print ("gstelementfactory: uh? no pad direction\n");
break;
gboolean
gst_elementfactory_can_src_caps (GstElementFactory *factory,
GstCaps *caps)
{
GList *templates;
g_return_val_if_fail(factory != NULL, FALSE);
g_return_val_if_fail(caps != NULL, FALSE);
templates = factory->padtemplates;
while (templates) {
GstPadTemplate *template = (GstPadTemplate *)templates->data;
if (template->direction == GST_PAD_SRC) {
if (gst_caps_check_compatibility (template->caps, caps))
return TRUE;
}
templates = g_list_next (templates);
}
return FALSE;
}
gboolean
gst_elementfactory_can_sink_caps (GstElementFactory *factory,
GstCaps *caps)
{
GList *templates;
g_return_val_if_fail(factory != NULL, FALSE);
g_return_val_if_fail(caps != NULL, FALSE);
templates = factory->padtemplates;
while (templates) {
GstPadTemplate *template = (GstPadTemplate *)templates->data;
if (template->direction == GST_PAD_SINK) {
if (gst_caps_check_compatibility (caps, template->caps))
return TRUE;
}
templates = g_list_next (templates);
}
return FALSE;
}
/**
......@@ -344,6 +344,8 @@ gst_elementfactory_load_thyself (xmlNodePtr parent)
children = children->next;
}
_gst_elementfactories = g_list_prepend (_gst_elementfactories, factory);
return factory;
}
......@@ -22,6 +22,7 @@
#include "gstsink.h"
#include "gstutils.h"
#include "gsttype.h"
#include "gstautoplug.h"
GstElementDetails gst_pipeline_details = {
"Pipeline object",
......@@ -88,7 +89,6 @@ gst_pipeline_class_init (GstPipelineClass *klass)
parent_class = gtk_type_class(gst_bin_get_type());
gstelement_class->change_state = gst_pipeline_change_state;
gstelement_class->elementfactory = gst_elementfactory_find ("pipeline");
}
static void
......@@ -133,13 +133,12 @@ gst_pipeline_have_type (GstSink *sink, GstSink *sink2, gpointer data)
*(gboolean *)data = TRUE;
}
static guint16
static GstCaps*
gst_pipeline_typefind (GstPipeline *pipeline, GstElement *element)
{
gboolean found = FALSE;
GstElement *typefind;
GstCaps *caps = NULL;
guint type_id = 0;
g_print("GstPipeline: typefind for element \"%s\" %p\n",
gst_element_get_name(element), &found);
......@@ -169,8 +168,6 @@ gst_pipeline_typefind (GstPipeline *pipeline, GstElement *element)
caps = gst_util_get_pointer_arg (GTK_OBJECT (typefind), "caps");
gst_pad_set_caps (gst_element_get_pad (element, "src"), caps);
type_id = caps->id;
}
gst_pad_disconnect (gst_element_get_pad (element, "src"),
......@@ -178,7 +175,7 @@ gst_pipeline_typefind (GstPipeline *pipeline, GstElement *element)
gst_bin_remove (GST_BIN (pipeline), typefind);
gst_object_unref (GST_OBJECT (typefind));
return type_id;
return caps;
}
static gboolean
......@@ -207,27 +204,6 @@ gst_pipeline_pads_autoplug_func (GstElement *src, GstPad *pad, GstElement *sink)
connected = TRUE;
break;
}
else {
GList *factories;
g_print("gstpipeline: not compatible, find intermediate element\n");
factories = gst_type_get_sink_to_src (pad->caps->id, sinkpad->caps->id);
while (factories) {
GstElementFactory *factory = (GstElementFactory *)factories->data;
GstElement *element = gst_elementfactory_create (factory, factory->name);
g_print ("gstpipeline: trying element \"%s\"\n", element->name);
if (gst_pipeline_pads_autoplug_func (src, pad, element)) {
if (gst_pipeline_pads_autoplug_func (element, gst_element_get_pad (element, "src"), sink)) {
gst_bin_add (gst_object_get_parent (GST_OBJECT(sink)), element);
return TRUE;
}
}
factories = g_list_next (factories);
}
}
}
sinkpads = g_list_next(sinkpads);
}
......@@ -327,8 +303,8 @@ gst_pipeline_autoplug (GstPipeline *pipeline)
GList **factories;
GList **base_factories;
GstElementFactory *factory;
GList *src_types;
guint16 src_type = 0, sink_type = 0;
GList *src_pads;
GstCaps *src_caps = 0;
guint i, numsinks;
gboolean use_thread = FALSE, have_common = FALSE;
......@@ -346,31 +322,18 @@ gst_pipeline_autoplug (GstPipeline *pipeline)
return FALSE;
}
// FIXME check the factory???
factory = gst_element_get_factory(pipeline->src);
g_print("GstPipeline: source \"%s\" has no MIME type, running typefind...\n",
gst_element_get_name(pipeline->src));
//src_types = factory->pads;
src_types = NULL; // FIXME
if (src_types == NULL) {
g_print("GstPipeline: source \"%s\" has no MIME type, running typefind...\n",
gst_element_get_name(pipeline->src));
src_caps = gst_pipeline_typefind(pipeline, pipeline->src);
src_type = gst_pipeline_typefind(pipeline, pipeline->src);
if (src_type) {
g_print("GstPipeline: source \"%s\" type found %d\n", gst_element_get_name(pipeline->src),
src_type);
}
else {
g_print("GstPipeline: source \"%s\" has no type\n", gst_element_get_name(pipeline->src));
return FALSE;
}
if (src_caps) {
g_print("GstPipeline: source \"%s\" type found %d\n", gst_element_get_name(pipeline->src),
src_caps->id);
}
else {
while (src_types) {
// FIXME loop over types and find paths...
src_types = g_list_next(src_types);
}
g_print("GstPipeline: source \"%s\" has no type\n", gst_element_get_name(pipeline->src));
return FALSE;
}
srcelement = pipeline->src;
......@@ -389,25 +352,9 @@ gst_pipeline_autoplug (GstPipeline *pipeline)
element = GST_ELEMENT(elements->data);
pads = gst_element_get_pad_list(element);
while (pads) {
pad = (GstPad *)pads->data;
if (pad->direction == GST_PAD_SINK) {
GstCaps *caps = gst_pad_get_caps (pad);
if (caps) {
sink_type = caps->id;
break;
}
else
sink_type = 0;
}
pads = g_list_next(pads);
}
pad = (GstPad *)gst_element_get_pad_list (element)->data;
base_factories[i] = factories[i] = gst_type_get_sink_to_src(src_type, sink_type);
base_factories[i] = factories[i] = gst_autoplug_caps (src_caps, pad->caps);
i++;
elements = g_list_next(elements);
......
......@@ -180,7 +180,7 @@ gst_plugin_remove (GstPlugin *plugin)
factories = plugin->elements;
while (factories) {
gst_elementfactory_unregister((GstElementFactory*)(factories->data));
gst_elementfactory_destroy ((GstElementFactory*)(factories->data));
factories = g_list_next(factories);
}
_gst_plugins = g_list_remove(_gst_plugins, plugin);
......@@ -478,7 +478,6 @@ gst_plugin_add_factory (GstPlugin *plugin, GstElementFactory *factory)
// g_print("adding factory to plugin\n");
plugin->elements = g_list_prepend (plugin->elements, factory);
gst_elementfactory_register (factory);
}
/**
......
......@@ -17,7 +17,7 @@
* Boston, MA 02111-1307, USA.
*/
//#define DEBUG_ENABLED
#define DEBUG_ENABLED
#include "gstdebug.h"
#include "gstprops.h"
......@@ -305,6 +305,12 @@ gst_props_check_compatibility (GstProps *fromprops, GstProps *toprops)
sourcelist = g_slist_next (sourcelist);
sinklist = g_slist_next (sinklist);
}
if (sinklist) {
GstPropsEntry *entry2;
entry2 = (GstPropsEntry *)sinklist->data;
missing++;
DEBUG ("source has missing property \"%s\"\n", g_quark_to_string (entry2->propid));
}
end:
if (missing)
......
......@@ -105,7 +105,6 @@ gst_thread_class_init (GstThreadClass *klass)
gstelement_class->change_state = gst_thread_change_state;
gstelement_class->save_thyself = gst_thread_save_thyself;
gstelement_class->restore_thyself = gst_thread_restore_thyself;
gstelement_class->elementfactory = gst_elementfactory_find("thread");
gstbin_class->create_plan = gst_thread_create_plan_dummy;
......
......@@ -39,33 +39,8 @@ struct _GstTypeFindInfo {
GstPlugin *plugin; /* the plugin with this typefind function */
};
#define MAX_COST 999999
struct _gst_type_node
{
int iNode;
int iDist;
int iPrev;
};
typedef struct _gst_type_node gst_type_node;
static GstCaps* gst_type_typefind_dummy (GstBuffer *buffer, gpointer priv);
/* we keep a (spase) matrix in the hashtable like:
*
* type_id list of factories hashed by src type_id
*
* 1 -> (1, factory1, factory2), (3, factory3)
* 2 -> NULL
* 3 -> (4, factory4)
* 4 -> NULL
*
* That way, we can quickly find all factories that convert
* 1 to 2.
*
**/
void
_gst_type_initialize (void)
{
......@@ -98,9 +73,6 @@ gst_type_register (GstTypeFactory *factory)
type->id = _gst_maxtype++;
type->mime = factory->mime;
type->exts = factory->exts;
type->srcs = NULL;
type->sinks = NULL;
type->converters = g_hash_table_new (NULL, NULL);
_gst_types = g_list_prepend (_gst_types, type);
id = type->id;
......@@ -212,397 +184,6 @@ gst_type_find_by_id (guint16 id)
return NULL;
}
static void
gst_type_dump_converter (gpointer key,
gpointer value,
gpointer data)
{
GList *walk = (GList *)value;
GstElementFactory *factory;
guint16 id = GPOINTER_TO_UINT (key);
GstType *type = gst_type_find_by_id (id);
g_print ("\ngsttype: %u (%s), ", type->id, type->mime);
while (walk) {
factory = (GstElementFactory *) walk->data;
g_print("\"%s\" ", factory->name);
walk = g_list_next (walk);
}
}
/**
* gst_type_dump:
*
* dumps the current type system
*/
void
gst_type_dump(void)
{
GList *walk = _gst_types;
GstType *type;
g_print ("gst_type_dump() : \n");
while (walk) {
type = (GstType *)walk->data;
g_print ("gsttype: %d (%s)", type->id, type->mime);
g_hash_table_foreach (type->converters, gst_type_dump_converter, NULL);
g_print ("\n");
walk = g_list_next (walk);
}
}
static void
gst_type_handle_src (guint16 id, GstElementFactory *src, gboolean remove)
{
GList *walk;
GstType *type = gst_type_find_by_id (id);
g_return_if_fail (type != NULL);
g_return_if_fail (src != NULL);
if (remove)
type->srcs = g_list_remove (type->srcs, src);
else
type->srcs = g_list_prepend (type->srcs, src);
// find out if the element has to be indexed in the matrix
walk = src->padtemplates;
while (walk) {
GstPadTemplate *template;
template = (GstPadTemplate *) walk->data;
if (template->direction == GST_PAD_SINK) {
GstType *type2;
GList *converters;
GList *orig;
GstCaps *caps;
caps = template->caps;
if (caps)
type2 = gst_type_find_by_id (caps->id);
else
goto next;
converters = (GList *)g_hash_table_lookup (type2->converters, GUINT_TO_POINTER ((guint)id));
orig = converters;
while (converters) {
if (converters->data == src) {
break;
}
converters = g_list_next (converters);
}
if (remove)
orig = g_list_remove (orig, src);
else if (!converters)
orig = g_list_prepend (orig, src);
g_hash_table_insert (type2->converters, GUINT_TO_POINTER ((guint)id), orig);
}
next:
walk = g_list_next (walk);
}