--- /dev/null
+/* GStreamer
+ * Copyright (C) 2001 RidgeRun (http://www.ridgerun.com/)
+ * Written by Erik Walthinsen <omega@ridgerun.com>
+ *
+ * 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);
+}
+
--- /dev/null
+/* GStreamer
+ * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
+ * 2000 Wim Taymans <wim.taymans@chello.be>
+ *
+ * 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 <gst/gstobject.h>
+#include <gst/gstformat.h>
+#include <gst/gstpluginfeature.h>
+
+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__ */