- Added first attempt at general caching mechanism (GstTimeCache renamed to GstCache)

Original commit message from CVS:
- Added first attempt at general caching mechanism (GstTimeCache renamed
to GstCache)
- Some more clocking checks and updates (waiting on GST_CLOCK_TIME_NONE
returns immediatly instead of blocking forever)
- Moved clock get/set functions to element class instead of instance.
- Added cache methods on elements.
- Renamed GST_PROPS_BOOL_TYPE to GST_PROPS_BOOLEAN_TYPE to make it more
consistent with gst_props_get/set_boolean and GST_PROPS_BOOLEAN.
- Give short stats about plugins in gst-inspect.
This commit is contained in:
Wim Taymans 2002-11-27 20:47:39 +00:00
parent 86376a2402
commit a48bce0ad6
16 changed files with 761 additions and 42 deletions

2
common

@ -1 +1 @@
Subproject commit 1ca7d9a20180cab830f4383cde5ba932338e50b1
Subproject commit f2d9b99515c73da09bfe307d273d320f79a226da

View file

@ -56,6 +56,7 @@ libgstreamer_la_SOURCES = \
gstbin.c \
gstbuffer.c \
gstbufferpool-default.c \
gstcache.c \
gstcaps.c \
gstclock.c \
gstcpu.c \
@ -83,7 +84,6 @@ libgstreamer_la_SOURCES = \
$(GST_TYPEFIND_SRC) \
gstutils.c \
gstregistry.c \
gsttimecache.c \
$(GST_PARSE_SRC) \
$(GSTARCH_SRCS) \
$(GST_LOADSAVE_SRC)
@ -103,6 +103,7 @@ gst_headers = \
gstbin.h \
gstbuffer.h \
gstbufferpool-default.h \
gstcache.h \
gstcaps.h \
gstclock.h \
gstcpu.h \
@ -129,7 +130,6 @@ gst_headers = \
gsttypefind.h \
gstutils.h \
gstregistry.h \
gsttimecache.h \
gstparse.h \
gstxml.h

View file

@ -134,6 +134,7 @@ gst_fakesink_class_init (GstFakeSinkClass *klass)
gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_fakesink_get_property);
gstelement_class->request_new_pad = GST_DEBUG_FUNCPTR (gst_fakesink_request_new_pad);
gstelement_class->set_clock = GST_DEBUG_FUNCPTR (gst_fakesink_set_clock);
}
static void
@ -150,8 +151,6 @@ gst_fakesink_init (GstFakeSink *fakesink)
fakesink->sync = FALSE;
fakesink->last_message = NULL;
GST_ELEMENT (fakesink)->setclockfunc = gst_fakesink_set_clock;
GST_FLAG_SET (fakesink, GST_ELEMENT_EVENT_AWARE);
}

View file

@ -35,6 +35,7 @@
#include <gst/gstpad.h>
#include <gst/gstbuffer.h>
#include <gst/gstbufferpool-default.h>
#include <gst/gstcache.h>
#include <gst/gstcpu.h>
#include <gst/gstelement.h>
#include <gst/gstbin.h>
@ -49,7 +50,6 @@
#include <gst/gsttrace.h>
#include <gst/gstxml.h>
#include <gst/gstscheduler.h>
#include <gst/gsttimecache.h>
#include <gst/gstevent.h>
#include <gst/gstclock.h>
#include <gst/gstsystemclock.h>

407
gst/gstcache.c Normal file
View file

