From 8de25d9aff6f7a599c6de6546299c0d029f32024 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Thu, 12 Dec 2002 22:16:11 +0000 Subject: [PATCH] cache->index Original commit message from CVS: cache->index --- gst/gstindex.c | 662 +++++++++++++++++++++++++++++++++++++++++++++++++ gst/gstindex.h | 249 +++++++++++++++++++ 2 files changed, 911 insertions(+) create mode 100644 gst/gstindex.c create mode 100644 gst/gstindex.h diff --git a/gst/gstindex.c b/gst/gstindex.c new file mode 100644 index 0000000000..df62e8b5d2 --- /dev/null +++ b/gst/gstindex.c @@ -0,0 +1,662 @@ +/* GStreamer + * Copyright (C) 2001 RidgeRun (http://www.ridgerun.com/) + * Written by Erik Walthinsen + * + * gstindex.c: Index for mappings and other data + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "gstlog.h" +#include "gst_private.h" +#include "gstregistry.h" + +#include "gstindex.h" + +/* Index signals and args */ +enum { + ENTRY_ADDED, + LAST_SIGNAL +}; + +enum { + ARG_0, + /* FILL ME */ +}; + +static void gst_index_class_init (GstIndexClass *klass); +static void gst_index_init (GstIndex *index); + +#define CLASS(index) GST_INDEX_CLASS (G_OBJECT_GET_CLASS (index)) + +static GstObject *parent_class = NULL; +static guint gst_index_signals[LAST_SIGNAL] = { 0 }; + +GType +gst_index_get_type(void) { + static GType index_type = 0; + + if (!index_type) { + static const GTypeInfo index_info = { + sizeof(GstIndexClass), + NULL, + NULL, + (GClassInitFunc)gst_index_class_init, + NULL, + NULL, + sizeof(GstIndex), + 1, + (GInstanceInitFunc)gst_index_init, + NULL + }; + index_type = g_type_register_static(GST_TYPE_OBJECT, "GstIndex", &index_info, 0); + } + return index_type; +} + +static void +gst_index_class_init (GstIndexClass *klass) +{ + GObjectClass *gobject_class; + GstElementClass *gstelement_class; + + gobject_class = (GObjectClass*)klass; + gstelement_class = (GstElementClass*)klass; + + parent_class = g_type_class_ref(GST_TYPE_OBJECT); + + gst_index_signals[ENTRY_ADDED] = + g_signal_new ("entry_added", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GstIndexClass, entry_added), NULL, NULL, + gst_marshal_VOID__POINTER, G_TYPE_NONE, 1, + G_TYPE_POINTER); +} + +static GstIndexGroup * +gst_index_group_new(guint groupnum) +{ + GstIndexGroup *indexgroup = g_new(GstIndexGroup,1); + + indexgroup->groupnum = groupnum; + indexgroup->entries = NULL; + indexgroup->certainty = GST_INDEX_UNKNOWN; + indexgroup->peergroup = -1; + + GST_DEBUG(0, "created new index group %d",groupnum); + + return indexgroup; +} + +static void +gst_index_init (GstIndex *index) +{ + index->curgroup = gst_index_group_new(0); + index->maxgroup = 0; + index->groups = g_list_prepend(NULL, index->curgroup); + + index->writers = g_hash_table_new (NULL, NULL); + index->last_id = 0; + + GST_DEBUG(0, "created new index"); +} + +/** + * gst_index_new: + * + * Create a new tileindex object + * + * Returns: a new index object + */ +GstIndex * +gst_index_new() +{ + GstIndex *index; + + index = g_object_new (gst_index_get_type (), NULL); + + return index; +} + +/** + * gst_index_get_group: + * @index: the index to get the current group from + * + * Get the id of the current group. + * + * Returns: the id of the current group. + */ +gint +gst_index_get_group(GstIndex *index) +{ + return index->curgroup->groupnum; +} + +/** + * gst_index_new_group: + * @index: the index to create the new group in + * + * Create a new group for the given index. It will be + * set as the current group. + * + * Returns: the id of the newly created group. + */ +gint +gst_index_new_group(GstIndex *index) +{ + index->curgroup = gst_index_group_new(++index->maxgroup); + index->groups = g_list_append(index->groups,index->curgroup); + GST_DEBUG(0, "created new group %d in index",index->maxgroup); + return index->maxgroup; +} + +/** + * gst_index_set_group: + * @index: the index to set the new group in + * @groupnum: the groupnumber to set + * + * Set the current groupnumber to the given argument. + * + * Returns: TRUE if the operation succeeded, FALSE if the group + * did not exist. + */ +gboolean +gst_index_set_group(GstIndex *index, gint groupnum) +{ + GList *list; + GstIndexGroup *indexgroup; + + /* first check for null change */ + if (groupnum == index->curgroup->groupnum) + return TRUE; + + /* else search for the proper group */ + list = index->groups; + while (list) { + indexgroup = (GstIndexGroup *)(list->data); + list = g_list_next(list); + if (indexgroup->groupnum == groupnum) { + index->curgroup = indexgroup; + GST_DEBUG(0, "switched to index group %d", indexgroup->groupnum); + return TRUE; + } + } + + /* couldn't find the group in question */ + GST_DEBUG(0, "couldn't find index group %d",groupnum); + return FALSE; +} + +/** + * gst_index_set_certainty: + * @index: the index to set the certainty on + * @certainty: the certainty to set + * + * Set the certainty of the given index. + */ +void +gst_index_set_certainty(GstIndex *index, GstIndexCertainty certainty) +{ + index->curgroup->certainty = certainty; +} + +/** + * gst_index_get_certainty: + * @index: the index to get the certainty of + * + * Get the certainty of the given index. + * + * Returns: the certainty of the index. + */ +GstIndexCertainty +gst_index_get_certainty(GstIndex *index) +{ + return index->curgroup->certainty; +} + +void +gst_index_set_filter (GstIndex *index, + GstIndexFilter filter, gpointer user_data) +{ + g_return_if_fail (GST_IS_INDEX (index)); + + index->filter = filter; + index->filter_user_data = user_data; +} + +void +gst_index_set_resolver (GstIndex *index, + GstIndexResolver resolver, gpointer user_data) +{ + g_return_if_fail (GST_IS_INDEX (index)); + + index->resolver = resolver; + index->resolver_user_data = user_data; +} + +void +gst_index_entry_free (GstIndexEntry *entry) +{ + g_free (entry); +} + +/** + * gst_index_add_format: + * @index: the index to add the entry to + * @id: the id of the index writer + * @format: the format to add to the index + * + * Adds a format entry into the index. This function is + * used to map dynamic GstFormat ids to their original + * format key. + * + * Returns: a pointer to the newly added entry in the index. + */ +GstIndexEntry* +gst_index_add_format (GstIndex *index, gint id, GstFormat format) +{ + GstIndexEntry *entry; + const GstFormatDefinition* def; + + g_return_val_if_fail (GST_IS_INDEX (index), NULL); + g_return_val_if_fail (format != 0, NULL); + + entry = g_new0 (GstIndexEntry, 1); + entry->type = GST_INDEX_ENTRY_FORMAT; + entry->id = id; + entry->data.format.format = format; + def = gst_format_get_details (format); + entry->data.format.key = def->nick; + + if (CLASS (index)->add_entry) + CLASS (index)->add_entry (index, entry); + + g_signal_emit (G_OBJECT (index), gst_index_signals[ENTRY_ADDED], 0, entry); + + return entry; +} + +/** + * gst_index_add_id: + * @index: the index to add the entry to + * @id: the id of the index writer + * @description: the description of the index writer + * + * Returns: a pointer to the newly added entry in the index. + */ +GstIndexEntry* +gst_index_add_id (GstIndex *index, gint id, gchar *description) +{ + GstIndexEntry *entry; + + g_return_val_if_fail (GST_IS_INDEX (index), NULL); + g_return_val_if_fail (description != NULL, NULL); + + entry = g_new0 (GstIndexEntry, 1); + entry->type = GST_INDEX_ENTRY_ID; + entry->id = id; + entry->data.id.description = description; + + if (CLASS (index)->add_entry) + CLASS (index)->add_entry (index, entry); + + g_signal_emit (G_OBJECT (index), gst_index_signals[ENTRY_ADDED], 0, entry); + + return entry; +} + +/** + * gst_index_get_writer_id: + * @index: the index to get a unique write id for + * @writer: the GstObject to allocate an id for + * @id: a pointer to a gint to hold the id + * + * Before entries can be added to the index, a writer + * should obtain a unique id. The methods to add new entries + * to the index require this id as an argument. + * + * The application or a GstIndex subclass can implement + * custom functions to map the writer object to an id. + * + * Returns: TRUE if the writer would be mapped to an id. + */ +gboolean +gst_index_get_writer_id (GstIndex *index, GstObject *writer, gint *id) +{ + gchar *writer_string = NULL; + gboolean success = FALSE; + GstIndexEntry *entry; + + g_return_val_if_fail (GST_IS_INDEX (index), FALSE); + g_return_val_if_fail (GST_IS_OBJECT (writer), FALSE); + g_return_val_if_fail (id, FALSE); + + *id = -1; + + entry = g_hash_table_lookup (index->writers, writer); + if (entry == NULL) { + *id = index->last_id; + + writer_string = gst_object_get_path_string (writer); + + gst_index_add_id (index, *id, writer_string); + index->last_id++; + g_hash_table_insert (index->writers, writer, entry); + } + + if (CLASS (index)->resolve_writer) { + success = CLASS (index)->resolve_writer (index, writer, id, &writer_string); + } + + if (index->resolver) { + success = index->resolver (index, writer, id, &writer_string, index->resolver_user_data); + } + + return success; +} + +/** + * gst_index_add_association: + * @index: the index to add the entry to + * @id: the id of the index writer + * @format: the format of the value + * @value: the value + * @...: other format/value pairs or 0 to end the list + * + * Associate given format/value pairs with eachother. + * Be sure to pass gint64 values to this functions varargs, + * you might want to use a gint64 cast to be sure. + * + * Returns: a pointer to the newly added entry in the index. + */ +GstIndexEntry* +gst_index_add_association (GstIndex *index, gint id, GstAssocFlags flags, + GstFormat format, gint64 value, ...) +{ + va_list args; + GstIndexAssociation *assoc; + GstIndexEntry *entry; + gulong size; + gint nassocs = 0; + GstFormat cur_format; + volatile gint64 dummy; + + g_return_val_if_fail (GST_IS_INDEX (index), NULL); + g_return_val_if_fail (format != 0, NULL); + + va_start (args, value); + + cur_format = format; + + while (cur_format) { + nassocs++; + cur_format = va_arg (args, GstFormat); + if (cur_format) + dummy = va_arg (args, gint64); + } + va_end (args); + + /* make room for two assoc */ + size = sizeof (GstIndexEntry) + (sizeof (GstIndexAssociation) * nassocs); + + entry = g_malloc (size); + + entry->type = GST_INDEX_ENTRY_ASSOCIATION; + entry->id = id; + entry->data.assoc.flags = flags; + assoc = (GstIndexAssociation *) (((guint8 *) entry) + sizeof (GstIndexEntry)); + entry->data.assoc.assocs = assoc; + entry->data.assoc.nassocs = nassocs; + + va_start (args, value); + while (format) { + assoc->format = format; + assoc->value = value; + + assoc++; + + format = va_arg (args, GstFormat); + if (format) + value = va_arg (args, gint64); + } + va_end (args); + + if (CLASS (index)->add_entry) + CLASS (index)->add_entry (index, entry); + + g_signal_emit (G_OBJECT (index), gst_index_signals[ENTRY_ADDED], 0, entry); + + return entry; +} + +static gint +gst_index_compare_func (gconstpointer a, + gconstpointer b, + gpointer user_data) +{ + return a - b; +} + +GstIndexEntry* +gst_index_get_assoc_entry (GstIndex *index, gint id, + GstIndexLookupMethod method, + GstFormat format, gint64 value) +{ + g_return_val_if_fail (GST_IS_INDEX (index), NULL); + + return gst_index_get_assoc_entry_full (index, id, method, format, value, + gst_index_compare_func, NULL); +} + +GstIndexEntry* +gst_index_get_assoc_entry_full (GstIndex *index, gint id, + GstIndexLookupMethod method, + GstFormat format, gint64 value, + GCompareDataFunc func, + gpointer user_data) +{ + g_return_val_if_fail (GST_IS_INDEX (index), NULL); + + if (CLASS(index)->get_assoc_entry) + return CLASS (index)->get_assoc_entry (index, id, method, format, value, func, user_data); + + return NULL; +} + +gboolean +gst_index_entry_assoc_map (GstIndexEntry *entry, + GstFormat format, gint64 *value) +{ + gint i; + + g_return_val_if_fail (entry != NULL, FALSE); + g_return_val_if_fail (value != NULL, FALSE); + + for (i = 0; i < GST_INDEX_NASSOCS (entry); i++) { + if (GST_INDEX_ASSOC_FORMAT (entry, i) == format) { + *value = GST_INDEX_ASSOC_VALUE (entry, i); + return TRUE; + } + } + return FALSE; +} + + +static void gst_index_factory_class_init (GstIndexFactoryClass *klass); +static void gst_index_factory_init (GstIndexFactory *factory); + +static GstPluginFeatureClass *factory_parent_class = NULL; +/* static guint gst_index_factory_signals[LAST_SIGNAL] = { 0 }; */ + +GType +gst_index_factory_get_type (void) +{ + static GType indexfactory_type = 0; + + if (!indexfactory_type) { + static const GTypeInfo indexfactory_info = { + sizeof (GstIndexFactoryClass), + NULL, + NULL, + (GClassInitFunc) gst_index_factory_class_init, + NULL, + NULL, + sizeof(GstIndexFactory), + 0, + (GInstanceInitFunc) gst_index_factory_init, + NULL + }; + indexfactory_type = g_type_register_static (GST_TYPE_PLUGIN_FEATURE, + "GstIndexFactory", &indexfactory_info, 0); + } + return indexfactory_type; +} + +static void +gst_index_factory_class_init (GstIndexFactoryClass *klass) +{ + GObjectClass *gobject_class; + GstObjectClass *gstobject_class; + GstPluginFeatureClass *gstpluginfeature_class; + + gobject_class = (GObjectClass*)klass; + gstobject_class = (GstObjectClass*)klass; + gstpluginfeature_class = (GstPluginFeatureClass*) klass; + + factory_parent_class = g_type_class_ref (GST_TYPE_PLUGIN_FEATURE); +} + +static void +gst_index_factory_init (GstIndexFactory *factory) +{ +} + +/** + * gst_index_factory_new: + * @name: name of indexfactory to create + * @longdesc: long description of indexfactory to create + * @type: the GType of the GstIndex element of this factory + * + * Create a new indexfactory with the given parameters + * + * Returns: a new #GstIndexFactory. + */ +GstIndexFactory* +gst_index_factory_new (const gchar *name, const gchar *longdesc, GType type) +{ + GstIndexFactory *factory; + + g_return_val_if_fail(name != NULL, NULL); + factory = gst_index_factory_find (name); + if (!factory) { + factory = GST_INDEX_FACTORY (g_object_new (GST_TYPE_INDEX_FACTORY, NULL)); + } + + GST_PLUGIN_FEATURE_NAME (factory) = g_strdup (name); + if (factory->longdesc) + g_free (factory->longdesc); + factory->longdesc = g_strdup (longdesc); + factory->type = type; + + return factory; +} + +/** + * gst_index_factory_destroy: + * @factory: factory to destroy + * + * Removes the index from the global list. + */ +void +gst_index_factory_destroy (GstIndexFactory *factory) +{ + g_return_if_fail (factory != NULL); + + /* we don't free the struct bacause someone might have a handle to it.. */ +} + +/** + * gst_index_factory_find: + * @name: name of indexfactory to find + * + * Search for an indexfactory of the given name. + * + * Returns: #GstIndexFactory if found, NULL otherwise + */ +GstIndexFactory* +gst_index_factory_find (const gchar *name) +{ + GstPluginFeature *feature; + + g_return_val_if_fail (name != NULL, NULL); + + GST_DEBUG (0,"gstindex: find \"%s\"", name); + + feature = gst_registry_pool_find_feature (name, GST_TYPE_INDEX_FACTORY); + if (feature) + return GST_INDEX_FACTORY (feature); + + return NULL; +} + +/** + * gst_index_factory_create: + * @factory: the factory used to create the instance + * + * Create a new #GstIndex instance from the + * given indexfactory. + * + * Returns: A new #GstIndex instance. + */ +GstIndex* +gst_index_factory_create (GstIndexFactory *factory) +{ + GstIndex *new = NULL; + + g_return_val_if_fail (factory != NULL, NULL); + + if (gst_plugin_feature_ensure_loaded (GST_PLUGIN_FEATURE (factory))) { + g_return_val_if_fail (factory->type != 0, NULL); + + new = GST_INDEX (g_object_new(factory->type,NULL)); + } + + return new; +} + +/** + * gst_index_factory_make: + * @name: the name of the factory used to create the instance + * + * Create a new #GstIndex instance from the + * indexfactory with the given name. + * + * Returns: A new #GstIndex instance. + */ +GstIndex* +gst_index_factory_make (const gchar *name) +{ + GstIndexFactory *factory; + + g_return_val_if_fail (name != NULL, NULL); + + factory = gst_index_factory_find (name); + + if (factory == NULL) + return NULL; + + return gst_index_factory_create (factory); +} + diff --git a/gst/gstindex.h b/gst/gstindex.h new file mode 100644 index 0000000000..3fa754749a --- /dev/null +++ b/gst/gstindex.h @@ -0,0 +1,249 @@ +/* GStreamer + * Copyright (C) 1999,2000 Erik Walthinsen + * 2000 Wim Taymans + * + * gstindex.h: Header for GstIndex, base class to handle efficient + * storage or caching of seeking information. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __GST_INDEX_H__ +#define __GST_INDEX_H__ + +#include +#include +#include + +G_BEGIN_DECLS + +#define GST_TYPE_INDEX (gst_index_get_type ()) +#define GST_INDEX(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_INDEX, GstIndex)) +#define GST_INDEX_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_INDEX, GstIndexClass)) +#define GST_IS_INDEX(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_INDEX)) +#define GST_IS_INDEX_CLASS(obj) (GST_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_INDEX)) + +typedef struct _GstIndexEntry GstIndexEntry; +typedef struct _GstIndexGroup GstIndexGroup; +typedef struct _GstIndex GstIndex; +typedef struct _GstIndexClass GstIndexClass; + +typedef enum { + GST_INDEX_UNKNOWN, + GST_INDEX_CERTAIN, + GST_INDEX_FUZZY +} GstIndexCertainty; + +typedef enum { + GST_INDEX_ENTRY_ID, + GST_INDEX_ENTRY_ASSOCIATION, + GST_INDEX_ENTRY_OBJECT, + GST_INDEX_ENTRY_FORMAT, +} GstIndexEntryType; + +typedef enum { + GST_INDEX_LOOKUP_EXACT, + GST_INDEX_LOOKUP_BEFORE, + GST_INDEX_LOOKUP_AFTER, +} GstIndexLookupMethod; + +#define GST_INDEX_NASSOCS(entry) ((entry)->data.assoc.nassocs) +#define GST_INDEX_ASSOC_FLAGS(entry) ((entry)->data.assoc.flags) +#define GST_INDEX_ASSOC_FORMAT(entry,i) ((entry)->data.assoc.assocs[(i)].format) +#define GST_INDEX_ASSOC_VALUE(entry,i) ((entry)->data.assoc.assocs[(i)].value) + +typedef struct _GstIndexAssociation GstIndexAssociation; + +struct _GstIndexAssociation { + GstFormat format; + gint64 value; +}; + +typedef enum { + GST_ACCOCIATION_FLAG_NONE = 0, + GST_ACCOCIATION_FLAG_KEY_UNIT = (1 << 0), +} GstAssocFlags; + +#define GST_INDEX_FORMAT_FORMAT(entry) ((entry)->data.format.format) +#define GST_INDEX_FORMAT_KEY(entry) ((entry)->data.format.key) + +#define GST_INDEX_ID_DESCRIPTION(entry) ((entry)->data.id.description) + +struct _GstIndexEntry { + GstIndexEntryType type; + gint id; + + union { + struct { + gchar *description; + } id; + struct { + gint nassocs; + GstIndexAssociation + *assocs; + GstAssocFlags flags; + } assoc; + struct { + gchar *key; + GType type; + gpointer object; + } object; + struct { + GstFormat format; + gchar *key; + } format; + } data; +}; + +struct _GstIndexGroup { + /* unique ID of group in index */ + gint groupnum; + + /* list of entries */ + GList *entries; + + /* the certainty level of the group */ + GstIndexCertainty certainty; + + /* peer group that contains more certain entries */ + gint peergroup; +}; + +typedef gboolean (*GstIndexFilter) (GstIndex *index, + GstIndexEntry *entry); + +typedef gboolean (*GstIndexResolver) (GstIndex *index, + GstObject *writer, + gint *writer_id, + gchar **writer_string, + gpointer user_data); +struct _GstIndex { + GstObject object; + + GList *groups; + GstIndexGroup *curgroup; + gint maxgroup; + + GstIndexResolver resolver; + gpointer resolver_user_data; + + GstIndexFilter filter; + gpointer filter_user_data; + + GHashTable *writers; + gint last_id; +}; + +struct _GstIndexClass { + GstObjectClass parent_class; + + gboolean (*resolve_writer) (GstIndex *index, GstObject *writer, + gint *writer_id, gchar **writer_string); + + /* abstract methods */ + void (*add_entry) (GstIndex *index, GstIndexEntry *entry); + + GstIndexEntry* (*get_assoc_entry) (GstIndex *index, gint id, + GstIndexLookupMethod method, + GstFormat format, gint64 value, + GCompareDataFunc func, + gpointer user_data); + /* signals */ + void (*entry_added) (GstIndex *index, GstIndexEntry *entry); +}; + +GType gst_index_get_type (void); +GstIndex* gst_index_new (void); + +gint gst_index_get_group (GstIndex *index); +gint gst_index_new_group (GstIndex *index); +gboolean gst_index_set_group (GstIndex *index, gint groupnum); + +void gst_index_set_certainty (GstIndex *index, + GstIndexCertainty certainty); +GstIndexCertainty gst_index_get_certainty (GstIndex *index); + +void gst_index_set_filter (GstIndex *index, + GstIndexFilter filter, gpointer user_data); +void gst_index_set_resolver (GstIndex *index, + GstIndexResolver resolver, gpointer user_data); + +gboolean gst_index_get_writer_id (GstIndex *index, GstObject *writer, gint *id); + +GstIndexEntry* gst_index_add_format (GstIndex *index, gint id, GstFormat format); +GstIndexEntry* gst_index_add_association (GstIndex *index, gint id, GstAssocFlags flags, + GstFormat format, gint64 value, ...); +GstIndexEntry* gst_index_add_object (GstIndex *index, gint id, gchar *key, + GType type, gpointer object); +GstIndexEntry* gst_index_add_id (GstIndex *index, gint id, + gchar *description); + +GstIndexEntry* gst_index_get_assoc_entry (GstIndex *index, gint id, + GstIndexLookupMethod method, + GstFormat format, gint64 value); +GstIndexEntry* gst_index_get_assoc_entry_full (GstIndex *index, gint id, + GstIndexLookupMethod method, + GstFormat format, gint64 value, + GCompareDataFunc func, + gpointer user_data); + +/* working with index entries */ +void gst_index_entry_free (GstIndexEntry *entry); +gboolean gst_index_entry_assoc_map (GstIndexEntry *entry, + GstFormat format, gint64 *value); +/* + * creating indexs + * + */ +#define GST_TYPE_INDEX_FACTORY \ + (gst_index_factory_get_type()) +#define GST_INDEX_FACTORY(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_INDEX_FACTORY,GstIndexFactory)) +#define GST_INDEX_FACTORY_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_INDEX_FACTORY,GstIndexFactoryClass)) +#define GST_IS_INDEX_FACTORY(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_INDEX_FACTORY)) +#define GST_IS_INDEX_FACTORY_CLASS(obj) \ + (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_INDEX_FACTORY)) + +typedef struct _GstIndexFactory GstIndexFactory; +typedef struct _GstIndexFactoryClass GstIndexFactoryClass; + +struct _GstIndexFactory { + GstPluginFeature feature; + + gchar *longdesc; /* long description of the index (well, don't overdo it..) */ + GType type; /* unique GType of the index */ +}; + +struct _GstIndexFactoryClass { + GstPluginFeatureClass parent; +}; + +GType gst_index_factory_get_type (void); + +GstIndexFactory* gst_index_factory_new (const gchar *name, + const gchar *longdesc, GType type); +void gst_index_factory_destroy (GstIndexFactory *factory); + +GstIndexFactory* gst_index_factory_find (const gchar *name); + +GstIndex* gst_index_factory_create (GstIndexFactory *factory); +GstIndex* gst_index_factory_make (const gchar *name); + +G_END_DECLS + +#endif /* __GST_INDEX_H__ */