index: remove GstIndex and GstIndexFactory for now

There are many good use cases for GstIndex and we want
to add it back again in some form, but possibly not with
the current API, which is very powerful (maybe too powerful),
but also a bit confusing. At the very least we'd need to
make the API bindings-friendly.
This commit is contained in:
Tim-Philipp Müller 2011-12-30 15:03:02 +00:00
parent 7d6e165007
commit be04f3945c
27 changed files with 63 additions and 1585 deletions

View file

@ -732,7 +732,6 @@ libs/gst/controller/Makefile
libs/gst/helpers/Makefile
libs/gst/net/Makefile
plugins/Makefile
plugins/indexers/Makefile
plugins/elements/Makefile
po/Makefile.in
tests/Makefile

View file

@ -76,8 +76,6 @@ Windows. It is released under the GNU Library General Public License
<xi:include href="xml/gstevent.xml" />
<xi:include href="xml/gstformat.xml" />
<xi:include href="xml/gstghostpad.xml" />
<xi:include href="xml/gstindex.xml" />
<xi:include href="xml/gstindexfactory.xml" />
<xi:include href="xml/gstiterator.xml" />
<xi:include href="xml/gstmemory.xml" />
<xi:include href="xml/gstmessage.xml" />

View file

@ -687,8 +687,6 @@ gst_element_get_start_time
gst_element_set_bus
gst_element_get_bus
gst_element_get_factory
gst_element_set_index
gst_element_get_index
gst_element_set_name
gst_element_get_name
gst_element_set_parent
@ -1053,102 +1051,6 @@ gst_ghost_pad_get_type
</SECTION>
<SECTION>
<FILE>gstindex</FILE>
<TITLE>GstIndex</TITLE>
GstIndex
GstIndexEntry
GstIndexGroup
GstIndexCertainty
GstIndexEntryType
GstIndexLookupMethod
GST_INDEX_NASSOCS
GST_INDEX_ASSOC_FLAGS
GST_INDEX_ASSOC_FORMAT
GST_INDEX_ASSOC_VALUE
GstIndexAssociation
GstAssocFlags
GST_INDEX_FORMAT_FORMAT
GST_INDEX_FORMAT_KEY
GST_INDEX_ID_INVALID
GST_INDEX_ID_DESCRIPTION
GstIndexFilter
GstIndexResolverMethod
GstIndexResolver
GstIndexFlags
GST_INDEX_IS_READABLE
GST_INDEX_IS_WRITABLE
gst_index_new
gst_index_commit
gst_index_get_group
gst_index_new_group
gst_index_set_group
gst_index_set_certainty
gst_index_get_certainty
gst_index_set_filter
gst_index_set_filter_full
gst_index_set_resolver
gst_index_set_resolver_full
gst_index_get_writer_id
gst_index_add_format
gst_index_add_association
gst_index_add_associationv
gst_index_add_object
gst_index_add_id
gst_index_get_assoc_entry
gst_index_get_assoc_entry_full
gst_index_entry_copy
gst_index_entry_free
gst_index_entry_assoc_map
<SUBSECTION Standard>
GstIndexClass
GST_INDEX
GST_IS_INDEX
GST_TYPE_INDEX
GST_INDEX_CLASS
GST_IS_INDEX_CLASS
GST_INDEX_GET_CLASS
GST_TYPE_INDEX_ENTRY
GST_TYPE_ASSOC_FLAGS
GST_TYPE_INDEX_CERTAINTY
GST_TYPE_INDEX_ENTRY_TYPE
GST_TYPE_INDEX_FLAGS
GST_TYPE_INDEX_LOOKUP_METHOD
GST_TYPE_INDEX_RESOLVER_METHOD
<SUBSECTION Private>
gst_index_get_type
gst_assoc_flags_get_type
gst_index_certainty_get_type
gst_index_entry_get_type
gst_index_entry_type_get_type
gst_index_flags_get_type
gst_index_lookup_method_get_type
gst_index_resolver_method_get_type
</SECTION>
<SECTION>
<FILE>gstindexfactory</FILE>
<TITLE>GstIndexFactory</TITLE>
GstIndexFactory
gst_index_factory_new
gst_index_factory_destroy
gst_index_factory_find
gst_index_factory_create
gst_index_factory_make
<SUBSECTION Standard>
GstIndexFactoryClass
GST_INDEX_FACTORY
GST_IS_INDEX_FACTORY
GST_INDEX_FACTORY_CLASS
GST_IS_INDEX_FACTORY_CLASS
GST_INDEX_FACTORY_GET_CLASS
GST_TYPE_INDEX_FACTORY
<SUBSECTION Private>
gst_index_factory_get_type
</SECTION>
<SECTION>
<FILE>gstinfo</FILE>
<TITLE>GstInfo</TITLE>

View file

@ -17,8 +17,6 @@ gst_control_source_get_type
gst_element_factory_get_type
gst_element_get_type
gst_ghost_pad_get_type
gst_index_factory_get_type
gst_index_get_type
gst_object_get_type
gst_pad_get_type
gst_pad_template_get_type

View file

@ -66,8 +66,6 @@ libgstreamer_@GST_MAJORMINOR@_la_SOURCES = \
gstevent.c \
gstformat.c \
gstghostpad.c \
gstindex.c \
gstindexfactory.c \
gstinfo.c \
gstiterator.c \
gstatomicqueue.c \
@ -162,8 +160,6 @@ gst_headers = \
gstevent.h \
gstformat.h \
gstghostpad.h \
gstindex.h \
gstindexfactory.h \
gstinfo.h \
gstiterator.h \
gstatomicqueue.h \

View file