@ -0,0 +1,407 @@
/* GStreamer
* Copyright (C) 2001 RidgeRun (http://www.ridgerun.com/)
* Written by Erik Walthinsen <omega@ridgerun.com>
*
* gstcache.c: Cache for mappings and other data
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include "gstlog.h"
#include "gst_private.h"
#include "gstcache.h"
/* Cache signals and args */
enum {
ENTRY_ADDED,
LAST_SIGNAL
};
enum {
ARG_0,
/* FILL ME */
};
static void gst_cache_class_init (GstCacheClass *klass);
static void gst_cache_init (GstCache *tc);
#define CLASS(cache) GST_CACHE_CLASS (G_OBJECT_GET_CLASS (cache))
static GstObject *parent_class = NULL;
static guint gst_cache_signals[LAST_SIGNAL] = { 0 };
GType
gst_cache_get_type(void) {
static GType tc_type = 0;
if (!tc_type) {
static const GTypeInfo tc_info = {
sizeof(GstCacheClass),
NULL,
NULL,
(GClassInitFunc)gst_cache_class_init,
NULL,
NULL,
sizeof(GstCache),
1,
(GInstanceInitFunc)gst_cache_init,
NULL
};
tc_type = g_type_register_static(GST_TYPE_OBJECT, "GstCache", &tc_info, 0);
}
return tc_type;
}
static void
gst_cache_class_init (GstCacheClass *klass)
{
GObjectClass *gobject_class;
GstElementClass *gstelement_class;
gobject_class = (GObjectClass*)klass;
gstelement_class = (GstElementClass*)klass;
parent_class = g_type_class_ref(GST_TYPE_OBJECT);
gst_cache_signals[ENTRY_ADDED] =
g_signal_new ("entry_added", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstCacheClass, entry_added), NULL, NULL,
gst_marshal_VOID__POINTER, G_TYPE_NONE, 1,
G_TYPE_POINTER);
}
static GstCacheGroup *
gst_cache_group_new(guint groupnum)
{
GstCacheGroup *tcgroup = g_new(GstCacheGroup,1);
tcgroup->groupnum = groupnum;
tcgroup->entries = NULL;
tcgroup->certainty = GST_CACHE_UNKNOWN;
tcgroup->peergroup = -1;
GST_DEBUG(0, "created new cache group %d",groupnum);
return tcgroup;
}
static void
gst_cache_init (GstCache *tc)
{
tc->curgroup = gst_cache_group_new(0);
tc->maxgroup = 0;
tc->groups = g_list_prepend(NULL, tc->curgroup);
tc->writers = g_hash_table_new (NULL, NULL);
tc->last_id = 0;
GST_DEBUG(0, "created new cache");
}
/**
* gst_cache_new:
*
* Create a new tilecache object
*
* Returns: a new cache object
*/
GstCache *
gst_cache_new()
{
GstCache *tc;
tc = g_object_new (gst_cache_get_type (), NULL);
return tc;
}
/**
* gst_cache_get_group:
* @tc: the cache to get the current group from
*
* Get the id of the current group.
*
* Returns: the id of the current group.
*/
gint
gst_cache_get_group(GstCache *tc)
{
return tc->curgroup->groupnum;
}
/**
* gst_cache_new_group:
* @tc: the cache to create the new group in
*
* Create a new group for the given cache. It will be
* set as the current group.
*
* Returns: the id of the newly created group.
*/
gint
gst_cache_new_group(GstCache *tc)
{
tc->curgroup = gst_cache_group_new(++tc->maxgroup);
tc->groups = g_list_append(tc->groups,tc->curgroup);
GST_DEBUG(0, "created new group %d in cache",tc->maxgroup);
return tc->maxgroup;
}
/**
* gst_cache_set_group:
* @tc: the cache to set the new group in
* @groupnum: the groupnumber to set
*
* Set the current groupnumber to the given argument.
*
* Returns: TRUE if the operation succeeded, FALSE if the group
* did not exist.
*/
gboolean
gst_cache_set_group(GstCache *tc, gint groupnum)
{
GList *list;
GstCacheGroup *tcgroup;
/* first check for null change */
if (groupnum == tc->curgroup->groupnum)
return TRUE;
/* else search for the proper group */
list = tc->groups;
while (list) {
tcgroup = (GstCacheGroup *)(list->data);
list = g_list_next(list);
if (tcgroup->groupnum == groupnum) {
tc->curgroup = tcgroup;
GST_DEBUG(0, "switched to cache group %d", tcgroup->groupnum);
return TRUE;
}
}
/* couldn't find the group in question */
GST_DEBUG(0, "couldn't find cache group %d",groupnum);
return FALSE;
}
/**
* gst_cache_set_certainty:
* @tc: the cache to set the certainty on
* @certainty: the certainty to set
*
* Set the certainty of the given cache.
*/
void
gst_cache_set_certainty(GstCache *tc, GstCacheCertainty certainty)
{
tc->curgroup->certainty = certainty;
}
/**
* gst_cache_get_certainty:
* @tc: the cache to get the certainty of
*
* Get the certainty of the given cache.
*
* Returns: the certainty of the cache.
*/
GstCacheCertainty
gst_cache_get_certainty(GstCache *tc)
{
return tc->curgroup->certainty;
}
/**
* gst_cache_add_format:
* @tc: the cache to add the entry to
* @id: the id of the cache writer
* @format: the format to add to the cache
*
* Adds a format entry into the cache. This function is
* used to map dynamic GstFormat ids to their original
* format key.
*
* Returns: a pointer to the newly added entry in the cache.
*/
GstCacheEntry*
gst_cache_add_format (GstCache *tc, gint id, GstFormat format)
{
GstCacheEntry *entry;
const GstFormatDefinition* def;
g_return_val_if_fail (GST_IS_CACHE (tc), NULL);
g_return_val_if_fail (format != 0, NULL);
entry = g_new0 (GstCacheEntry, 1);
entry->type = GST_CACHE_ENTRY_FORMAT;
entry->id = id;
entry->data.format.format = format;
def = gst_format_get_details (format);
entry->data.format.key = def->nick;
g_signal_emit (G_OBJECT (tc), gst_cache_signals[ENTRY_ADDED], 0, entry);
return entry;
}
/**
* gst_cache_add_id:
* @tc: the cache to add the entry to
* @id: the id of the cache writer
* @description: the description of the cache writer
*
* Returns: a pointer to the newly added entry in the cache.
*/
GstCacheEntry*
gst_cache_add_id (GstCache *tc, gint id, gchar *description)
{
GstCacheEntry *entry;
g_return_val_if_fail (GST_IS_CACHE (tc), NULL);
g_return_val_if_fail (description != NULL, NULL);
entry = g_new0 (GstCacheEntry, 1);
entry->type = GST_CACHE_ENTRY_ID;
entry->id = id;
entry->data.id.description = description;
g_signal_emit (G_OBJECT (tc), gst_cache_signals[ENTRY_ADDED], 0, entry);
return entry;
}
/**
* gst_cache_get_writer_id:
* @tc: the cache to get a unique write id for
* @writer: the GstObject to allocate an id for
* @id: a pointer to a gint to hold the id
*
* Before entries can be added to the cache, a writer
* should obtain a unique id. The methods to add new entries
* to the cache require this id as an argument.
*
* The application or a GstCache subclass can implement
* custom functions to map the writer object to an id.
*
* Returns: TRUE if the writer would be mapped to an id.
*/
gboolean
gst_cache_get_writer_id (GstCache *tc, GstObject *writer, gint *id)
{
gchar *writer_string = NULL;
gboolean success = FALSE;
GstCacheEntry *entry;
g_return_val_if_fail (GST_IS_CACHE (tc), FALSE);
g_return_val_if_fail (GST_IS_OBJECT (writer), FALSE);
g_return_val_if_fail (id, FALSE);
*id = -1;
entry = g_hash_table_lookup (tc->writers, writer);
if (entry == NULL) {
*id = tc->last_id;
writer_string = gst_object_get_path_string (writer);
gst_cache_add_id (tc, *id, writer_string);
tc->last_id++;
g_hash_table_insert (tc->writers, writer, entry);
}
if (CLASS (tc)->resolve_writer) {
success = CLASS (tc)->resolve_writer (tc, writer, id, &writer_string);
}
if (tc->resolver) {
success = tc->resolver (tc, writer, id, &writer_string, tc->user_data);
}
return success;
}
/**
* gst_cache_add_association:
* @tc: the cache to add the entry to
* @id: the id of the cache writer
* @format: the format of the value
* @value: the value
* @...: other format/value pairs or 0 to end the list
*
* Associate given format/value pairs with eachother.
*
* Returns: a pointer to the newly added entry in the cache.
*/
GstCacheEntry*
gst_cache_add_association (GstCache *tc, gint id, GstAssocFlags flags,
GstFormat format, gint64 value, ...)
{
va_list args;
GstCacheAssociation *assoc;
GstCacheEntry *entry;
gulong size;
gint nassocs = 0;
GstFormat cur_format;
g_return_val_if_fail (GST_IS_CACHE (tc), NULL);
g_return_val_if_fail (format != 0, NULL);
va_start (args, value);
cur_format = format;
while (cur_format) {
nassocs++;
cur_format = va_arg (args, GstFormat);
if (cur_format)
va_arg (args, gint64);
}
va_end (args);
/* make room for two assoc */
size = sizeof (GstCacheEntry) + (sizeof (GstCacheAssociation) * nassocs);
entry = g_malloc (size);
entry->type = GST_CACHE_ENTRY_ASSOCIATION;
entry->id = id;
entry->data.assoc.flags = flags;
assoc = (GstCacheAssociation *) (((guint8 *) entry) + sizeof (GstCacheEntry));
entry->data.assoc.assocs = assoc;
entry->data.assoc.nassocs = nassocs;
va_start (args, value);
while (format) {
assoc->format = format;
assoc->value = value;
assoc++;
format = va_arg (args, GstFormat);
if (format)
value = va_arg (args, gint64);
}
va_end (args);
if (CLASS (tc)->add_entry)
CLASS (tc)->add_entry (tc, entry);
g_signal_emit (G_OBJECT (tc), gst_cache_signals[ENTRY_ADDED], 0, entry);
return entry;
}

