mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-07 06:52:41 +00:00
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:
parent
7d6e165007
commit
be04f3945c
27 changed files with 63 additions and 1585 deletions
|
@ -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
|
||||
|
|
|
@ -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" />
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 \
|
||||
|
|
15
gst/gst.c
15
gst/gst.c
|
@ -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 ()));
|
||||
|
|
|
@ -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>
|
||||
|
|
16
gst/gstbin.c
16
gst/gstbin.c
|
@ -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 */
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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__ */
|
|
@ -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 ();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -1,6 +1,6 @@
|
|||
SUBDIRS = elements indexers
|
||||
SUBDIRS = elements
|
||||
|
||||
DIST_SUBDIRS = elements indexers
|
||||
DIST_SUBDIRS = elements
|
||||
|
||||
Android.mk: Makefile.am
|
||||
androgenizer -:PROJECT gstreamer \
|
||||
|
|
7
plugins/indexers/.gitignore
vendored
7
plugins/indexers/.gitignore
vendored
|
@ -1,7 +0,0 @@
|
|||
*.bb
|
||||
*.bbg
|
||||
*.da
|
||||
*.def
|
||||
*.gcno
|
||||
*.lo
|
||||
*.la
|
|
@ -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@ \
|
||||
> $@
|
||||
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
|
@ -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__ */
|
|
@ -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) {
|
||||
|
|
|
@ -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"));
|
||||
|
|
Loading…
Reference in a new issue