@ -692,7 +692,6 @@ init_post (GOptionContext * context, GOptionGroup * group, gpointer data,
g_type_class_ref (gst_task_get_type ());
g_type_class_ref (gst_clock_get_type ());
g_type_class_ref (gst_index_factory_get_type ());
gst_uri_handler_get_type ();
g_type_class_ref (gst_object_flags_get_type ());
@ -721,12 +720,6 @@ init_post (GOptionContext * context, GOptionGroup * group, gpointer data,
g_type_class_ref (gst_seek_flags_get_type ());
g_type_class_ref (gst_qos_type_get_type ());
g_type_class_ref (gst_format_get_type ());
g_type_class_ref (gst_index_certainty_get_type ());
g_type_class_ref (gst_index_entry_type_get_type ());
g_type_class_ref (gst_index_lookup_method_get_type ());
g_type_class_ref (gst_assoc_flags_get_type ());
g_type_class_ref (gst_index_resolver_method_get_type ());
g_type_class_ref (gst_index_flags_get_type ());
g_type_class_ref (gst_debug_level_get_type ());
g_type_class_ref (gst_debug_color_flags_get_type ());
g_type_class_ref (gst_iterator_result_get_type ());
@ -1067,7 +1060,6 @@ gst_deinit (void)
g_type_class_unref (g_type_class_peek (gst_bin_get_type ()));
g_type_class_unref (g_type_class_peek (gst_bus_get_type ()));
g_type_class_unref (g_type_class_peek (gst_task_get_type ()));
g_type_class_unref (g_type_class_peek (gst_index_factory_get_type ()));
g_type_class_unref (g_type_class_peek (gst_object_flags_get_type ()));
g_type_class_unref (g_type_class_peek (gst_bin_flags_get_type ()));
g_type_class_unref (g_type_class_peek (gst_buffer_flags_get_type ()));
@ -1101,13 +1093,6 @@ gst_deinit (void)
g_type_class_unref (g_type_class_peek (gst_seek_flags_get_type ()));
g_type_class_unref (g_type_class_peek (gst_qos_type_get_type ()));
g_type_class_unref (g_type_class_peek (gst_format_get_type ()));
g_type_class_unref (g_type_class_peek (gst_index_certainty_get_type ()));
g_type_class_unref (g_type_class_peek (gst_index_entry_type_get_type ()));
g_type_class_unref (g_type_class_peek (gst_index_lookup_method_get_type ()));
g_type_class_unref (g_type_class_peek (gst_assoc_flags_get_type ()));
g_type_class_unref (g_type_class_peek (gst_index_resolver_method_get_type
()));
g_type_class_unref (g_type_class_peek (gst_index_flags_get_type ()));
g_type_class_unref (g_type_class_peek (gst_debug_level_get_type ()));
g_type_class_unref (g_type_class_peek (gst_debug_color_flags_get_type ()));
g_type_class_unref (g_type_class_peek (gst_iterator_result_get_type ()));

View file

@ -52,8 +52,6 @@
#include <gst/gsterror.h>
#include <gst/gstevent.h>
#include <gst/gstghostpad.h>
#include <gst/gstindex.h>
#include <gst/gstindexfactory.h>
#include <gst/gstinfo.h>
#include <gst/gstiterator.h>
#include <gst/gstmarshal.h>

View file

@ -168,8 +168,6 @@
#include "gstinfo.h"
#include "gsterror.h"
#include "gstindex.h"
#include "gstindexfactory.h"
#include "gstutils.h"
#include "gstchildproxy.h"
@ -201,8 +199,11 @@ struct _GstBinPrivate
guint32 structure_cookie;
#if 0
/* cached index */
GstIndex *index;
#endif
/* forward messages from our children */
gboolean message_forward;
@ -238,8 +239,10 @@ static void bin_do_eos (GstBin * bin);
static gboolean gst_bin_add_func (GstBin * bin, GstElement * element);
static gboolean gst_bin_remove_func (GstBin * bin, GstElement * element);
#if 0
static void gst_bin_set_index_func (GstElement * element, GstIndex * index);
static GstIndex *gst_bin_get_index_func (GstElement * element);
#endif
static GstClock *gst_bin_provide_clock_func (GstElement * element);
static gboolean gst_bin_set_clock_func (GstElement * element, GstClock * clock);
@ -473,8 +476,10 @@ gst_bin_class_init (GstBinClass * klass)
GST_DEBUG_FUNCPTR (gst_bin_change_state_func);
gstelement_class->state_changed = GST_DEBUG_FUNCPTR (gst_bin_state_changed);
gstelement_class->get_state = GST_DEBUG_FUNCPTR (gst_bin_get_state_func);
#if 0
gstelement_class->get_index = GST_DEBUG_FUNCPTR (gst_bin_get_index_func);
gstelement_class->set_index = GST_DEBUG_FUNCPTR (gst_bin_set_index_func);
#endif
gstelement_class->provide_clock =
GST_DEBUG_FUNCPTR (gst_bin_provide_clock_func);
gstelement_class->set_clock = GST_DEBUG_FUNCPTR (gst_bin_set_clock_func);
@ -529,7 +534,6 @@ gst_bin_dispose (GObject * object)
GstBus **child_bus_p = &bin->child_bus;
GstClock **provided_clock_p = &bin->provided_clock;
GstElement **clock_provider_p = &bin->clock_provider;
GstIndex **index_p = &bin->priv->index;
GST_CAT_DEBUG_OBJECT (GST_CAT_REFCOUNTING, object, "dispose");
@ -537,7 +541,6 @@ gst_bin_dispose (GObject * object)
gst_object_replace ((GstObject **) child_bus_p, NULL);
gst_object_replace ((GstObject **) provided_clock_p, NULL);
gst_object_replace ((GstObject **) clock_provider_p, NULL);
gst_object_replace ((GstObject **) index_p, NULL);
bin_remove_messages (bin, NULL, GST_MESSAGE_ANY);
GST_OBJECT_UNLOCK (object);
@ -616,6 +619,7 @@ gst_bin_get_property (GObject * object, guint prop_id,
}
}
#if 0
/* return the cached index */
static GstIndex *
gst_bin_get_index_func (GstElement * element)
@ -699,6 +703,7 @@ was_set:
return;
}
}
#endif
/* set the clock on all elements in this bin
*
@ -1120,9 +1125,12 @@ gst_bin_add_func (GstBin * bin, GstElement * element)
* that is not important right now. When the pipeline goes to PLAYING,
* a new clock will be selected */
gst_element_set_clock (element, GST_ELEMENT_CLOCK (bin));
#if 0
/* set the cached index on the children */
if (bin->priv->index)
gst_element_set_index (element, bin->priv->index);
#endif
ret = GST_STATE_RETURN (bin);
/* no need to update the state if we are in error */

View file

@ -552,6 +552,7 @@ gst_element_get_start_time (GstElement * element)
return result;
}
#if 0
/**
* gst_element_set_index:
* @element: a #GstElement.
@ -602,6 +603,7 @@ gst_element_get_index (GstElement * element)
return result;
}
#endif
/**
* gst_element_add_pad:

View file

@ -60,8 +60,6 @@ typedef enum {
#include <gst/gstelementfactory.h>
#include <gst/gstplugin.h>
#include <gst/gstpluginfeature.h>
#include <gst/gstindex.h>
#include <gst/gstindexfactory.h>
#include <gst/gstiterator.h>
#include <gst/gstmessage.h>
#include <gst/gstquery.h>
@ -653,10 +651,6 @@ struct _GstElementClass
GstClock* (*provide_clock) (GstElement *element);
gboolean (*set_clock) (GstElement *element, GstClock *clock);
/* index */
GstIndex* (*get_index) (GstElement *element);
void (*set_index) (GstElement *element, GstIndex *index);
/* query functions */
gboolean (*send_event) (GstElement *element, GstEvent *event);
@ -739,10 +733,6 @@ GstClockTime gst_element_get_base_time (GstElement *element);
void gst_element_set_start_time (GstElement *element, GstClockTime time);
GstClockTime gst_element_get_start_time (GstElement *element);
/* indexes */
void gst_element_set_index (GstElement *element, GstIndex *index);
GstIndex* gst_element_get_index (GstElement *element);
/* bus */
void gst_element_set_bus (GstElement * element, GstBus * bus);
GstBus * gst_element_get_bus (GstElement * element);

View file