182
gst/gstcache.h Normal file
View file

@ -0,0 +1,182 @@
/* GStreamer
* Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
* 2000 Wim Taymans <wim.taymans@chello.be>
*
* gstcache.h: Header for GstCache
*
* 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_CACHE_H__
#define __GST_CACHE_H__
#include <gst/gstobject.h>
#include <gst/gstformat.h>
#include <gst/gstcaps.h>
G_BEGIN_DECLS
#define GST_TYPE_CACHE (gst_cache_get_type ())
#define GST_CACHE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_CACHE, GstCache))
#define GST_CACHE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_CACHE, GstCacheClass))
#define GST_IS_CACHE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_CACHE))
#define GST_IS_CACHE_CLASS(obj) (GST_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_CACHE))
typedef struct _GstCacheEntry GstCacheEntry;
typedef struct _GstCacheGroup GstCacheGroup;
typedef struct _GstCache GstCache;
typedef struct _GstCacheClass GstCacheClass;
typedef enum {
GST_CACHE_UNKNOWN,
GST_CACHE_CERTAIN,
GST_CACHE_FUZZY
} GstCacheCertainty;
typedef enum {
GST_CACHE_ENTRY_ID,
GST_CACHE_ENTRY_ASSOCIATION,
GST_CACHE_ENTRY_OBJECT,
GST_CACHE_ENTRY_FORMAT,
} GstCacheEntryType;
#define GST_CACHE_NASSOCS(entry) ((entry)->data.assoc.nassocs)
#define GST_CACHE_ASSOC_FLAGS(entry) ((entry)->data.assoc.flags)
#define GST_CACHE_ASSOC_FORMAT(entry,i) ((entry)->data.assoc.assocs[(i)].format)
#define GST_CACHE_ASSOC_VALUE(entry,i) ((entry)->data.assoc.assocs[(i)].value)
typedef struct _GstCacheAssociation GstCacheAssociation;
struct _GstCacheAssociation {
GstFormat format;
gint64 value;
};
typedef enum {
GST_ACCOCIATION_FLAG_NONE = 0,
GST_ACCOCIATION_FLAG_KEY_UNIT = (1 << 0),
} GstAssocFlags;
#define GST_CACHE_FORMAT_FORMAT(entry) ((entry)->data.format.format)
#define GST_CACHE_FORMAT_KEY(entry) ((entry)->data.format.key)
#define GST_CACHE_ID_DESCRIPTION(entry) ((entry)->data.id.description)
struct _GstCacheEntry {
GstCacheEntryType type;
gint id;
union {
struct {
gchar *description;
} id;
struct {
gint nassocs;
GstCacheAssociation
*assocs;
GstAssocFlags flags;
} assoc;
struct {
gchar *key;
GType type;
gpointer object;
} object;
struct {
GstFormat format;
gchar *key;
} format;
} data;
};
struct _GstCacheGroup {
/* unique ID of group in cache */
gint groupnum;
/* list of entries */
GList *entries;
/* the certainty level of the group */
GstCacheCertainty certainty;
/* peer group that contains more certain entries */
gint peergroup;
};
typedef gboolean (*GstCacheWriterResolver) (GstCache *cache,
GstObject *writer,
gint *writer_id,
gchar **writer_string,
gpointer user_data);
struct _GstCache {
GstObject object;
GList *groups;
GstCacheGroup *curgroup;
gint maxgroup;
GstCacheWriterResolver resolver;
gpointer user_data;
GHashTable *writers;
gint last_id;
};
struct _GstCacheClass {
GstObjectClass parent_class;
gboolean (*resolve_writer) (GstCache *cache, GstObject *writer,
gint *writer_id, gchar **writer_string);
/* abstract methods */
void (*add_entry) (GstCache *cache, GstCacheEntry *entry);
void (*remove_entry) (GstCache *cache, GstCacheEntry *entry);
void (*modify_entry) (GstCache *cache, GstCacheEntry *oldentry,
GstCacheEntry *new_entry);
GstCacheEntry* (*get_entry) (GstCache *cache);
/* signals */
void (*entry_added) (GstCache *cache, GstCacheEntry *entry);
void (*entry_removed) (GstCache *cache, GstCacheEntry *entry);
void (*entry_modified) (GstCache *cache, GstCacheEntry *oldentry,
GstCacheEntry *new_entry);
};
GType gst_cache_get_type (void);
GstCache* gst_cache_new (void);
gint gst_cache_get_group (GstCache *cache);
gint gst_cache_new_group (GstCache *cache);
gboolean gst_cache_set_group (GstCache *cache, gint groupnum);
void gst_cache_set_certainty (GstCache *cache,
GstCacheCertainty certainty);
GstCacheCertainty gst_cache_get_certainty (GstCache *cache);
gboolean gst_cache_get_writer_id (GstCache *cache, GstObject *writer, gint *id);
GstCacheEntry* gst_cache_add_format (GstCache *cache, gint id, GstFormat format);
GstCacheEntry* gst_cache_add_association (GstCache *cache, gint id, GstAssocFlags flags,
GstFormat format, gint64 value, ...);
GstCacheEntry* gst_cache_add_object (GstCache *cache, gint id, gchar *key,
GType type, gpointer object);
GstCacheEntry* gst_cache_add_id (GstCache *cache, gint id,
gchar *description);
G_END_DECLS
#endif /* __GST_CACHE_H__ */

View file

@ -83,6 +83,8 @@ gst_clock_entry_new (GstClock *clock, GstClockTime time,
GstClockID
gst_clock_new_single_shot_id (GstClock *clock, GstClockTime time)
{
g_return_val_if_fail (GST_IS_CLOCK (clock), NULL);
return gst_clock_entry_new (clock,
time,
GST_CLOCK_TIME_NONE,
@ -105,6 +107,10 @@ GstClockID
gst_clock_new_periodic_id (GstClock *clock, GstClockTime start_time,
GstClockTime interval)
{
g_return_val_if_fail (GST_IS_CLOCK (clock), NULL);
g_return_val_if_fail (start_time != GST_CLOCK_TIME_NONE, NULL);
g_return_val_if_fail (interval != 0, NULL);
return gst_clock_entry_new (clock,
start_time,
interval,
@ -149,8 +155,14 @@ gst_clock_id_wait (GstClockID id, GstClockTimeDiff *jitter)
g_return_val_if_fail (id != NULL, GST_CLOCK_ERROR);
entry = (GstClockEntry *) id;
clock = GST_CLOCK_ENTRY_CLOCK (entry);
requested = GST_CLOCK_ENTRY_TIME (entry);
if (requested == GST_CLOCK_TIME_NONE) {
res = GST_CLOCK_TIMEOUT;
goto done;
}
clock = GST_CLOCK_ENTRY_CLOCK (entry);
if (CLASS (clock)->wait) {
GstClockTime now;
@ -170,6 +182,7 @@ gst_clock_id_wait (GstClockID id, GstClockTimeDiff *jitter)
}
}
done:
if (entry->type == GST_CLOCK_ENTRY_SINGLE) {
gst_clock_id_free (id);
}
@ -188,7 +201,7 @@ gst_clock_id_wait (GstClockID id, GstClockTimeDiff *jitter)
* when the clock has reached the given time. A ClockID is returned
* that can be used to cancel the request.
*
* Returns: the clock id or NULL when async notification is not supported.
* Returns: the result of the non blocking wait.
*/
GstClockReturn
gst_clock_id_wait_async (GstClockID id,
@ -199,10 +212,16 @@ gst_clock_id_wait_async (GstClockID id,
GstClockReturn res = GST_CLOCK_UNSUPPORTED;
g_return_val_if_fail (id != NULL, GST_CLOCK_ERROR);
g_return_val_if_fail (func != NULL, GST_CLOCK_ERROR);
entry = (GstClockEntry *) id;
clock = entry->clock;
if (GST_CLOCK_ENTRY_TIME (entry) == GST_CLOCK_TIME_NONE) {
(func) (clock, GST_CLOCK_TIME_NONE, id, user_data);
return GST_CLOCK_TIMEOUT;
}
if (CLASS (clock)->wait_async) {
res = CLASS (clock)->wait_async (clock, entry, func, user_data);
}
@ -243,6 +262,8 @@ gst_clock_id_unschedule (GstClockID id)
void
gst_clock_id_free (GstClockID id)
{
g_return_if_fail (id != NULL);
gst_mem_chunk_free (_gst_clock_entries_chunk, id);
}
@ -389,6 +410,7 @@ guint64
gst_clock_set_resolution (GstClock *clock, guint64 resolution)
{
g_return_val_if_fail (GST_IS_CLOCK (clock), 0LL);
g_return_val_if_fail (resolution != 0, 0LL);
if (CLASS (clock)->change_resolution)
clock->resolution = CLASS (clock)->change_resolution (clock, clock->resolution, resolution);
@ -510,6 +532,9 @@ gst_clock_handle_discont (GstClock *clock, guint64 time)
GST_DEBUG (GST_CAT_CLOCK, "clock discont %llu %llu %d", time, clock->start_time, clock->accept_discont);
if (time == GST_CLOCK_TIME_NONE)
return TRUE;
GST_LOCK (clock);
if (clock->accept_discont) {
if (CLASS (clock)->get_internal_time) {
@ -585,6 +610,8 @@ gst_clock_get_next_id (GstClock *clock)
{
GstClockEntry *entry = NULL;
g_return_val_if_fail (GST_IS_CLOCK (clock), NULL);
GST_LOCK (clock);
if (clock->entries)
entry = GST_CLOCK_ENTRY (clock->entries->data);

View file

@ -741,6 +741,38 @@ gst_element_get_parent (GstElement *element)
return GST_OBJECT_PARENT (element);
}
/**
* gst_element_requires_clock:
* @element: a #GstElement to query
*
* Query if the element requiresd a clock
*
* Returns: TRUE if the element requires a clock
*/
gboolean
gst_element_requires_clock (GstElement *element)
{
g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
return (CLASS (element)->set_clock != NULL);
}
/**
* gst_element_provides_clock:
* @element: a #GstElement to query
*
* Query if the element provides a clock
*
* Returns: TRUE if the element provides a clock
*/
gboolean
gst_element_provides_clock (GstElement *element)
{
g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
return (CLASS (element)->get_clock != NULL);
}
/**
* gst_element_set_clock:
* @element: a #GstElement to set the clock for.
@ -751,11 +783,10 @@ gst_element_get_parent (GstElement *element)
void
gst_element_set_clock (GstElement *element, GstClock *clock)
{
g_return_if_fail (element != NULL);
g_return_if_fail (GST_IS_ELEMENT (element));
if (element->setclockfunc)
element->setclockfunc (element, clock);
if (CLASS (element)->set_clock)
CLASS (element)->set_clock (element, clock);
element->clock = clock;
}
@ -774,8 +805,8 @@ gst_element_get_clock (GstElement *element)
g_return_val_if_fail (element != NULL, NULL);
g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
if (element->getclockfunc)
return element->getclockfunc (element);
if (CLASS (element)->get_clock)
return CLASS (element)->get_clock (element);
return NULL;
}
@ -796,7 +827,6 @@ gst_element_clock_wait (GstElement *element, GstClock *clock, GstClockTime time,
{
GstClockReturn res;
g_return_val_if_fail (element != NULL, GST_CLOCK_ERROR);
g_return_val_if_fail (GST_IS_ELEMENT (element), GST_CLOCK_ERROR);
if (GST_ELEMENT_SCHED (element)) {
@ -808,6 +838,35 @@ gst_element_clock_wait (GstElement *element, GstClock *clock, GstClockTime time,
return res;
}
gboolean
gst_element_is_cachable (GstElement *element)
{
g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
return (CLASS (element)->set_cache != NULL);
}
void
gst_element_set_cache (GstElement *element, GstCache *cache)
{
g_return_if_fail (GST_IS_ELEMENT (element));
g_return_if_fail (GST_IS_CACHE (cache));
if (CLASS (element)->set_cache)
CLASS (element)->set_cache (element, cache);
}
GstCache*
gst_element_get_cache (GstElement *element)
{
g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
if (CLASS (element)->get_cache)
return CLASS (element)->get_cache (element);
return NULL;
}
/**
* gst_element_release_locks:

View file

@ -30,6 +30,7 @@
#include <gst/gstpad.h>
#include <gst/gstclock.h>
#include <gst/gstpluginfeature.h>
#include <gst/gstcache.h>
G_BEGIN_DECLS
@ -109,8 +110,6 @@ typedef struct _GstElementFactory GstElementFactory;
typedef struct _GstElementFactoryClass GstElementFactoryClass;
typedef void (*GstElementLoopFunction) (GstElement *element);
typedef void (*GstElementSetClockFunction) (GstElement *element, GstClock *clock);
typedef GstClock* (*GstElementGetClockFunction) (GstElement *element);
typedef void (*GstElementPreRunFunction) (GstElement *element);
typedef void (*GstElementPostRunFunction) (GstElement *element);
@ -125,8 +124,6 @@ struct _GstElement {
GstScheduler *sched;
gpointer sched_private;
GstElementSetClockFunction setclockfunc;
GstElementGetClockFunction getclockfunc;
GstClock *clock;
GstClockTime base_time;
@ -176,6 +173,12 @@ struct _GstElementClass {
/* request a new pad */
GstPad* (*request_new_pad) (GstElement *element, GstPadTemplate *templ, const gchar* name);
void (*release_pad) (GstElement *element, GstPad *pad);
/* set/get clocks */
GstClock* (*get_clock) (GstElement *element);
void (*set_clock) (GstElement *element, GstClock *clock);
/* cache */
GstCache* (*get_cache) (GstElement *element);
void (*set_cache) (GstElement *element, GstCache *cache);
};
void gst_element_class_add_pad_template (GstElementClass *klass, GstPadTemplate *templ);
@ -214,10 +217,18 @@ const gchar* gst_element_get_name (GstElement *element);
void gst_element_set_parent (GstElement *element, GstObject *parent);
GstObject* gst_element_get_parent (GstElement *element);
/* clocking */
gboolean gst_element_requires_clock (GstElement *element);
gboolean gst_element_provides_clock (GstElement *element);
GstClock* gst_element_get_clock (GstElement *element);
void gst_element_set_clock (GstElement *element, GstClock *clock);
GstClockReturn gst_element_clock_wait (GstElement *element, GstClock *clock,
GstClockTime time, GstClockTimeDiff *jitter);
/* caches */
gboolean gst_element_is_cachable (GstElement *element);
void gst_element_set_cache (GstElement *element, GstCache *cache);
GstCache* gst_element_get_cache (GstElement *element);
gboolean gst_element_release_locks (GstElement *element);

View file

@ -92,6 +92,10 @@ transform_func (const GValue *src_value,
case GST_PROPS_FOURCC_TYPE:
g_string_append_printf (result, "%s=(fourcc) '%4.4s'", name, (gchar *)&entry->data.fourcc_data);
break;
case GST_PROPS_BOOLEAN_TYPE:
g_string_append_printf (result, "%s=(boolean) %s", name,
(entry->data.bool_data ? "TRUE" : "FALSE"));
break;
default:
break;
}
@ -147,7 +151,7 @@ gst_props_debug_entry (GstPropsEntry *entry)
(entry->data.fourcc_data>>16)&0xff,
(entry->data.fourcc_data>>24)&0xff);
break;
case GST_PROPS_BOOL_TYPE:
case GST_PROPS_BOOLEAN_TYPE:
GST_DEBUG (GST_CAT_PROPERTIES, "%s: bool %d", name, entry->data.bool_data);
break;
case GST_PROPS_STRING_TYPE:
@ -223,7 +227,7 @@ G_STMT_START { \
case GST_PROPS_FOURCC_TYPE: \
entry->data.fourcc_data = va_arg (var_args, gulong); \
break; \
case GST_PROPS_BOOL_TYPE: \
case GST_PROPS_BOOLEAN_TYPE: \
entry->data.bool_data = va_arg (var_args, gboolean); \
break; \
case GST_PROPS_STRING_TYPE: \
@ -269,7 +273,7 @@ G_STMT_START { \
case GST_PROPS_FOURCC_TYPE: \
*(va_arg (var_args, guint32*)) = entry->data.fourcc_data; \
break; \
case GST_PROPS_BOOL_TYPE: \
case GST_PROPS_BOOLEAN_TYPE: \
*(va_arg (var_args, gboolean*)) = entry->data.bool_data; \
break; \
case GST_PROPS_STRING_TYPE: \
@ -606,7 +610,7 @@ gst_props_newv (const gchar *firstname, va_list var_args)
entry_type = GST_PROPS_LIST_T_FLOATS;
break;
case GST_PROPS_FOURCC_TYPE:
case GST_PROPS_BOOL_TYPE:
case GST_PROPS_BOOLEAN_TYPE:
case GST_PROPS_STRING_TYPE:
entry_type = GST_PROPS_LIST_T_MISC;
break;
@ -1179,7 +1183,7 @@ gst_props_entry_get_fourcc_int (const GstPropsEntry *entry, guint32 *val)
gboolean
gst_props_entry_get_boolean (const GstPropsEntry *entry, gboolean *val)
{
return gst_props_entry_get_safe (entry, GST_PROPS_BOOL_TYPE, val);
return gst_props_entry_get_safe (entry, GST_PROPS_BOOLEAN_TYPE, val);
}
/**
@ -1391,10 +1395,10 @@ gst_props_entry_check_compatibility (GstPropsEntry *entry1, GstPropsEntry *entry
break;
}
break;
case GST_PROPS_BOOL_TYPE:
case GST_PROPS_BOOLEAN_TYPE:
switch (entry2->propstype) {
/* t <---> t */
case GST_PROPS_BOOL_TYPE:
case GST_PROPS_BOOLEAN_TYPE:
return (entry2->data.bool_data == entry1->data.bool_data);
default:
break;
@ -1669,10 +1673,10 @@ gst_props_entry_intersect (GstPropsEntry *entry1, GstPropsEntry *entry2)
break;
}
break;
case GST_PROPS_BOOL_TYPE:
case GST_PROPS_BOOLEAN_TYPE:
switch (entry2->propstype) {
/* t <---> t */
case GST_PROPS_BOOL_TYPE:
case GST_PROPS_BOOLEAN_TYPE:
if (entry1->data.bool_data == entry2->data.bool_data)
result = gst_props_entry_copy (entry1);
default:
@ -1928,7 +1932,7 @@ gst_props_save_thyself_func (GstPropsEntry *entry, xmlNodePtr parent)
xmlNewProp (subtree, "hexvalue", str);
g_free(str);
break;
case GST_PROPS_BOOL_TYPE:
case GST_PROPS_BOOLEAN_TYPE:
subtree = xmlNewChild (parent, NULL, "boolean", NULL);
xmlNewProp (subtree, "name", g_quark_to_string (entry->propid));
xmlNewProp (subtree, "value", (entry->data.bool_data ? "true" : "false"));
@ -2035,7 +2039,7 @@ gst_props_load_thyself_func (xmlNodePtr field)
g_free (prop);
}
else if (!strcmp(field->name, "boolean")) {
entry->propstype = GST_PROPS_BOOL_TYPE;
entry->propstype = GST_PROPS_BOOLEAN_TYPE;
prop = xmlGetProp(field, "name");
entry->propid = g_quark_from_string (prop);
g_free (prop);

View file

@ -43,7 +43,7 @@ typedef enum {
GST_PROPS_INT_TYPE,
GST_PROPS_FLOAT_TYPE,
GST_PROPS_FOURCC_TYPE,
GST_PROPS_BOOL_TYPE,
GST_PROPS_BOOLEAN_TYPE,
GST_PROPS_STRING_TYPE,
GST_PROPS_VAR_TYPE, /* after this marker start the variable properties */
@ -66,7 +66,7 @@ typedef enum {
#define GST_PROPS_FLOAT(a) GST_PROPS_FLOAT_TYPE,((float)(a))
#define GST_PROPS_FLOAT_RANGE(a,b) GST_PROPS_FLOAT_RANGE_TYPE,((float)(a)),((float)(b))
#define GST_PROPS_FOURCC(a) GST_PROPS_FOURCC_TYPE,(a)
#define GST_PROPS_BOOLEAN(a) GST_PROPS_BOOL_TYPE,(a)
#define GST_PROPS_BOOLEAN(a) GST_PROPS_BOOLEAN_TYPE,(a)
#define GST_PROPS_STRING(a) GST_PROPS_STRING_TYPE,(a)
#define GST_PROPS_INT_POSITIVE GST_PROPS_INT_RANGE(0,G_MAXINT)

View file

@ -212,11 +212,11 @@ gst_scheduler_add_element (GstScheduler *sched, GstElement *element)
/* if it's not inside this scheduler, it has to be NULL */
g_assert (GST_ELEMENT_SCHED (element) == NULL);
if (element->getclockfunc) {
if (gst_element_provides_clock (element)) {
sched->clock_providers = g_list_prepend (sched->clock_providers, element);
GST_DEBUG (GST_CAT_CLOCK, "added clock provider %s", GST_ELEMENT_NAME (element));
}
if (element->setclockfunc) {
if (gst_element_requires_clock (element)) {
sched->clock_receivers = g_list_prepend (sched->clock_receivers, element);
GST_DEBUG (GST_CAT_CLOCK, "added clock receiver %s", GST_ELEMENT_NAME (element));
}

View file

@ -506,7 +506,7 @@ gst_print_props (GString *buf, gint indent, GList *props, gboolean showname)
g_string_append_printf (buf, "%f - %f (float)\n", min, max);
break;
}
case GST_PROPS_BOOL_TYPE:
case GST_PROPS_BOOLEAN_TYPE:
{
gboolean val;
gst_props_entry_get_boolean (prop, &val);

View file

@ -1233,7 +1233,7 @@ gst_xml_registry_save_props_func (GstPropsEntry *entry,
CLASS (xmlregistry)->save_func (xmlregistry, "<fourcc name=\"%s\" hexvalue=\"%08x\"/>\n", name, fourcc);
break;
}
case GST_PROPS_BOOL_TYPE:
case GST_PROPS_BOOLEAN_TYPE:
{
gboolean value;
gst_props_entry_get_boolean (entry, &value);

View file

@ -134,6 +134,7 @@ gst_fakesink_class_init (GstFakeSinkClass *klass)
gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_fakesink_get_property);
gstelement_class->request_new_pad = GST_DEBUG_FUNCPTR (gst_fakesink_request_new_pad);
gstelement_class->set_clock = GST_DEBUG_FUNCPTR (gst_fakesink_set_clock);
}
static void
@ -150,8 +151,6 @@ gst_fakesink_init (GstFakeSink *fakesink)
fakesink->sync = FALSE;
fakesink->last_message = NULL;
GST_ELEMENT (fakesink)->setclockfunc = gst_fakesink_set_clock;
GST_FLAG_SET (fakesink, GST_ELEMENT_EVENT_AWARE);
}

View file

@ -43,7 +43,7 @@ print_prop (GstPropsEntry *prop, gboolean showname, const gchar *pfx)
g_print("Float range: %f - %f\n", min, max);
break;
}
case GST_PROPS_BOOL_TYPE:
case GST_PROPS_BOOLEAN_TYPE:
{
gboolean val;
gst_props_entry_get_boolean (prop, &val);
@ -571,22 +571,31 @@ print_element_info (GstElementFactory *factory)
have_flags = FALSE;
g_print ("\nClocking Interaction:\n");
if (element->setclockfunc) {
if (gst_element_requires_clock (element)) {
g_print (" element requires a clock\n");
have_flags = TRUE;
}
if (element->getclockfunc) {
if (gst_element_provides_clock (element)) {
GstClock *clock;
clock = gst_element_get_clock (element);
if (clock)
g_print (" element provides a clock: %s\n", GST_OBJECT_NAME(clock));
else
g_print (" element is supposed to provide a clock but returned NULL\n");
have_flags = TRUE;
}
if (!have_flags) {
g_print (" none\n");
}
g_print ("\nCaching capabilities:\n");
if (gst_element_is_cachable (element)) {
g_print (" element can do caching\n");
}
else {
g_print (" none\n");
}
g_print ("\nPads:\n");
if (element->numpads) {
@ -841,6 +850,12 @@ static void
print_plugin_info (GstPlugin *plugin)
{
GList *features;
gint num_features = 0;
gint num_elements = 0;
gint num_autoplug = 0;
gint num_types = 0;
gint num_schedulers = 0;
gint num_other = 0;
g_print ("Plugin Details:\n");
g_print (" Name:\t\t%s\n", plugin->name);
@ -861,12 +876,14 @@ print_plugin_info (GstPlugin *plugin)
factory = GST_ELEMENT_FACTORY (feature);
g_print (" %s: %s\n", GST_OBJECT_NAME (factory),
factory->details->longname);
num_elements++;
}
else if (GST_IS_AUTOPLUG_FACTORY (feature)) {
GstAutoplugFactory *factory;
factory = GST_AUTOPLUG_FACTORY (feature);
g_print (" %s: %s\n", GST_OBJECT_NAME (factory), factory->longdesc);
num_autoplug++;
}
else if (GST_IS_TYPE_FACTORY (feature)) {
GstTypeFactory *factory;
@ -877,21 +894,35 @@ print_plugin_info (GstPlugin *plugin)
if (factory->typefindfunc)
g_print (" Has typefind function: %s\n",
GST_DEBUG_FUNCPTR_NAME (factory->typefindfunc));
num_types++;
}
else if (GST_IS_SCHEDULER_FACTORY (feature)) {
GstSchedulerFactory *factory;
factory = GST_SCHEDULER_FACTORY (feature);
g_print (" %s: %s\n", GST_OBJECT_NAME (factory), factory->longdesc);
num_schedulers++;
}
else {
g_print (" %s (%s)\n", gst_object_get_name (GST_OBJECT (feature)),
g_type_name (G_OBJECT_TYPE (feature)));
num_other++;
}
num_features++;
features = g_list_next (features);
}
g_print ("\n %d features:\n", num_features);
if (num_elements > 0)
g_print (" +-- %d elements\n", num_elements);
if (num_autoplug > 0)
g_print (" +-- %d autopluggers\n", num_autoplug);
if (num_types > 0)
g_print (" +-- %d types\n", num_types);
if (num_schedulers > 0)
g_print (" +-- %d schedulers\n", num_schedulers);
if (num_other > 0)
g_print (" +-- %d other objects\n", num_other);
g_print ("\n");
}