@ -1,212 +0,0 @@
/* GStreamer
* Copyright (C) 2001 RidgeRun (http://www.ridgerun.com/)
* Written by Erik Walthinsen <omega@ridgerun.com>
*
* gstindexfactory.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.
*/
/**
* SECTION:gstindexfactory
* @short_description: Create GstIndexes from a factory
* @see_also: #GstIndex
*
* GstIndexFactory is used to dynamically create GstIndex implementations.
*/
#include "gst_private.h"
#include "gstinfo.h"
#include "gstindex.h"
#include "gstindexfactory.h"
#include "gstmarshal.h"
#include "gstregistry.h"
static void gst_index_factory_finalize (GObject * object);
/* static guint gst_index_factory_signals[LAST_SIGNAL] = { 0 }; */
#define gst_index_factory_parent_class parent_class
G_DEFINE_TYPE (GstIndexFactory, gst_index_factory, GST_TYPE_PLUGIN_FEATURE);
static void
gst_index_factory_class_init (GstIndexFactoryClass * klass)
{
GObjectClass *gobject_class = (GObjectClass *) klass;
gobject_class->finalize = gst_index_factory_finalize;
}
static void
gst_index_factory_init (GstIndexFactory * factory)
{
}
static void
gst_index_factory_finalize (GObject * object)
{
GstIndexFactory *factory = GST_INDEX_FACTORY (object);
g_free (factory->longdesc);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
/**
* 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: (transfer full): 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 (g_object_new (GST_TYPE_INDEX_FACTORY, "name", name,
NULL));
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.. */
/* FIXME: gst_index_factory_destroy */
}
/**
* gst_index_factory_find:
* @name: name of indexfactory to find
*
* Search for an indexfactory of the given name.
*
* Returns: (transfer full): #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 ("gstindex: find \"%s\"", name);
feature = gst_registry_find_feature (gst_registry_get_default (), 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: (transfer full): a new #GstIndex instance.
*/
GstIndex *
gst_index_factory_create (GstIndexFactory * factory)
{
GstIndexFactory *newfactory;
GstIndex *new = NULL;
g_return_val_if_fail (factory != NULL, NULL);
newfactory =
GST_INDEX_FACTORY (gst_plugin_feature_load (GST_PLUGIN_FEATURE
(factory)));
if (newfactory == NULL)
return NULL;
new = GST_INDEX (g_object_newv (newfactory->type, 0, NULL));
gst_object_unref (newfactory);
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: (transfer full): a new #GstIndex instance.
*/
GstIndex *
gst_index_factory_make (const gchar * name)
{
GstIndexFactory *factory;
GstIndex *index;
g_return_val_if_fail (name != NULL, NULL);
factory = gst_index_factory_find (name);
if (factory == NULL)
goto no_factory;
index = gst_index_factory_create (factory);
if (index == NULL)
goto create_failed;
gst_object_unref (factory);
return index;
/* ERRORS */
no_factory:
{
GST_INFO ("no such index factory \"%s\"!", name);
return NULL;
}
create_failed:
{
GST_INFO_OBJECT (factory, "couldn't create instance!");
gst_object_unref (factory);
return NULL;
}
}

View file

@ -1,76 +0,0 @@
/* GStreamer
* Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
* 2000 Wim Taymans <wim.taymans@chello.be>
*
* gstindexfactory.h: Header for GstIndexFactory, 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_FACTORY_H__
#define __GST_INDEX_FACTORY_H__
#include <gst/gstobject.h>
#include <gst/gstformat.h>
#include <gst/gstpluginfeature.h>
G_BEGIN_DECLS
#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_IS_INDEX_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_INDEX_FACTORY))
#define GST_INDEX_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_INDEX_FACTORY, GstIndexFactoryClass))
#define GST_IS_INDEX_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_INDEX_FACTORY))
#define GST_INDEX_FACTORY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_INDEX_FACTORY, GstIndexFactoryClass))
typedef struct _GstIndexFactory GstIndexFactory;
typedef struct _GstIndexFactoryClass GstIndexFactoryClass;
/**
* GstIndexFactory:
*
* The GstIndexFactory object
*/
struct _GstIndexFactory {
GstPluginFeature feature;
gchar *longdesc; /* long description of the index (well, don't overdo it..) */
GType type; /* unique GType of the index */
gpointer _gst_reserved[GST_PADDING];
};
struct _GstIndexFactoryClass {
GstPluginFeatureClass parent;
gpointer _gst_reserved[GST_PADDING];
};
GType gst_index_factory_get_type (void);
GstIndexFactory* gst_index_factory_new (const gchar *name,
const gchar *longdesc, GType type) G_GNUC_MALLOC;
void gst_index_factory_destroy (GstIndexFactory *factory);
GstIndexFactory* gst_index_factory_find (const gchar *name);
GstIndex* gst_index_factory_create (GstIndexFactory *factory) G_GNUC_MALLOC;
GstIndex* gst_index_factory_make (const gchar *name) G_GNUC_MALLOC;
G_END_DECLS
#endif /* __GST_INDEX_FACTORY_H__ */

View file

@ -523,7 +523,6 @@ priv_gst_registry_binary_read_cache (GstRegistry * registry,
/* make sure these types exist */
GST_TYPE_ELEMENT_FACTORY;
GST_TYPE_TYPE_FIND_FACTORY;
GST_TYPE_INDEX_FACTORY;
#ifndef GST_DISABLE_GST_DEBUG
timer = g_timer_new ();

View file

@ -332,16 +332,6 @@ gst_registry_chunks_save_feature (GList ** list, GstPluginFeature * feature)
} else {
gst_registry_chunks_save_const_string (list, "");
}
} else if (GST_IS_INDEX_FACTORY (feature)) {
GstIndexFactory *factory = GST_INDEX_FACTORY (feature);
pf = g_slice_new (GstRegistryChunkPluginFeature);
chk =
gst_registry_chunks_make_data (pf,
sizeof (GstRegistryChunkPluginFeature));
/* pack element factory strings */
gst_registry_chunks_save_const_string (list, factory->longdesc);
} else {
GST_WARNING ("unhandled feature type '%s'", type_name);
}
@ -660,17 +650,6 @@ gst_registry_chunks_load_feature (GstRegistry * registry, gchar ** in,
factory->extensions[i - 1] = str;
}
}
} else if (GST_IS_INDEX_FACTORY (feature)) {
GstIndexFactory *factory = GST_INDEX_FACTORY (feature);
align (*in);
GST_DEBUG
("Reading/casting for GstRegistryChunkPluginFeature at address %p",
*in);
unpack_element (*in, pf, GstRegistryChunkPluginFeature, end, fail);
/* unpack index factory strings */
unpack_string (*in, factory->longdesc, end, fail);
} else {
GST_WARNING ("unhandled factory type : %s", G_OBJECT_TYPE_NAME (feature));
goto fail;

View file

@ -40,7 +40,10 @@ libgstbase_@GST_MAJORMINOR@include_HEADERS = \
noinst_HEADERS = \
gstbytereader-docs.h \
gstbytewriter-docs.h \
gstbitreader-docs.h
gstbitreader-docs.h \
gstindex.h
EXTRA_DIST = gstindex.c gstmemindex.c
CLEANFILES = *.gcno *.gcda *.gcov

View file

@ -208,6 +208,11 @@
#include "gstbaseparse.h"
/* FIXME: get rid of old GstIndex code */
#include "gstindex.h"
#include "gstindex.c"
#include "gstmemindex.c"
#define GST_BASE_PARSE_FRAME_PRIVATE_FLAG_NOALLOC (1 << 0)
#define MIN_FRAMES_TO_POST_BITRATE 10
@ -390,8 +395,10 @@ static GstStateChangeReturn gst_base_parse_change_state (GstElement * element,
GstStateChange transition);
static void gst_base_parse_reset (GstBaseParse * parse);
#if 0
static void gst_base_parse_set_index (GstElement * element, GstIndex * index);
static GstIndex *gst_base_parse_get_index (GstElement * element);
#endif
static gboolean gst_base_parse_sink_activate (GstPad * sinkpad,
GstObject * parent);
@ -521,8 +528,11 @@ gst_base_parse_class_init (GstBaseParseClass * klass)
gstelement_class = (GstElementClass *) klass;
gstelement_class->change_state =
GST_DEBUG_FUNCPTR (gst_base_parse_change_state);
#if 0
gstelement_class->set_index = GST_DEBUG_FUNCPTR (gst_base_parse_set_index);
gstelement_class->get_index = GST_DEBUG_FUNCPTR (gst_base_parse_get_index);
#endif
/* Default handlers */
klass->check_valid_frame = gst_base_parse_check_frame;
@ -4025,6 +4035,7 @@ gst_base_parse_handle_tag (GstBaseParse * parse, GstEvent * event)
}
}
#if 0
static void
gst_base_parse_set_index (GstElement * element, GstIndex * index)
{
@ -4057,6 +4068,7 @@ gst_base_parse_get_index (GstElement * element)
return result;
}
#endif
static GstStateChangeReturn
gst_base_parse_change_state (GstElement * element, GstStateChange transition)
@ -4081,7 +4093,7 @@ gst_base_parse_change_state (GstElement * element, GstStateChange transition)
if (G_UNLIKELY (!parse->priv->index)) {
GST_DEBUG_OBJECT (parse, "no index provided creating our own");
parse->priv->index = gst_index_factory_make ("memindex");
parse->priv->index = g_object_new (gst_mem_index_get_type (), NULL);
gst_index_get_writer_id (parse->priv->index, GST_OBJECT (parse),
&parse->priv->index_id);
parse->priv->own_index = TRUE;

View file

@ -55,17 +55,11 @@
* sense to ask the app to provide a ptr and fill it.
*/
#include "gst_private.h"
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "gstinfo.h"
#include "gstindex.h"
#include "gstindexfactory.h"
#include "gstmarshal.h"
#include "gstregistry.h"
/* for constructing an entry name */
#include "gstelement.h"
#include "gstpad.h"
#include "gstinfo.h"
#include <gst/gst.h>
/* Index signals and args */
enum
@ -81,8 +75,10 @@ enum
/* FILL ME */
};
#if 0
GST_DEBUG_CATEGORY_STATIC (index_debug);
#define GST_CAT_DEFAULT index_debug
#endif
static void gst_index_finalize (GObject * object);
@ -148,14 +144,15 @@ gst_index_entry_get_type (void)
return index_entry_type;
}
#if 0
#define _do_init \
{ \
GST_DEBUG_CATEGORY_INIT (index_debug, "GST_INDEX", GST_DEBUG_BOLD, \
"Generic indexing support"); \
}
#endif
#define gst_index_parent_class parent_class
G_DEFINE_TYPE_WITH_CODE (GstIndex, gst_index, GST_TYPE_OBJECT, _do_init);
G_DEFINE_TYPE (GstIndex, gst_index, GST_TYPE_OBJECT);
static void
gst_index_class_init (GstIndexClass * klass)
@ -238,7 +235,7 @@ gst_index_finalize (GObject * object)
if (index->resolver_user_data && index->resolver_user_data_destroy)
index->resolver_user_data_destroy (index->resolver_user_data);
G_OBJECT_CLASS (parent_class)->finalize (object);
G_OBJECT_CLASS (gst_index_parent_class)->finalize (object);
}
static void

View file

@ -19,8 +19,6 @@
#include <gst/gst.h>
#include "gstindexers.h"
#define GST_TYPE_MEM_INDEX \
(gst_index_get_type ())
#define GST_MEM_INDEX(obj) \
@ -95,18 +93,6 @@ struct _GstMemIndexClass
GstIndexClass parent_class;
};
/* Index signals and args */
enum
{
LAST_SIGNAL
};
enum
{
ARG_0,
/* FILL ME */
};
static void gst_mem_index_finalize (GObject * object);
static void gst_mem_index_add_entry (GstIndex * index, GstIndexEntry * entry);
@ -116,8 +102,6 @@ static GstIndexEntry *gst_mem_index_get_assoc_entry (GstIndex * index, gint id,
#define CLASS(mem_index) GST_MEM_INDEX_CLASS (G_OBJECT_GET_CLASS (mem_index))
/*static guint gst_mem_index_signals[LAST_SIGNAL] = { 0 }; */
GType gst_mem_index_get_type (void);
G_DEFINE_TYPE (GstMemIndex, gst_mem_index, GST_TYPE_INDEX);
@ -421,6 +405,7 @@ gst_mem_index_get_assoc_entry (GstIndex * index, gint id,
return entry;
}
#if 0
gboolean
gst_mem_index_plugin_init (GstPlugin * plugin)
{
@ -442,3 +427,4 @@ gst_mem_index_plugin_init (GstPlugin * plugin)
return TRUE;
}
#endif

View file

@ -1,6 +1,6 @@
SUBDIRS = elements indexers
SUBDIRS = elements
DIST_SUBDIRS = elements indexers
DIST_SUBDIRS = elements
Android.mk: Makefile.am
androgenizer -:PROJECT gstreamer \

View file

@ -1,7 +0,0 @@
*.bb
*.bbg
*.da
*.def
*.gcno
*.lo
*.la

View file

@ -1,30 +0,0 @@
plugin_LTLIBRARIES = libgstcoreindexers.la
# FIXME 0.11: gstfileindex.c used libxml and mmap, rewrite using something else or remove
noinst_HEADERS = \
gstindexers.h
libgstcoreindexers_la_DEPENDENCIES = $(top_builddir)/gst/libgstreamer-@GST_MAJORMINOR@.la
libgstcoreindexers_la_SOURCES = gstindexers.c gstmemindex.c
libgstcoreindexers_la_CFLAGS = $(GST_OBJ_CFLAGS)
libgstcoreindexers_la_LIBADD = $(GST_OBJ_LIBS) $(GST_FILEINDEX_LIBS)
libgstcoreindexers_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
libgstcoreindexers_la_LIBTOOLFLAGS = --tag=disable-static
%.c.gcov: .libs/libgstcoreindexers_la-%.gcda %.c
$(GCOV) -b -f -o $^ > $@.out
gcov: $(libgstcoreindexers_la_SOURCES:=.gcov)
Android.mk: Makefile.am
androgenizer -:PROJECT gstreamer -:SHARED libgstcoreindexers -:TAGS eng debug \
-:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-:SOURCES $(libgstcoreindexers_la_SOURCES) \
-:CFLAGS $(DEFS) $(libgstcoreindexers_la_CFLAGS) \
-:LDFLAGS $(libgstcoreindexers_la_LDFLAGS) \
$(libgstcoreindexers_la_LIBADD) \
-:PASSTHROUGH LOCAL_ARM_MODE:=arm \
LOCAL_MODULE_PATH:=$$\(TARGET_OUT\)/lib/gstreamer-@GST_MAJORMINOR@ \
> $@

View file

@ -1,990 +0,0 @@
/* GStreamer
* Copyright (C) 2003 Erik Walthinsen <omega@cse.ogi.edu>
* 2003 Joshua N Pritikin <jpritikin@pobox.com>
*
* 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 <gst/gst.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#ifdef GST_DISABLE_DEPRECATED
#include <libxml/parser.h>
#endif
#include "gstindexers.h"
#define GST_TYPE_FILE_INDEX \
(gst_file_index_get_type ())
#define GST_FILE_INDEX(obj) \
(G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_FILE_INDEX, GstFileIndex))
#define GST_FILE_INDEX_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_FILE_INDEX, GstFileIndexClass))
#define GST_IS_FILE_INDEX(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_FILE_INDEX))
#define GST_IS_FILE_INDEX_CLASS(klass) \
(GST_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_FILE_INDEX))
/*
* Object model:
*
* We build an index to each entry for each id.
*
*
* fileindex
* -----------------------------...
* ! !
* id1 id2
* !
* GArray
*
* The fileindex creates a FileIndexId object for each writer id, a
* Hashtable is kept to map the id to the FileIndexId
*
* The FileIndexId also keeps all the values in a sorted GArray.
*
* Finding a value for an id/format requires locating the correct GArray,
* then do a binary search to get the required value.
*
* Unlike gstmemindex: All formats are assumed to sort to the
* same order. All formats are assumed to be available from
* any entry.
*/
/*
* Each array element is (32bits flags, nformats * 64bits)
*/
typedef struct
{
gint id;
gchar *id_desc;
gint nformats;
GstFormat *format;
GArray *array;
}
GstFileIndexId;
typedef struct _GstFileIndex GstFileIndex;
typedef struct _GstFileIndexClass GstFileIndexClass;
#define ARRAY_ROW_SIZE(_ii) \
(sizeof (gint32) + (_ii)->nformats * sizeof (gint64))
#define ARRAY_TOTAL_SIZE(_ii) \
(_ii->array->len * ARRAY_ROW_SIZE(_ii))
/* don't forget to convert to/from BE byte-order */
#define ARRAY_ROW_FLAGS(_row) \
(*((gint32*) (_row)))
#define ARRAY_ROW_VALUE(_row,_vx) \
(*(gint64*) (((gchar*)(_row)) + sizeof (gint32) + (_vx) * sizeof (gint64)))
GST_DEBUG_CATEGORY_STATIC (DC);
#define GST_CAT_DEFAULT DC
struct _GstFileIndex
{
GstIndex parent;
gchar *location;
gboolean is_loaded;
GSList *unresolved;
gint next_id;
GHashTable *id_index;
GstIndexEntry *ret_entry; /* hack to avoid leaking memory */
};
struct _GstFileIndexClass
{
GstIndexClass parent_class;
};
enum
{
ARG_0,
ARG_LOCATION,
};
static void gst_file_index_dispose (GObject * object);
static void
gst_file_index_set_property (GObject * object,
guint prop_id, const GValue * value, GParamSpec * pspec);
static void
gst_file_index_get_property (GObject * object,
guint prop_id, GValue * value, GParamSpec * pspec);
static gboolean
gst_file_index_get_writer_id (GstIndex * _index, gint * id,
gchar * writer_string);
static void gst_file_index_commit (GstIndex * index, gint writer_id);
static void gst_file_index_add_entry (GstIndex * index, GstIndexEntry * entry);
static GstIndexEntry *gst_file_index_get_assoc_entry (GstIndex * index, gint id,
GstIndexLookupMethod method,
GstAssocFlags flags,
GstFormat format, gint64 value, GCompareDataFunc func, gpointer user_data);
#define CLASS(file_index) GST_FILE_INDEX_CLASS (G_OBJECT_GET_CLASS (file_index))
GType gst_file_index_get_type (void);
G_DEFINE_TYPE (GstFileIndex, gst_file_index, GST_TYPE_INDEX);
static void
gst_file_index_class_init (GstFileIndexClass * klass)
{
GObjectClass *gobject_class;
GstIndexClass *gstindex_class;
gobject_class = (GObjectClass *) klass;
gstindex_class = (GstIndexClass *) klass;
gobject_class->dispose = gst_file_index_dispose;
gobject_class->set_property = gst_file_index_set_property;
gobject_class->get_property = gst_file_index_get_property;
gstindex_class->add_entry = gst_file_index_add_entry;
gstindex_class->get_assoc_entry = gst_file_index_get_assoc_entry;
gstindex_class->commit = gst_file_index_commit;
gstindex_class->get_writer_id = gst_file_index_get_writer_id;
g_object_class_install_property (gobject_class, ARG_LOCATION,
g_param_spec_string ("location", "File Location",
"Location of the index file", NULL,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
}
static void
gst_file_index_init (GstFileIndex * index)
{
GST_DEBUG ("created new file index");
index->id_index = g_hash_table_new (g_int_hash, g_int_equal);
}
static void
_file_index_id_free (GstFileIndexId * index_id, gboolean is_mmapped)
{
if (index_id->id_desc)
g_free (index_id->id_desc);
if (index_id->format)
g_free (index_id->format);
if (index_id->array) {
if (is_mmapped)
munmap (index_id->array->data, ARRAY_TOTAL_SIZE (index_id));
g_array_free (index_id->array, !is_mmapped);
}
g_slice_free (GstFileIndexId, index_id);
}
static gboolean
_id_index_free_helper (gpointer _key, GstFileIndexId * index_id,
GstFileIndex * index)
{
_file_index_id_free (index_id, index->is_loaded);
return TRUE;
}
static void
gst_file_index_dispose (GObject * object)
{
GstFileIndex *index = GST_FILE_INDEX (object);
if (index->location) {
g_free (index->location);
index->location = NULL;
}
{
GSList *elem;
for (elem = index->unresolved; elem; elem = g_slist_next (elem))
_file_index_id_free (elem->data, index->is_loaded);
g_slist_free (index->unresolved);
index->unresolved = NULL;
}
g_hash_table_foreach_steal (index->id_index,
(GHRFunc) _id_index_free_helper, index);
g_hash_table_destroy (index->id_index);
index->id_index = NULL;
gst_index_entry_free (index->ret_entry); /* hack */
G_OBJECT_CLASS (gst_file_index_parent_class)->dispose (object);
}
struct fi_find_writer_context
{
const gchar *writer_string;
GstFileIndexId *ii;
};
static void
_fi_find_writer (gpointer key, gpointer val, gpointer data)
{
struct fi_find_writer_context *cx = data;
GstFileIndexId *ii = val;
if (strcmp (ii->id_desc, cx->writer_string) == 0)
cx->ii = ii;
}
static gboolean
gst_file_index_get_writer_id (GstIndex * _index,
gint * id, gchar * writer_string)
{
GstFileIndex *index = GST_FILE_INDEX (_index);
GSList *pending = index->unresolved;
gboolean match = FALSE;
GSList *elem;
if (!index->is_loaded)
return FALSE;
g_return_val_if_fail (id, FALSE);
g_return_val_if_fail (writer_string, FALSE);
index->unresolved = NULL;
for (elem = pending; elem; elem = g_slist_next (elem)) {
GstFileIndexId *ii = elem->data;
if (strcmp (ii->id_desc, writer_string) != 0) {
index->unresolved = g_slist_prepend (index->unresolved, ii);
continue;
}
if (match) {
GST_WARNING_OBJECT (index, "Duplicate matches for writer '%s'",
writer_string);
continue;
}
ii->id = *id = ++index->next_id;
g_hash_table_insert (index->id_index, &ii->id, ii);
match = TRUE;
}
g_slist_free (pending);
if (!match) {
struct fi_find_writer_context cx;
cx.writer_string = writer_string;
cx.ii = NULL;
g_hash_table_foreach (index->id_index, _fi_find_writer, &cx);
if (cx.ii) {
match = TRUE;
GST_DEBUG_OBJECT (index, "Resolved writer '%s' again", writer_string);
} else
GST_WARNING_OBJECT (index, "Can't resolve writer '%s'", writer_string);
}
return match;
}
static void
_fc_alloc_array (GstFileIndexId * id_index)
{
g_assert (!id_index->array);
id_index->array =
g_array_sized_new (FALSE, FALSE, ARRAY_ROW_SIZE (id_index), 0);
}
static void
gst_file_index_load (GstFileIndex * index)
{
xmlDocPtr doc;
xmlNodePtr root, part;
xmlChar *val;
g_assert (index->location);
g_return_if_fail (!index->is_loaded);
{
gchar *path = g_strdup_printf ("%s/gstindex.xml", index->location);
GError *err = NULL;
gchar *buf;
gsize len;
g_file_get_contents (path, &buf, &len, &err);
g_free (path);
if (err) {
GST_ERROR_OBJECT (index, "%s", err->message);
return;
}
doc = xmlParseMemory (buf, len);
g_free (buf);
}
//xmlDocFormatDump (stderr, doc, TRUE);
root = doc->xmlRootNode;
if (strcmp ((char *) root->name, "gstfileindex") != 0) {
GST_ERROR_OBJECT (index, "root node isn't a gstfileindex");
return;
}
val = xmlGetProp (root, (xmlChar *) "version");
if (!val || atoi ((char *) val) != 1) {
GST_ERROR_OBJECT (index, "version != 1");
return;
}
free (val);
for (part = root->children; part; part = part->next) {
if (strcmp ((char *) part->name, "writers") == 0) {
xmlNodePtr writer;
for (writer = part->children; writer; writer = writer->next) {
xmlChar *datafile = xmlGetProp (writer, (xmlChar *) "datafile");
gchar *path = g_strdup_printf ("%s/%s", index->location, datafile);
int fd;
GstFileIndexId *id_index;
xmlNodePtr wpart;
xmlChar *entries_str;
gpointer array_data;
free (datafile);
fd = open (path, O_RDONLY);
g_free (path);
if (fd < 0) {
GST_ERROR_OBJECT (index,
"Can't open '%s': %s", path, g_strerror (errno));
continue;
}
id_index = g_slice_new0 (GstFileIndexId);
id_index->id_desc = (char *) xmlGetProp (writer, (xmlChar *) "id");
for (wpart = writer->children; wpart; wpart = wpart->next) {
if (strcmp ((char *) wpart->name, "formats") == 0) {
xmlChar *count_str = xmlGetProp (wpart, (xmlChar *) "count");
gint fx = 0;
xmlNodePtr format;
id_index->nformats = atoi ((char *) count_str);
free (count_str);
id_index->format = g_new (GstFormat, id_index->nformats);
for (format = wpart->children; format; format = format->next) {
xmlChar *nick = xmlGetProp (format, (xmlChar *) "nick");
GstFormat fmt = gst_format_get_by_nick ((gchar *) nick);
if (fmt == GST_FORMAT_UNDEFINED)
GST_ERROR_OBJECT (index, "format '%s' undefined", nick);
g_assert (fx < id_index->nformats);
id_index->format[fx++] = fmt;
free (nick);
}
} else
GST_INFO_OBJECT (index, "unknown wpart '%s'", wpart->name);
}
g_assert (id_index->nformats > 0);
_fc_alloc_array (id_index);
g_assert (id_index->array->data == NULL); /* little bit risky */
entries_str = xmlGetProp (writer, (xmlChar *) "entries");
id_index->array->len = atoi ((char *) entries_str);
free (entries_str);
array_data =
mmap (NULL, ARRAY_TOTAL_SIZE (id_index), PROT_READ, MAP_SHARED, fd,
0);
close (fd);
if (array_data == MAP_FAILED) {
GST_ERROR_OBJECT (index,
"mmap %s failed: %s", path, g_strerror (errno));
continue;
}
id_index->array->data = array_data;
index->unresolved = g_slist_prepend (index->unresolved, id_index);
}
} else
GST_INFO_OBJECT (index, "unknown part '%s'", part->name);
}
xmlFreeDoc (doc);
GST_OBJECT_FLAG_UNSET (index, GST_INDEX_WRITABLE);
index->is_loaded = TRUE;
GST_LOG_OBJECT (index, "index %s loaded OK", index->location);
}
static void
gst_file_index_set_property (GObject * object,
guint prop_id, const GValue * value, GParamSpec * pspec)
{
GstFileIndex *index = GST_FILE_INDEX (object);
switch (prop_id) {
case ARG_LOCATION:
if (index->location)
g_free (index->location);
index->location = g_value_dup_string (value);
if (index->location && !g_hash_table_size (index->id_index))
gst_file_index_load (index);
break;
}
}
static void
gst_file_index_get_property (GObject * object,
guint prop_id, GValue * value, GParamSpec * pspec)
{
GstFileIndex *index = GST_FILE_INDEX (object);
switch (prop_id) {
case ARG_LOCATION:
g_value_set_string (value, index->location);
break;
}
}
static void
_file_index_id_save_xml (gpointer _key, GstFileIndexId * ii, xmlNodePtr writers)
{
const gint bufsize = 16;
gchar buf[16];
xmlNodePtr writer;
xmlNodePtr formats;
gint xx;
if (!ii->array) {
GST_INFO ("Index for %s is empty", ii->id_desc);
return;
}
writer = xmlNewChild (writers, NULL, (xmlChar *) "writer", NULL);
xmlSetProp (writer, (xmlChar *) "id", (xmlChar *) ii->id_desc);
g_snprintf (buf, bufsize, "%d", ii->array->len);
xmlSetProp (writer, (xmlChar *) "entries", (xmlChar *) buf);
g_snprintf (buf, bufsize, "%d", ii->id); /* any unique number is OK */
xmlSetProp (writer, (xmlChar *) "datafile", (xmlChar *) buf);
formats = xmlNewChild (writer, NULL, (xmlChar *) "formats", NULL);
g_snprintf (buf, bufsize, "%d", ii->nformats);
xmlSetProp (formats, (xmlChar *) "count", (xmlChar *) buf);
for (xx = 0; xx < ii->nformats; xx++) {
xmlNodePtr format = xmlNewChild (formats, NULL, (xmlChar *) "format", NULL);
const GstFormatDefinition *def = gst_format_get_details (ii->format[xx]);
xmlSetProp (format, (xmlChar *) "nick", (xmlChar *) def->nick);
}
}
/*
We must save the binary data in separate files because
mmap wants getpagesize() alignment. If we append all
the data to one file then we don't know the appropriate
padding since the page size isn't fixed.
*/
static void
_file_index_id_save_entries (gpointer * _key,
GstFileIndexId * ii, gchar * prefix)
{
GError *err;
gchar *path;
GIOChannel *chan;
if (!ii->array)
return;
err = NULL;
path = g_strdup_printf ("%s/%d", prefix, ii->id);
chan = g_io_channel_new_file (path, "w", &err);
g_free (path);
if (err)
goto fail;
g_io_channel_set_encoding (chan, NULL, &err);
if (err)
goto fail;
g_io_channel_write_chars (chan,
ii->array->data, ARRAY_TOTAL_SIZE (ii), NULL, &err);
if (err)
goto fail;
g_io_channel_shutdown (chan, TRUE, &err);
if (err)
goto fail;
g_io_channel_unref (chan);
return;
fail:
GST_ERROR ("%s", err->message);
}
/*
We have to save the whole set of indexes into a single file
so it doesn't make sense to commit only a single writer.
i suggest:
gst_index_commit (index, -1);
*/
static void
gst_file_index_commit (GstIndex * _index, gint _writer_id)
{
GstFileIndex *index = GST_FILE_INDEX (_index);
xmlDocPtr doc;
xmlNodePtr writers;
GError *err = NULL;
gchar *path;
GIOChannel *tocfile;
g_return_if_fail (index->location);
g_return_if_fail (!index->is_loaded);
GST_OBJECT_FLAG_UNSET (index, GST_INDEX_WRITABLE);
doc = xmlNewDoc ((xmlChar *) "1.0");
doc->xmlRootNode =
xmlNewDocNode (doc, NULL, (xmlChar *) "gstfileindex", NULL);
xmlSetProp (doc->xmlRootNode, (xmlChar *) "version", (xmlChar *) "1");
writers = xmlNewChild (doc->xmlRootNode, NULL, (xmlChar *) "writers", NULL);
g_hash_table_foreach (index->id_index,
(GHFunc) _file_index_id_save_xml, writers);
if (mkdir (index->location, 0777) && errno != EEXIST) {
GST_ERROR_OBJECT (index, "mkdir %s: %s", index->location,
g_strerror (errno));
return;
}
path = g_strdup_printf ("%s/gstindex.xml", index->location);
tocfile = g_io_channel_new_file (path, "w", &err);
g_free (path);
if (err) {
GST_ERROR_OBJECT (index, "%s", err->message);
return;
}
g_io_channel_set_encoding (tocfile, NULL, &err);
if (err) {
GST_ERROR_OBJECT (index, "%s", err->message);
return;
}
{
xmlChar *xmlmem;
int xmlsize;
xmlDocDumpMemory (doc, &xmlmem, &xmlsize);
g_io_channel_write_chars (tocfile, (gchar *) xmlmem, xmlsize, NULL, &err);
if (err) {
GST_ERROR_OBJECT (index, "%s", err->message);
return;
}
xmlFreeDoc (doc);
free (xmlmem);
}
g_io_channel_shutdown (tocfile, TRUE, &err);
if (err) {
GST_ERROR_OBJECT (index, "%s", err->message);
return;
}
g_io_channel_unref (tocfile);
g_hash_table_foreach (index->id_index,
(GHFunc) _file_index_id_save_entries, index->location);
}
static void
gst_file_index_add_id (GstIndex * index, GstIndexEntry * entry)
{
GstFileIndex *fileindex = GST_FILE_INDEX (index);
GstFileIndexId *id_index;
id_index = g_hash_table_lookup (fileindex->id_index, &entry->id);
if (!id_index) {
id_index = g_slice_new0 (GstFileIndexId);
id_index->id = entry->id;
id_index->id_desc = g_strdup (entry->data.id.description);
/* It would be useful to know the GType of the writer so
we can try to cope with changes in the id_desc path. */
g_hash_table_insert (fileindex->id_index, &id_index->id, id_index);
}
}
/* This algorithm differs from libc bsearch in the handling
of non-exact matches. */
static gboolean
_fc_bsearch (GArray * ary,
gint stride,
gint * ret,
GCompareDataFunc compare, gconstpointer sample, gpointer user_data)
{
gint first, last;
gint mid;
gint midsize;
gint cmp;
gint tx;
g_return_val_if_fail (compare, FALSE);
if (!ary->len) {
if (ret)
*ret = 0;
return FALSE;
}
first = 0;
last = ary->len - 1;
midsize = last - first;
while (midsize > 1) {
mid = first + midsize / 2;
cmp = (*compare) (sample, ary->data + mid * stride, user_data);
if (cmp == 0) {
/* if there are multiple matches then scan for the first match */
while (mid > 0 &&
(*compare) (sample, ary->data + (mid - 1) * stride, user_data) == 0)
--mid;
if (ret)
*ret = mid;
return TRUE;
}
if (cmp < 0)
last = mid - 1;
else
first = mid + 1;
midsize = last - first;
}
for (tx = first; tx <= last; tx++) {
cmp = (*compare) (sample, ary->data + tx * stride, user_data);
if (cmp < 0) {
if (ret)
*ret = tx;
return FALSE;
}
if (cmp == 0) {
if (ret)
*ret = tx;
return TRUE;
}
}
if (ret)
*ret = last + 1;
return FALSE;
}
static gint
file_index_compare (gconstpointer sample, gconstpointer row, gpointer user_data)
{
//GstFileIndexId *id_index = user_data;
const GstIndexAssociation *ca = sample;
gint64 val1 = ca->value;
gint64 val2_be = ARRAY_ROW_VALUE (row, ca->format);
gint64 val2 = GINT64_FROM_BE (val2_be);
gint64 diff = val2 - val1;
return (diff == 0 ? 0 : (diff < 0 ? 1 : -1));
}
static void
gst_file_index_add_association (GstIndex * index, GstIndexEntry * entry)
{
GstFileIndex *fileindex = GST_FILE_INDEX (index);
GstFileIndexId *id_index;
gint mx;
GstIndexAssociation sample;
gboolean exact;
id_index = g_hash_table_lookup (fileindex->id_index, &entry->id);
if (!id_index)
return;
if (!id_index->nformats) {
gint fx;
id_index->nformats = GST_INDEX_NASSOCS (entry);
GST_LOG_OBJECT (fileindex, "creating %d formats for %d",
id_index->nformats, entry->id);
id_index->format = g_new (GstFormat, id_index->nformats);
for (fx = 0; fx < id_index->nformats; fx++)
id_index->format[fx] = GST_INDEX_ASSOC_FORMAT (entry, fx);
_fc_alloc_array (id_index);
} else {
/* only sanity checking */
if (id_index->nformats != GST_INDEX_NASSOCS (entry))
GST_WARNING_OBJECT (fileindex, "arity change %d -> %d",
id_index->nformats, GST_INDEX_NASSOCS (entry));
else {
gint fx;
for (fx = 0; fx < id_index->nformats; fx++)
if (id_index->format[fx] != GST_INDEX_ASSOC_FORMAT (entry, fx))
GST_WARNING_OBJECT (fileindex, "format[%d] changed %d -> %d",
fx, id_index->format[fx], GST_INDEX_ASSOC_FORMAT (entry, fx));
}
}
/* this is a hack, we should use a private structure instead */
sample.format = GST_FORMAT_UNDEFINED;
sample.value = GST_INDEX_ASSOC_VALUE (entry, 0);
exact =
_fc_bsearch (id_index->array, ARRAY_ROW_SIZE (id_index),
&mx, file_index_compare, &sample, id_index);
if (exact) {
/* maybe overwrite instead? */
GST_DEBUG_OBJECT (index,
"Ignoring duplicate index association at %" G_GINT64_FORMAT,
GST_INDEX_ASSOC_VALUE (entry, 0));
return;
}
{
gchar *row_data = (gchar *) g_malloc (ARRAY_ROW_SIZE (id_index));
gint fx;
gint32 flags_host = GST_INDEX_ASSOC_FLAGS (entry);
ARRAY_ROW_FLAGS (row_data) = GINT32_TO_BE (flags_host);
for (fx = 0; fx < id_index->nformats; fx++) {
gint64 val_host = GST_INDEX_ASSOC_VALUE (entry, fx);
ARRAY_ROW_VALUE (row_data, fx) = GINT64_TO_BE (val_host);
}
g_array_insert_vals (id_index->array, mx, row_data, 1);
g_free (row_data);
}
}
/*
static void
show_entry (GstIndexEntry *entry)
{
switch (entry->type) {
case GST_INDEX_ENTRY_ID:
g_print ("id %d describes writer %s\n", entry->id,
GST_INDEX_ID_DESCRIPTION (entry));
break;
case GST_INDEX_ENTRY_FORMAT:
g_print ("%d: registered format %d for %s\n", entry->id,
GST_INDEX_FORMAT_FORMAT (entry),
GST_INDEX_FORMAT_KEY (entry));
break;
case GST_INDEX_ENTRY_ASSOCIATION:
{
gint i;
g_print ("%d: %08x ", entry->id, GST_INDEX_ASSOC_FLAGS (entry));
for (i = 0; i < GST_INDEX_NASSOCS (entry); i++) {
g_print ("%d %" G_GINT64_FORMAT, GST_INDEX_ASSOC_FORMAT (entry, i),
GST_INDEX_ASSOC_VALUE (entry, i));
}
g_print ("\n");
break;
}
default:
break;
}
}
*/
static void
gst_file_index_add_entry (GstIndex * index, GstIndexEntry * entry)
{
GST_LOG_OBJECT (index, "adding this entry");
switch (entry->type) {
case GST_INDEX_ENTRY_ID:
gst_file_index_add_id (index, entry);
break;
case GST_INDEX_ENTRY_ASSOCIATION:
gst_file_index_add_association (index, entry);
break;
case GST_INDEX_ENTRY_OBJECT:
GST_ERROR_OBJECT (index, "gst_file_index_add_object not implemented");
break;
case GST_INDEX_ENTRY_FORMAT:
/*
We infer the formats from the entry itself so this type of
GST_INDEX_ENTRY_* can probably go away.
*/
GST_DEBUG_OBJECT (index, "gst_file_index_add_format not implemented");
break;
default:
break;
}
}
static GstIndexEntry *
gst_file_index_get_assoc_entry (GstIndex * index,
gint id,
GstIndexLookupMethod method,
GstAssocFlags flags,
GstFormat format,
gint64 value, GCompareDataFunc _ignore_func, gpointer _ignore_user_data)
{
GstFileIndex *fileindex = GST_FILE_INDEX (index);
GstFileIndexId *id_index;
gint formatx = -1;
gint fx;
GstIndexAssociation sample;
gint mx;
gboolean exact;
gpointer row_data;
GstIndexEntry *entry;
gint xx;
g_return_val_if_fail (id > 0, NULL);
id_index = g_hash_table_lookup (fileindex->id_index, &id);
if (!id_index) {
GST_WARNING_OBJECT (fileindex, "writer %d unavailable", id);
return NULL;
}
for (fx = 0; fx < id_index->nformats; fx++)
if (id_index->format[fx] == format) {
formatx = fx;
break;
}
if (formatx == -1) {
GST_WARNING_OBJECT (fileindex, "format %d not available", format);
return NULL;
}
/* this is a hack, we should use a private structure instead */
sample.format = (GstFormat) formatx;
sample.value = value;
exact = _fc_bsearch (id_index->array, ARRAY_ROW_SIZE (id_index),
&mx, file_index_compare, &sample, id_index);
if (!exact) {
if (method == GST_INDEX_LOOKUP_EXACT)
return NULL;
else if (method == GST_INDEX_LOOKUP_BEFORE) {
if (mx == 0)
return NULL;
mx -= 1;
} else if (method == GST_INDEX_LOOKUP_AFTER) {
if (mx == id_index->array->len)
return NULL;
}
}
row_data = id_index->array->data + mx * ARRAY_ROW_SIZE (id_index);
/* if exact then ignore flags (?) */
if (method != GST_INDEX_LOOKUP_EXACT)
while ((GINT32_FROM_BE (ARRAY_ROW_FLAGS (row_data)) & flags) != flags) {
if (method == GST_INDEX_LOOKUP_BEFORE)
mx -= 1;
else if (method == GST_INDEX_LOOKUP_AFTER)
mx += 1;
if (mx < 0 || mx >= id_index->array->len)
return NULL;
row_data = id_index->array->data + mx * ARRAY_ROW_SIZE (id_index);
}
/* entry memory management needs improvement FIXME */
if (!fileindex->ret_entry)
fileindex->ret_entry = g_slice_new0 (GstIndexEntry);
entry = fileindex->ret_entry;
if (entry->data.assoc.assocs) {
g_free (entry->data.assoc.assocs);
entry->data.assoc.assocs = NULL;
}
entry->type = GST_INDEX_ENTRY_ASSOCIATION;
GST_INDEX_NASSOCS (entry) = id_index->nformats;
entry->data.assoc.assocs = g_new (GstIndexAssociation, id_index->nformats);
{
gint32 flags_be = ARRAY_ROW_FLAGS (row_data);
GST_INDEX_ASSOC_FLAGS (entry) = (GstAssocFlags) GINT32_FROM_BE (flags_be);
for (xx = 0; xx < id_index->nformats; xx++) {
gint64 val_be = ARRAY_ROW_VALUE (row_data, xx);
GST_INDEX_ASSOC_FORMAT (entry, xx) = id_index->format[xx];
GST_INDEX_ASSOC_VALUE (entry, xx) = GINT64_FROM_BE (val_be);
}
}
return entry;
}
gboolean
gst_file_index_plugin_init (GstPlugin * plugin)
{
GstIndexFactory *factory;
factory = gst_index_factory_new ("fileindex",
"A index that stores entries in file", gst_file_index_get_type ());
if (factory == NULL) {
return FALSE;
}
GST_PLUGIN_FEATURE (factory)->plugin_name = plugin->desc.name;
GST_PLUGIN_FEATURE (factory)->loaded = TRUE;
gst_registry_add_feature (gst_registry_get_default (),
GST_PLUGIN_FEATURE (factory));
GST_DEBUG_CATEGORY_INIT (DC, "GST_FILEINDEX", 0, NULL);
return TRUE;
}

View file

@ -1,43 +0,0 @@
/* GStreamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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 <gst/gst_private.h>
#include <gst/gstversion.h>
#include <gst/gstplugin.h>
#include "gstindexers.h"
static gboolean
plugin_init (GstPlugin * plugin)
{
gboolean res = TRUE;
res &= gst_mem_index_plugin_init (plugin);
/* FIXME 0.11: fix or remove GstFileIndex, which used mmap and libxml */
/* res &= gst_file_index_plugin_init (plugin); */
return res;
}
GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
GST_VERSION_MINOR,
"coreindexers",
"GStreamer core indexers",
plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN);

View file

@ -1,33 +0,0 @@
/* GStreamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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_INDEXERS_H__
#define __GST_INDEXERS_H__
G_BEGIN_DECLS
gboolean gst_mem_index_plugin_init (GstPlugin * plugin);
/* gboolean gst_file_index_plugin_init (GstPlugin * plugin); */
G_END_DECLS
#endif /* __GST_INDEXERS_H__ */

View file

@ -1013,6 +1013,7 @@ print_element_list (gboolean print_all)
g_print ("%s: %s: %s\n", plugin->desc.name,
GST_OBJECT_NAME (factory),
gst_element_factory_get_longname (factory));
#if 0
} else if (GST_IS_INDEX_FACTORY (feature)) {
GstIndexFactory *factory;
@ -1020,6 +1021,7 @@ print_element_list (gboolean print_all)
if (!print_all)
g_print ("%s: %s: %s\n", plugin->desc.name,
GST_OBJECT_NAME (factory), factory->longdesc);
#endif
} else if (GST_IS_TYPE_FIND_FACTORY (feature)) {
GstTypeFindFactory *factory;
@ -1206,12 +1208,14 @@ print_plugin_features (GstPlugin * plugin)
n_print (" %s: %s\n", GST_OBJECT_NAME (factory),
gst_element_factory_get_longname (factory));
num_elements++;
#if 0
} else if (GST_IS_INDEX_FACTORY (feature)) {
GstIndexFactory *factory;
factory = GST_INDEX_FACTORY (feature);
n_print (" %s: %s\n", GST_OBJECT_NAME (factory), factory->longdesc);
num_indexes++;
#endif
} else if (GST_IS_TYPE_FIND_FACTORY (feature)) {
GstTypeFindFactory *factory;
@ -1262,12 +1266,14 @@ print_element_features (const gchar * element_name)
GstPluginFeature *feature;
/* FIXME implement other pretty print function for these */
#if 0
feature = gst_default_registry_find_feature (element_name,
GST_TYPE_INDEX_FACTORY);
if (feature) {
n_print ("%s: an index\n", element_name);
return 0;
}
#endif
feature = gst_default_registry_find_feature (element_name,
GST_TYPE_TYPE_FIND_FACTORY);
if (feature) {

View file

@ -177,6 +177,7 @@ fault_setup (void)
}
#endif /* DISABLE_FAULT_HANDLER */
#if 0
typedef struct _GstIndexStats
{
gint id;
@ -329,6 +330,7 @@ print_index_stats (GPtrArray * index_stats)
}
}
}
#endif
/* Kids, use the functions from libgstpbutils in gst-plugins-base in your
* own code (we can't do that here because it would introduce a circular
@ -822,7 +824,9 @@ main (int argc, char *argv[])
gboolean no_fault = FALSE;
gboolean trace = FALSE;
gboolean eos_on_shutdown = FALSE;
#if 0
gboolean check_index = FALSE;
#endif
gchar *savefile = NULL;
gchar *exclude_args = NULL;
#ifndef GST_DISABLE_OPTION_PARSING
@ -843,16 +847,20 @@ main (int argc, char *argv[])
N_("Print alloc trace (if enabled at compile time)"), NULL},
{"eos-on-shutdown", 'e', 0, G_OPTION_ARG_NONE, &eos_on_shutdown,
N_("Force EOS on sources before shutting the pipeline down"), NULL},
#if 0
{"index", 'i', 0, G_OPTION_ARG_NONE, &check_index,
N_("Gather and print index statistics"), NULL},
#endif
GST_TOOLS_GOPTION_VERSION,
{NULL}
};
GOptionContext *ctx;
GError *err = NULL;
#endif
#if 0
GstIndex *index;
GPtrArray *index_stats = NULL;
#endif
gchar **argvn;
GError *error = NULL;
gint res = 0;
@ -953,7 +961,7 @@ main (int argc, char *argv[])
gst_bin_add (GST_BIN (real_pipeline), pipeline);
pipeline = real_pipeline;
}
#if 0
if (check_index) {
/* gst_index_new() creates a null-index, it does not store anything, but
* the entry-added signal works and this is what we use to build the
@ -968,6 +976,7 @@ main (int argc, char *argv[])
gst_element_set_index (pipeline, index);
}
}
#endif
bus = gst_element_get_bus (pipeline);
gst_bus_set_sync_handler (bus, bus_sync_handler, (gpointer) pipeline);
@ -1061,10 +1070,12 @@ main (int argc, char *argv[])
gst_element_set_state (pipeline, GST_STATE_READY);
gst_element_get_state (pipeline, &state, &pending, GST_CLOCK_TIME_NONE);
#if 0
if (check_index) {
print_index_stats (index_stats);
g_ptr_array_free (index_stats, TRUE);
}
#endif
end:
PRINT (_("Setting pipeline to NULL ...\n"));