- Remove the propsprivate header file

Original commit message from CVS:
- Remove the propsprivate header file
- Added new API for properties.
- Moved the clock distribution to the scheduler.
- Removed the lock from GstCaps
- Added boxed types for Caps/Props
- Simplified the clock, new systemclock implementation
- Removed deprecated element_info/send_event functions
- First step at exposing more info in the pad_connect functions
- Queue cleanup
- Make the scheduler aware of other schedulers inside it
- Added the _SELF_SCHEDULABLE flag to gstthread
- Removed _get_widget from _utils, changed to new props API
- Make fakesink sync on timestamps when requested
- Removed the offset notify from filesrc
- Added a fast scheduler
- some scheduler cleanups.
This commit is contained in:
Wim Taymans 2002-03-30 17:05:03 +00:00
parent 2ed5aa240c
commit f0326eea55
39 changed files with 2274 additions and 820 deletions

View file

@ -145,19 +145,18 @@ libgstreamerinclude_HEADERS = \
noinst_HEADERS = \
gst_private.h \
gstarch.h \
gstpropsprivate.h \
cothreads.h
libgstreamer_la_CFLAGS = -D_GNU_SOURCE -DGST_CONFIG_DIR=\""$(GST_CONFIG_DIR)"\" \
$(LIBGST_CFLAGS) \
-D_GNU_SOURCE \
-DG_LOG_DOMAIN=g_log_domain_gstreamer \
-DGST_CONFIG_DIR=\""$(GST_CONFIG_DIR)"\"
-DGST_CONFIG_DIR=\""$(GST_CONFIG_DIR)"\"
# the compiler shoots cothreads.c in the head at -O6
libcothreads_la_CFLAGS = $(libgstreamer_la_CFLAGS) -O2
libcothreads_la_CFLAGS = $(libgstreamer_la_CFLAGS) -O2
libgstreamer_la_LIBADD = $(LIBGST_LIBS)
libgstreamer_la_LDFLAGS = @GST_LT_LDFLAGS@ -version-info @GST_LIBVERSION@
libgstreamer_la_LDFLAGS = @GST_LT_LDFLAGS@ -version-info @GST_LIBVERSION@
EXTRA_DIST = ROADMAP

View file

@ -46,6 +46,7 @@ enum {
ARG_NUM_SINKS,
ARG_SILENT,
ARG_DUMP,
ARG_SYNC,
ARG_LAST_MESSAGE,
};
@ -60,6 +61,7 @@ GST_PADTEMPLATE_FACTORY (fakesink_sink_factory,
static void gst_fakesink_class_init (GstFakeSinkClass *klass);
static void gst_fakesink_init (GstFakeSink *fakesink);
static void gst_fakesink_set_clock (GstElement *element, GstClock *clock);
static GstPad* gst_fakesink_request_new_pad (GstElement *element, GstPadTemplate *templ, const
gchar *unused);
@ -106,12 +108,14 @@ gst_fakesink_class_init (GstFakeSinkClass *klass)
parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_NUM_SINKS,
g_param_spec_int ("num_sinks", "num_sinks", "num_sinks",
g_param_spec_int ("num_sinks", "Number of sinks", "The number of sinkpads",
1, G_MAXINT, 1, G_PARAM_READABLE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_LAST_MESSAGE,
g_param_spec_string ("last_message", "last_message", "last_message",
NULL, G_PARAM_READABLE));
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_SYNC,
g_param_spec_boolean("sync","Sync","Sync on the clock",
FALSE, G_PARAM_READWRITE)); /* CHECKME */
gst_element_class_install_std_props (
GST_ELEMENT_CLASS (klass),
@ -141,9 +145,22 @@ gst_fakesink_init (GstFakeSink *fakesink)
fakesink->silent = FALSE;
fakesink->dump = FALSE;
fakesink->sync = FALSE;
fakesink->last_message = NULL;
GST_ELEMENT (fakesink)->setclockfunc = gst_fakesink_set_clock;
}
static void
gst_fakesink_set_clock (GstElement *element, GstClock *clock)
{
GstFakeSink *sink;
sink = GST_FAKESINK (element);
sink->clock = clock;
}
static GstPad*
gst_fakesink_request_new_pad (GstElement *element, GstPadTemplate *templ, const gchar *unused)
{
@ -183,6 +200,9 @@ gst_fakesink_set_property (GObject *object, guint prop_id, const GValue *value,
case ARG_DUMP:
sink->dump = g_value_get_boolean (value);
break;
case ARG_SYNC:
sink->sync = g_value_get_boolean (value);
break;
default:
break;
}
@ -208,6 +228,9 @@ gst_fakesink_get_property (GObject *object, guint prop_id, GValue *value, GParam
case ARG_DUMP:
g_value_set_boolean (value, sink->dump);
break;
case ARG_SYNC:
g_value_set_boolean (value, sink->sync);
break;
case ARG_LAST_MESSAGE:
g_value_set_string (value, sink->last_message);
break;
@ -228,9 +251,12 @@ gst_fakesink_chain (GstPad *pad, GstBuffer *buf)
fakesink = GST_FAKESINK (gst_pad_get_parent (pad));
if (fakesink->sync) {
gst_element_clock_wait (GST_ELEMENT (fakesink), fakesink->clock, GST_BUFFER_TIMESTAMP (buf));
}
if (!fakesink->silent) {
if (fakesink->last_message)
g_free (fakesink->last_message);
g_free (fakesink->last_message);
fakesink->last_message = g_strdup_printf ("chain ******* (%s:%s)< (%d bytes, %lld) %p",
GST_DEBUG_PAD_NAME (pad), GST_BUFFER_SIZE (buf), GST_BUFFER_TIMESTAMP (buf), buf);

View file

@ -52,11 +52,14 @@ typedef struct _GstFakeSink GstFakeSink;
typedef struct _GstFakeSinkClass GstFakeSinkClass;
struct _GstFakeSink {
GstElement element;
GstElement element;
gboolean silent;
gboolean dump;
gchar *last_message;
gboolean silent;
gboolean dump;
gboolean sync;
GstClock *clock;
gchar *last_message;
};
struct _GstFakeSinkClass {

View file

@ -321,6 +321,7 @@ gst_fakesrc_event_handler (GstPad *pad, GstEvent *event)
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_SEEK:
src->buffer_count = GST_EVENT_SEEK_OFFSET (event);
if (!GST_EVENT_SEEK_FLUSH (event)) {
gst_event_free (event);
break;

View file

@ -105,7 +105,8 @@ struct _GstFakeSrc {
gboolean silent;
gboolean dump;
gboolean need_flush;
gchar *last_message;
gchar *last_message;
};
struct _GstFakeSrcClass {

View file

@ -78,7 +78,7 @@ GstElementDetails gst_filesrc_details = {
"(C) 1999",
};
/*#define fs_print(format,args...) g_print(format, ## args)*/
/*#define fs_print(format,args...) g_print(format, ## args) */
#define fs_print(format,args...)
/* FileSrc signals and args */
@ -549,7 +549,7 @@ gst_filesrc_get (GstPad *pad)
/* we're done, return the buffer */
src->curoffset += GST_BUFFER_SIZE(buf);
g_object_notify (G_OBJECT (src), "offset");
//g_object_notify (G_OBJECT (src), "offset");
return buf;
}
@ -590,7 +590,7 @@ gst_filesrc_open_file (GstFileSrc *src)
/* now notify of the changes */
g_object_freeze_notify (G_OBJECT (src));
g_object_notify (G_OBJECT (src), "filesize");
g_object_notify (G_OBJECT (src), "offset");
//g_object_notify (G_OBJECT (src), "offset");
g_object_thaw_notify (G_OBJECT (src));
GST_FLAG_SET (src, GST_FILESRC_OPEN);
@ -614,7 +614,7 @@ gst_filesrc_close_file (GstFileSrc *src)
/* and notify that things changed */
g_object_freeze_notify (G_OBJECT (src));
g_object_notify (G_OBJECT (src), "filesize");
g_object_notify (G_OBJECT (src), "offset");
//g_object_notify (G_OBJECT (src), "offset");
g_object_thaw_notify (G_OBJECT (src));
if (src->mapbuf)

View file

@ -181,7 +181,7 @@ gst_tee_request_new_pad (GstElement *element, GstPadTemplate *templ, const gchar
GList *pads;
g_return_val_if_fail (GST_IS_TEE (element), NULL);
if (templ->direction != GST_PAD_SRC) {
g_warning ("gsttee: request new pad that is not a SRC pad\n");
return NULL;

View file

@ -35,7 +35,6 @@
#include <gst/gstpad.h>
#include <gst/gstbuffer.h>
#include <gst/gstcpu.h>
#include <gst/gstsystemclock.h>
#include <gst/gstelement.h>
#include <gst/gstbin.h>
#include <gst/gstpipeline.h>

View file

@ -152,78 +152,16 @@ gst_bin_new (const gchar * name)
return gst_elementfactory_make ("bin", name);
}
static inline void
gst_bin_reset_element_sched (GstElement * element, GstScheduler * sched)
{
GST_INFO_ELEMENT (GST_CAT_PARENTAGE, element, "resetting element's scheduler");
gst_element_set_sched (element, sched);
}
static void
gst_bin_get_clock_elements (GstBin *bin, GList **needing, GList **providing)
{
GList *children = gst_bin_get_list (bin);
while (children) {
GstElement *child = GST_ELEMENT (children->data);
if (GST_IS_BIN (child)) {
gst_bin_get_clock_elements (GST_BIN (child), needing, providing);
}
if (child->getclockfunc) {
*providing = g_list_prepend (*providing, child);
}
if (child->setclockfunc) {
*needing = g_list_prepend (*needing, child);
}
children = g_list_next (children);
}
}
static void
gst_bin_distribute_clock (GstBin *bin, GList *needing, GstClock *clock)
{
while (needing) {
GST_DEBUG (GST_CAT_CLOCK, "setting clock on %s", GST_ELEMENT_NAME (needing->data));
gst_element_set_clock (GST_ELEMENT (needing->data), clock);
needing = g_list_next (needing);
}
}
static void
gst_bin_distribute_clocks (GstBin *bin)
{
GList *needing = NULL, *providing = NULL;
GstClock *clock;
gst_bin_get_clock_elements (bin, &needing, &providing);
if (GST_FLAG_IS_SET (bin, GST_BIN_FLAG_FIXED_CLOCK)) {
clock = bin->clock;
}
else if (providing) {
clock = gst_element_get_clock (GST_ELEMENT (providing->data));
}
else {
GST_DEBUG (GST_CAT_CLOCK, "no clock provided, using default clock");
clock = gst_system_clock_obtain ();
}
GST_BIN_CLOCK (bin) = clock;
gst_bin_distribute_clock (bin, needing, clock);
}
GstClock*
gst_bin_get_clock (GstBin *bin)
{
g_return_val_if_fail (bin != NULL, NULL);
g_return_val_if_fail (GST_IS_BIN (bin), NULL);
return GST_BIN_CLOCK (bin);
if (GST_ELEMENT_SCHED (bin))
return gst_scheduler_get_clock (GST_ELEMENT_SCHED (bin));
return NULL;
}
void
@ -232,8 +170,8 @@ gst_bin_use_clock (GstBin *bin, GstClock *clock)
g_return_if_fail (bin != NULL);
g_return_if_fail (GST_IS_BIN (bin));
GST_FLAG_SET (bin, GST_BIN_FLAG_FIXED_CLOCK);
GST_BIN_CLOCK (bin) = clock;
if (GST_ELEMENT_SCHED (bin))
gst_scheduler_use_clock (GST_ELEMENT_SCHED (bin), clock);
}
void
@ -242,12 +180,12 @@ gst_bin_auto_clock (GstBin *bin)
g_return_if_fail (bin != NULL);
g_return_if_fail (GST_IS_BIN (bin));
GST_FLAG_UNSET (bin, GST_BIN_FLAG_FIXED_CLOCK);
GST_BIN_CLOCK (bin) = NULL;
if (GST_ELEMENT_SCHED (bin))
gst_scheduler_auto_clock (GST_ELEMENT_SCHED (bin));
}
static void
gst_bin_set_element_sched (GstElement * element, GstScheduler * sched)
gst_bin_set_element_sched (GstElement *element, GstScheduler *sched)
{
GList *children;
GstElement *child;
@ -264,6 +202,7 @@ gst_bin_set_element_sched (GstElement * element, GstScheduler * sched)
if (GST_IS_BIN (element)) {
if (GST_FLAG_IS_SET (element, GST_BIN_FLAG_MANAGER)) {
GST_INFO_ELEMENT (GST_CAT_PARENTAGE, element, "child is already a manager, not resetting");
gst_scheduler_add_scheduler (sched, GST_ELEMENT_SCHED (element));
return;
}
@ -278,7 +217,6 @@ gst_bin_set_element_sched (GstElement * element, GstScheduler * sched)
gst_bin_set_element_sched (child, sched);
}
}
/* otherwise, if it's just a regular old element */
else {
@ -288,7 +226,7 @@ gst_bin_set_element_sched (GstElement * element, GstScheduler * sched)
static void
gst_bin_unset_element_sched (GstElement * element)
gst_bin_unset_element_sched (GstElement *element, GstScheduler *sched)
{
GList *children;
GstElement *child;
@ -302,7 +240,7 @@ gst_bin_unset_element_sched (GstElement * element)
return;
}
GST_INFO (GST_CAT_SCHEDULING, "removing element \"%s\" from it sched %p",
GST_INFO (GST_CAT_SCHEDULING, "removing element \"%s\" from its sched %p",
GST_ELEMENT_NAME (element), GST_ELEMENT_SCHED (element));
/* if it's actually a Bin */
@ -311,20 +249,21 @@ gst_bin_unset_element_sched (GstElement * element)
if (GST_FLAG_IS_SET (element, GST_BIN_FLAG_MANAGER)) {
GST_INFO_ELEMENT (GST_CAT_PARENTAGE, element,
"child is already a manager, not unsetting sched");
if (sched) {
gst_scheduler_remove_scheduler (sched, GST_ELEMENT_SCHED (element));
}
return;
}
gst_scheduler_remove_element (GST_ELEMENT_SCHED (element), element);
/* for each child, remove them from their schedule */
children = GST_BIN (element)->children;
while (children) {
child = GST_ELEMENT (children->data);
children = g_list_next (children);
gst_bin_unset_element_sched (child);
gst_bin_unset_element_sched (child, sched);
}
gst_scheduler_remove_element (GST_ELEMENT_SCHED (element), element);
}
/* otherwise, if it's just a regular old element */
else {
@ -372,10 +311,11 @@ gst_bin_add_many (GstBin *bin, GstElement *element_1, ...)
* add a reference.
*/
void
gst_bin_add (GstBin * bin, GstElement * element)
gst_bin_add (GstBin *bin, GstElement *element)
{
gint state_idx = 0;
GstElementState state;
GstScheduler *sched;
g_return_if_fail (bin != NULL);
g_return_if_fail (GST_IS_BIN (bin));
@ -409,11 +349,9 @@ gst_bin_add (GstBin * bin, GstElement * element)
/* now we have to deal with manager stuff
* we can only do this if there's a scheduler:
* if we're not a manager, and aren't attached to anything, we have no sched (yet) */
if (GST_IS_BIN (element) && GST_FLAG_IS_SET (element, GST_BIN_FLAG_MANAGER)) {
GST_INFO_ELEMENT (GST_CAT_PARENTAGE, element, "child is a manager");
}
else if (GST_ELEMENT_SCHED (bin) != NULL) {
gst_bin_set_element_sched (element, GST_ELEMENT_SCHED (bin));
sched = GST_ELEMENT_SCHED (bin);
if (sched) {
gst_bin_set_element_sched (element, sched);
}
GST_INFO_ELEMENT (GST_CAT_PARENTAGE, bin, "added child \"%s\"", GST_ELEMENT_NAME (element));
@ -429,7 +367,7 @@ gst_bin_add (GstBin * bin, GstElement * element)
* Remove the element from its associated bin, unparenting as well.
*/
void
gst_bin_remove (GstBin * bin, GstElement * element)
gst_bin_remove (GstBin *bin, GstElement *element)
{
gint state_idx = 0;
GstElementState state;
@ -456,7 +394,7 @@ gst_bin_remove (GstBin * bin, GstElement * element)
}
/* remove this element from the list of managed elements */
gst_bin_unset_element_sched (element);
gst_bin_unset_element_sched (element, GST_ELEMENT_SCHED (bin));
/* now remove the element from the list of elements */
bin->children = g_list_remove (bin->children, element);
@ -504,7 +442,7 @@ gst_bin_child_state_change (GstBin *bin, GstElementState oldstate, GstElementSta
GST_LOCK (bin);
bin->child_states[old_idx]--;
bin->child_states[new_idx]++;
for (i = GST_NUM_STATES - 1; i >= 0; i--) {
if (bin->child_states[i] != 0) {
gint state = (1 << i);
@ -512,7 +450,9 @@ gst_bin_child_state_change (GstBin *bin, GstElementState oldstate, GstElementSta
GST_INFO (GST_CAT_STATES, "bin %s need state change to %s",
GST_ELEMENT_NAME (bin), gst_element_statename (state));
GST_STATE_PENDING (bin) = state;
GST_UNLOCK (bin);
gst_bin_change_state_norecurse (bin);
return;
}
break;
}
@ -542,7 +482,11 @@ gst_bin_change_state (GstElement * element)
GST_INFO_ELEMENT (GST_CAT_STATES, element, "changing childrens' state from %s to %s",
gst_element_statename (old_state), gst_element_statename (pending));
if (pending == GST_STATE_VOID_PENDING)
return GST_STATE_SUCCESS;
children = bin->children;
while (children) {
child = GST_ELEMENT (children->data);
children = g_list_next (children);
@ -569,28 +513,6 @@ gst_bin_change_state (GstElement * element)
}
}
if (GST_ELEMENT_SCHED (bin) != NULL && GST_ELEMENT_PARENT (bin) == NULL) {
switch (transition) {
case GST_STATE_NULL_TO_READY:
gst_bin_distribute_clocks (bin);
break;
case GST_STATE_READY_TO_PAUSED:
if (GST_BIN_CLOCK (bin))
gst_clock_reset (GST_BIN_CLOCK (bin));
break;
case GST_STATE_PAUSED_TO_PLAYING:
gst_bin_distribute_clocks (bin);
if (GST_BIN_CLOCK (bin))
gst_clock_activate (GST_BIN_CLOCK (bin), TRUE);
break;
case GST_STATE_PLAYING_TO_PAUSED:
if (GST_BIN_CLOCK (bin))
gst_clock_activate (GST_BIN_CLOCK (bin), FALSE);
break;
}
}
GST_INFO_ELEMENT (GST_CAT_STATES, element, "done changing bin's state from %s to %s, now in %s",
gst_element_statename (old_state),
gst_element_statename (pending),

View file

@ -48,10 +48,6 @@ extern GType _gst_bin_type;
# define GST_BIN_CLASS GST_BIN_CLASS_CAST
#endif
#define GST_BIN_CLOCK_PROVIDERS(bin) (GST_BIN(bin)->clock_providers)
#define GST_BIN_CLOCK_RECEIVERS(bin) (GST_BIN(bin)->clock_receivers)
#define GST_BIN_CLOCK(bin) (GST_BIN(bin)->clock)
typedef enum {
/* this bin is a manager of child elements, i.e. a pipeline or thread */
GST_BIN_FLAG_MANAGER = GST_ELEMENT_FLAG_LAST,
@ -82,8 +78,6 @@ struct _GstBin {
GstElementState child_states[GST_NUM_STATES];
GstClock *clock;
gpointer sched_private;
};
@ -128,9 +122,6 @@ void gst_bin_auto_clock (GstBin *bin);
/* one of our childs signaled a state change */
void gst_bin_child_state_change (GstBin *bin, GstElementState oldstate,
GstElementState newstate, GstElement *child);
/* one of our childs signaled an error */
void gst_bin_child_error (GstBin *bin, GstElement *child);
#ifdef __cplusplus
}

View file

@ -26,11 +26,11 @@
#include "gstcaps.h"
#include "gsttype.h"
#include "gstpropsprivate.h"
static GMemChunk *_gst_caps_chunk;
static GMutex *_gst_caps_chunk_lock;
GType _gst_caps_type;
void
_gst_caps_initialize (void)
{
@ -38,6 +38,11 @@ _gst_caps_initialize (void)
sizeof (GstCaps), sizeof (GstCaps) * 256,
G_ALLOC_AND_FREE);
_gst_caps_chunk_lock = g_mutex_new ();
_gst_caps_type = g_boxed_type_register_static ("GstCaps",
(GBoxedCopyFunc) gst_caps_ref,
(GBoxedFreeFunc) gst_caps_unref);
}
static guint16
@ -104,7 +109,6 @@ gst_caps_new_id (const gchar *name, const guint16 id, GstProps *props)
caps->properties = props;
caps->next = NULL;
caps->refcount = 1;
caps->lock = g_mutex_new ();
if (props)
caps->fixed = props->fixed;
else
@ -128,11 +132,8 @@ gst_caps_destroy (GstCaps *caps)
if (caps == NULL)
return;
GST_CAPS_LOCK (caps);
next = caps->next;
GST_CAPS_UNLOCK (caps);
g_mutex_free (caps->lock);
gst_props_unref (caps->properties);
g_free (caps->name);
g_mutex_lock (_gst_caps_chunk_lock);
@ -189,11 +190,9 @@ gst_caps_unref (GstCaps *caps)
g_return_val_if_fail (caps->refcount > 0, NULL);
GST_CAPS_LOCK (caps);
caps->refcount--;
zero = (caps->refcount == 0);
next = &caps->next;
GST_CAPS_UNLOCK (caps);
if (*next)
*next = gst_caps_unref (*next);
@ -218,9 +217,7 @@ gst_caps_ref (GstCaps *caps)
{
g_return_val_if_fail (caps != NULL, NULL);
GST_CAPS_LOCK (caps);
caps->refcount++;
GST_CAPS_UNLOCK (caps);
return caps;
}
@ -296,9 +293,7 @@ gst_caps_copy_on_write (GstCaps *caps)
g_return_val_if_fail (caps != NULL, NULL);
GST_CAPS_LOCK (caps);
needcopy = (caps->refcount > 1);
GST_CAPS_UNLOCK (caps);
if (needcopy) {
new = gst_caps_copy (caps);
@ -798,7 +793,6 @@ gst_caps_load_thyself (xmlNodePtr parent)
g_mutex_unlock (_gst_caps_chunk_lock);
caps->refcount = 1;
caps->lock = g_mutex_new ();
caps->next = NULL;
caps->fixed = TRUE;

View file

@ -30,13 +30,14 @@
typedef struct _GstCaps GstCaps;
extern GType _gst_caps_type;
#define GST_TYPE_CAPS (_get_caps_type)
#define GST_CAPS(caps) \
((GstCaps *)(caps))
#define GST_CAPS_LOCK(caps) (g_mutex_lock(GST_CAPS(caps)->lock))
#define GST_CAPS_TRYLOCK(caps) (g_mutex_trylock(GST_CAPS(caps)->lock))
#define GST_CAPS_UNLOCK(caps) (g_mutex_unlock(GST_CAPS(caps)->lock))
#define GST_CAPS_IS_FIXED(caps) ((caps)->fixed)
#define GST_CAPS_IS_CHAINED(caps) ((caps)->next)
@ -45,7 +46,6 @@ struct _GstCaps {
guint16 id; /* type id (major type) */
guint refcount;
GMutex *lock; /* global lock for this capability */
gboolean fixed; /* this caps doesn't contain variable properties */
GstProps *properties; /* properties for this capability */
@ -104,14 +104,16 @@ GstCaps* gst_caps_set_props (GstCaps *caps, GstProps *props);
GstProps* gst_caps_get_props (GstCaps *caps);
#define gst_caps_set(caps, name, args...) gst_props_set ((caps)->properties, name, args)
#define gst_caps_get(caps, name, args...) gst_props_get ((caps)->properties, name, args)
#define gst_caps_get_int(caps, name) gst_props_get_int ((caps)->properties, name)
#define gst_caps_get_float(caps, name) gst_props_get_float ((caps)->properties, name)
#define gst_caps_get_fourcc_int(caps, name) gst_props_get_fourcc_int ((caps)->properties, name)
#define gst_caps_get_boolean(caps, name) gst_props_get_boolean ((caps)->properties, name)
#define gst_caps_get_string(caps, name) gst_props_get_string ((caps)->properties, name)
#define gst_caps_get_int(caps,name,res) gst_props_entry_get_int(gst_props_get_entry((caps)->properties,name),res)
#define gst_caps_get_float(caps,name,res) gst_props_entry_get_float(gst_props_get_entry((caps)->properties,name),res)
#define gst_caps_get_fourcc_int(caps,name,res) gst_props_entry_get_fourcc_int(gst_props_get_entry((caps)->properties,name),res)
#define gst_caps_get_boolean(caps,name,res) gst_props_entry_get_boolean(gst_props_get_entry((caps)->properties,name),res)
#define gst_caps_get_string(caps,name,res) gst_props_entry_get_string(gst_props_get_entry((caps)->properties,name),res)
#define gst_caps_has_property(caps, name) gst_props_has_property ((caps)->properties, name)
#define gst_caps_has_property_typed(caps, name) gst_props_has_property_typed ((caps)->properties, name)
#define gst_caps_has_fixed_property(caps, name) gst_props_has_fixed_property ((caps)->properties, name)
GstCaps* gst_caps_get_by_name (GstCaps *caps, const gchar *name);

View file

@ -29,13 +29,80 @@
#define CLASS(clock) GST_CLOCK_CLASS (G_OBJECT_GET_CLASS (clock))
static GMemChunk *_gst_clock_entries_chunk;
static GMutex *_gst_clock_entries_chunk_lock;
static GList *_gst_clock_entries_pool;
static void gst_clock_class_init (GstClockClass *klass);
static void gst_clock_init (GstClock *clock);
static GstObjectClass *parent_class = NULL;
/* static guint gst_clock_signals[LAST_SIGNAL] = { 0 }; */
typedef struct _GstClockEntry GstClockEntry;
static void gst_clock_free_entry (GstClock *clock, GstClockEntry *entry);
typedef enum {
GST_ENTRY_OK,
GST_ENTRY_RESTART,
} GstEntryStatus;
struct _GstClockEntry {
GstClockTime time;
GstEntryStatus status;
GstClockCallback func;
gpointer user_data;
GMutex *lock;
GCond *cond;
};
#define GST_CLOCK_ENTRY(entry) ((GstClockEntry *)(entry))
#define GST_CLOCK_ENTRY_TIME(entry) (((GstClockEntry *)(entry))->time)
#define GST_CLOCK_ENTRY_LOCK(entry) (g_mutex_lock ((entry)->lock))
#define GST_CLOCK_ENTRY_UNLOCK(entry) (g_mutex_unlock ((entry)->lock))
#define GST_CLOCK_ENTRY_SIGNAL(entry) (g_cond_signal ((entry)->cond))
#define GST_CLOCK_ENTRY_WAIT(entry) (g_cond_wait (entry->cond, entry->lock))
#define GST_CLOCK_ENTRY_TIMED_WAIT(entry, time) (g_cond_timed_wait (entry->cond, entry->lock, (time)))
static GstClockEntry*
gst_clock_entry_new (GstClockTime time,
GstClockCallback func, gpointer user_data)
{
GstClockEntry *entry;
g_mutex_lock (_gst_clock_entries_chunk_lock);
if (_gst_clock_entries_pool) {
entry = GST_CLOCK_ENTRY (_gst_clock_entries_pool->data);
_gst_clock_entries_pool = g_list_remove (_gst_clock_entries_pool, entry);
g_mutex_unlock (_gst_clock_entries_chunk_lock);
}
else {
entry = g_mem_chunk_alloc (_gst_clock_entries_chunk);
g_mutex_unlock (_gst_clock_entries_chunk_lock);
entry->lock = g_mutex_new ();
entry->cond = g_cond_new ();
}
entry->time = time;
entry->func = func;
entry->user_data = user_data;
return entry;
}
static gint
clock_compare_func (gconstpointer a,
gconstpointer b)
{
GstClockEntry *entry1 = (GstClockEntry *)a;
GstClockEntry *entry2 = (GstClockEntry *)b;
return (entry1->time - entry2->time);
}
GType
gst_clock_get_type (void)
{
@ -43,19 +110,19 @@ gst_clock_get_type (void)
if (!clock_type) {
static const GTypeInfo clock_info = {
sizeof (GstObjectClass),
sizeof (GstClockClass),
NULL,
NULL,
(GClassInitFunc) gst_clock_class_init,
NULL,
NULL,
sizeof (GstObject),
sizeof (GstClock),
4,
(GInstanceInitFunc) gst_clock_init,
NULL
};
clock_type = g_type_register_static (GST_TYPE_OBJECT, "GstClock",
&clock_info, G_TYPE_FLAG_ABSTRACT);
&clock_info, G_TYPE_FLAG_ABSTRACT);
}
return clock_type;
}
@ -70,6 +137,12 @@ gst_clock_class_init (GstClockClass *klass)
gstobject_class = (GstObjectClass*) klass;
parent_class = g_type_class_ref (GST_TYPE_OBJECT);
_gst_clock_entries_chunk = g_mem_chunk_new ("GstClockEntries",
sizeof (GstClockEntry), sizeof (GstClockEntry) * 32,
G_ALLOC_AND_FREE);
_gst_clock_entries_chunk_lock = g_mutex_new ();
_gst_clock_entries_pool = NULL;
}
static void
@ -78,37 +151,66 @@ gst_clock_init (GstClock *clock)
clock->speed = 1.0;
clock->active = FALSE;
clock->start_time = 0;
clock->last_time = 0;
clock->entries = NULL;
clock->async_supported = FALSE;
clock->active_mutex = g_mutex_new ();
clock->active_cond = g_cond_new ();
}
gboolean
gst_clock_async_supported (GstClock *clock)
{
g_return_val_if_fail (GST_IS_CLOCK (clock), FALSE);
return clock->async_supported;
}
void
gst_clock_reset (GstClock *clock)
{
GstClockTime time = 0LL;
g_return_if_fail (GST_IS_CLOCK (clock));
clock->start_time = 0;
clock->active = FALSE;
if (CLASS (clock)->get_internal_time) {
time = CLASS (clock)->get_internal_time (clock);
}
if (CLASS (clock)->reset)
CLASS (clock)->reset (clock);
GST_LOCK (clock);
clock->active = FALSE;
clock->start_time = time;
clock->last_time = 0LL;
GST_UNLOCK (clock);
}
void
gst_clock_activate (GstClock *clock, gboolean active)
{
GstClockTime time = 0LL;
g_return_if_fail (GST_IS_CLOCK (clock));
clock->active = active;
if (CLASS (clock)->get_internal_time) {
time = CLASS (clock)->get_internal_time (clock);
}
if (CLASS (clock)->activate)
CLASS (clock)->activate (clock, active);
GST_LOCK (clock);
if (active) {
clock->start_time = time - clock->last_time;;
}
else {
clock->last_time = time - clock->start_time;
}
GST_UNLOCK (clock);
g_mutex_lock (clock->active_mutex);
g_cond_signal (clock->active_cond);
g_cond_broadcast (clock->active_cond);
g_mutex_unlock (clock->active_mutex);
}
gboolean
@ -119,40 +221,166 @@ gst_clock_is_active (GstClock *clock)
return clock->active;
}
void
gst_clock_set_time (GstClock *clock, GstClockTime time)
{
g_return_if_fail (GST_IS_CLOCK (clock));
if (CLASS (clock)->set_time)
CLASS (clock)->set_time (clock, time);
}
GstClockTime
gst_clock_get_time (GstClock *clock)
{
GstClockTime ret = 0LL;
g_return_val_if_fail (GST_IS_CLOCK (clock), 0LL);
if (CLASS (clock)->get_time)
return CLASS (clock)->get_time (clock);
if (!clock->active) {
/* clock is not activen return previous time */
ret = clock->last_time;
}
else {
if (CLASS (clock)->get_internal_time) {
ret = CLASS (clock)->get_internal_time (clock) - clock->start_time;
}
/* make sure the time is increasing, else return last_time */
if (ret < clock->last_time) {
ret = clock->last_time;
}
else {
clock->last_time = ret;
}
}
return 0LL;
return ret;
}
GstClockReturn
gst_clock_wait (GstClock *clock, GstClockTime time)
static GstClockID
gst_clock_wait_async_func (GstClock *clock, GstClockTime time,
GstClockCallback func, gpointer user_data)
{
g_return_val_if_fail (GST_IS_CLOCK (clock), GST_CLOCK_STOPPED);
GstClockEntry *entry = NULL;
g_return_val_if_fail (GST_IS_CLOCK (clock), NULL);
if (!clock->active) {
g_mutex_lock (clock->active_mutex);
g_cond_wait (clock->active_cond, clock->active_mutex);
g_mutex_unlock (clock->active_mutex);
}
if (CLASS (clock)->wait)
return CLASS (clock)->wait (clock, time);
return GST_CLOCK_TIMEOUT;
entry = gst_clock_entry_new (time, func, user_data);
GST_LOCK (clock);
clock->entries = g_list_insert_sorted (clock->entries, entry, clock_compare_func);
GST_UNLOCK (clock);
return entry;
}
GstClockReturn
gst_clock_wait (GstClock *clock, GstClockTime time)
{
GstClockID id;
GstClockReturn res;
g_return_val_if_fail (GST_IS_CLOCK (clock), GST_CLOCK_STOPPED);
id = gst_clock_wait_async_func (clock, time, NULL, NULL);
res = gst_clock_wait_id (clock, id);
return res;
}
GstClockID
gst_clock_wait_async (GstClock *clock, GstClockTime time,
GstClockCallback func, gpointer user_data)
{
g_return_val_if_fail (GST_IS_CLOCK (clock), NULL);
if (clock->async_supported) {
return gst_clock_wait_async_func (clock, time, func, user_data);
}
return NULL;
}
static void
gst_clock_unlock_func (GstClock *clock, GstClockTime time, GstClockID id, gpointer user_data)
{
GstClockEntry *entry = (GstClockEntry *) id;
GST_CLOCK_ENTRY_LOCK (entry);
GST_CLOCK_ENTRY_SIGNAL (entry);
GST_CLOCK_ENTRY_UNLOCK (entry);
}
GstClockReturn
gst_clock_wait_id (GstClock *clock, GstClockID id)
{
GstClockReturn res = GST_CLOCK_TIMEOUT;
GstClockEntry *entry = (GstClockEntry *) id;
GstClockTime current_real, current, target;
GTimeVal timeval;
g_return_val_if_fail (GST_IS_CLOCK (clock), GST_CLOCK_ERROR);
g_return_val_if_fail (entry, GST_CLOCK_ERROR);
current = gst_clock_get_time (clock);
g_get_current_time (&timeval);
current_real = GST_TIMEVAL_TO_TIME (timeval);
GST_CLOCK_ENTRY_LOCK (entry);
entry->func = gst_clock_unlock_func;
target = GST_CLOCK_ENTRY_TIME (entry) - current + current_real;
//g_print ("%lld %lld %lld\n", target, current, current_real);
if (target > current_real) {
timeval.tv_usec = target % 1000000;
timeval.tv_sec = target / 1000000;
GST_CLOCK_ENTRY_TIMED_WAIT (entry, &timeval);
}
GST_CLOCK_ENTRY_UNLOCK (entry);
gst_clock_free_entry (clock, entry);
return res;
}
GstClockID
gst_clock_get_next_id (GstClock *clock)
{
GstClockEntry *entry = NULL;
GST_LOCK (clock);
if (clock->entries)
entry = GST_CLOCK_ENTRY (clock->entries->data);
GST_UNLOCK (clock);
return (GstClockID *) entry;
}
GstClockTime
gst_clock_id_get_time (GstClockID id)
{
return GST_CLOCK_ENTRY_TIME (id);
}
static void
gst_clock_free_entry (GstClock *clock, GstClockEntry *entry)
{
GST_LOCK (clock);
clock->entries = g_list_remove (clock->entries, entry);
GST_UNLOCK (clock);
g_mutex_lock (_gst_clock_entries_chunk_lock);
_gst_clock_entries_pool = g_list_prepend (_gst_clock_entries_pool, entry);
g_mutex_unlock (_gst_clock_entries_chunk_lock);
}
void
gst_clock_unlock_id (GstClock *clock, GstClockID id)
{
GstClockEntry *entry = (GstClockEntry *) id;
if (entry->func)
entry->func (clock, gst_clock_get_time (clock), id, entry->user_data);
gst_clock_free_entry (clock, entry);
}
void
@ -172,6 +400,6 @@ gst_clock_get_resolution (GstClock *clock)
if (CLASS (clock)->get_resolution)
return CLASS (clock)->get_resolution (clock);
return 0LL;
return 1LL;
}

View file

@ -65,8 +65,11 @@ struct _GstClock {
GstObject object;
GstClockTime start_time;
GstClockTime last_time;
gdouble speed;
gboolean active;
GList *entries;
gboolean async_supported;
GMutex *active_mutex;
GCond *active_cond;
@ -76,20 +79,8 @@ struct _GstClockClass {
GstObjectClass parent_class;
/* vtable */
void (*activate) (GstClock *clock, gboolean active);
void (*reset) (GstClock *clock);
GstClockTime (*get_internal_time) (GstClock *clock);
void (*set_time) (GstClock *clock, GstClockTime time);
GstClockTime (*get_time) (GstClock *clock);
GstClockReturn (*wait) (GstClock *clock, GstClockTime time);
GstClockID (*wait_async) (GstClock *clock, GstClockTime time,
GstClockCallback func, gpointer user_data);
void (*cancel_wait_async) (GstClock *clock, GstClockID id);
GstClockID (*notify_async) (GstClock *clock, GstClockTime interval,
GstClockCallback func, gpointer user_data);
void (*remove_notify_async) (GstClock *clock, GstClockID id);
void (*set_resolution) (GstClock *clock, guint64 resolution);
guint64 (*get_resolution) (GstClock *clock);
@ -104,8 +95,8 @@ void gst_clock_get_speed (GstClock *clock, gdouble speed);
void gst_clock_activate (GstClock *clock, gboolean active);
gboolean gst_clock_is_active (GstClock *clock);
void gst_clock_reset (GstClock *clock);
gboolean gst_clock_async_supported (GstClock *clock);
void gst_clock_set_time (GstClock *clock, GstClockTime time);
GstClockTime gst_clock_get_time (GstClock *clock);
GstClockReturn gst_clock_wait (GstClock *clock, GstClockTime time);
@ -115,6 +106,12 @@ void gst_clock_cancel_wait_async (GstClock *clock, GstClockID id);
GstClockID gst_clock_notify_async (GstClock *clock, GstClockTime interval,
GstClockCallback func, gpointer user_data);
void gst_clock_remove_notify_async (GstClock *clock, GstClockID id);
GstClockReturn gst_clock_wait_id (GstClock *clock, GstClockID id);
GstClockID gst_clock_get_next_id (GstClock *clock);
void gst_clock_unlock_id (GstClock *clock, GstClockID id);
GstClockTime gst_clock_id_get_time (GstClockID id);
void gst_clock_set_resolution (GstClock *clock, guint64 resolution);
guint64 gst_clock_get_resolution (GstClock *clock);

View file

@ -315,8 +315,11 @@ gst_element_clock_wait (GstElement *element, GstClock *clock, GstClockTime time)
g_return_val_if_fail (element != NULL, GST_CLOCK_ERROR);
g_return_val_if_fail (GST_IS_ELEMENT (element), GST_CLOCK_ERROR);
/* FIXME inform the scheduler */
return gst_clock_wait (clock, time);
if (GST_ELEMENT_SCHED (element)) {
return gst_scheduler_clock_wait (GST_ELEMENT_SCHED (element), element, clock, time);
}
else
return GST_CLOCK_TIMEOUT;
}
/**
@ -489,7 +492,9 @@ gst_element_get_pad (GstElement *element, const gchar *name)
/* look through the list, matching by name */
walk = element->pads;
while (walk) {
GstPad *pad = GST_PAD(walk->data);
GstPad *pad;
pad = GST_PAD(walk->data);
if (!strcmp (GST_PAD_NAME(pad), name)) {
GST_INFO(GST_CAT_ELEMENT_PADS,"found pad %s:%s",GST_DEBUG_PAD_NAME(pad));
return pad;
@ -718,6 +723,7 @@ gst_element_request_pad_by_name (GstElement *element, const gchar *name)
g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
g_return_val_if_fail (name != NULL, NULL);
if (strstr (name, "%")) {
templ = gst_element_get_padtemplate_by_name (element, name);
req_name = NULL;
@ -1181,35 +1187,6 @@ gst_element_error (GstElement *element, const gchar *error, ...)
g_free (string);
}
/**
* gst_element_info:
* @element: Element with the info
* @info: String describing the info
* @...: arguments for the string.
*
* This function is used internally by elements to signal an info
* condition. It results in the "info" signal.
*/
void
gst_element_info (GstElement *element, const gchar *info, ...)
{
g_warning ("The function gst_element_info is gone. Use g_object_notify instead.");
}
/**
* gst_element_send_event:
* @element: Element generating the event
* @event: the event to send
*
* This function is deprecated and doesn't work anymore.
*/
void
gst_element_send_event (GstElement *element, GstEvent *event)
{
g_warning ("The function gst_element_send_event is gone. Use g_object_notify instead.");
}
/**
* gst_element_get_state:
* @element: element to get state of
@ -1258,13 +1235,13 @@ gst_element_set_state (GstElement *element, GstElementState state)
g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_FAILURE);
GST_DEBUG_ELEMENT (GST_CAT_STATES, element, "setting state from %s to %s\n",
gst_element_statename (GST_STATE (element)),
gst_element_statename (state));
/* start with the current state */
curpending = GST_STATE(element);
GST_DEBUG_ELEMENT (GST_CAT_STATES, element, "setting state from %s to %s\n",
gst_element_statename (curpending),
gst_element_statename (state));
/* loop until the final requested state is set */
while (GST_STATE (element) != state && GST_STATE (element) != GST_STATE_VOID_PENDING) {
/* move the curpending state in the correct direction */
@ -1277,9 +1254,10 @@ gst_element_set_state (GstElement *element, GstElementState state)
/* FIXME: should probably check to see that we don't already have one */
GST_STATE_PENDING (element) = curpending;
if (curpending != state)
if (curpending != state) {
GST_DEBUG_ELEMENT (GST_CAT_STATES, element, "intermediate: setting state to %s\n",
gst_element_statename (curpending));
}
/* call the state change function so it can set the state */
oclass = CLASS (element);
@ -1297,7 +1275,11 @@ gst_element_set_state (GstElement *element, GstElementState state)
/* Last thing we do is verify that a successful state change really
* did change the state... */
if (GST_STATE (element) != curpending) {
GST_DEBUG_ELEMENT (GST_CAT_STATES, element, "element claimed state-change success, but state didn't change\n");
GST_DEBUG_ELEMENT (GST_CAT_STATES, element,
"element claimed state-change success, but state didn't change %s, %s <-> %s\n",
gst_element_statename (GST_STATE (element)),
gst_element_statename (GST_STATE_PENDING (element)),
gst_element_statename (curpending));
return GST_STATE_FAILURE;
}
break;
@ -1429,9 +1411,6 @@ gst_element_change_state (GstElement *element)
}
}
g_signal_emit (G_OBJECT (element), gst_element_signals[STATE_CHANGE],
0, old_state, GST_STATE (element));
parent = GST_ELEMENT_PARENT (element);
/* tell our parent about the state change */
@ -1439,6 +1418,9 @@ gst_element_change_state (GstElement *element)
gst_bin_child_state_change (GST_BIN (parent), old_state, GST_STATE (element), element);
}
g_signal_emit (G_OBJECT (element), gst_element_signals[STATE_CHANGE],
0, old_state, GST_STATE (element));
/* signal the state change in case somebody is waiting for us */
g_mutex_lock (element->state_mutex);
g_cond_signal (element->state_cond);
@ -1688,7 +1670,7 @@ gst_element_interrupt (GstElement *element)
*/
void
gst_element_set_sched (GstElement *element,
GstScheduler *sched)
GstScheduler *sched)
{
g_return_if_fail (GST_IS_ELEMENT (element));
@ -1727,8 +1709,8 @@ gst_element_get_sched (GstElement *element)
* a new loopfunc to be assigned, this should be no problem.
*/
void
gst_element_set_loop_function(GstElement *element,
GstElementLoopFunction loop)
gst_element_set_loop_function (GstElement *element,
GstElementLoopFunction loop)
{
g_return_if_fail (GST_IS_ELEMENT (element));

View file

@ -38,7 +38,6 @@ extern "C" {
#define GST_NUM_STATES 4
/* NOTE: this probably should be done with an #ifdef to decide
* whether to safe-cast or to just do the non-checking cast.
*/
@ -171,7 +170,6 @@ struct _GstElementClass {
GstElementStateReturn (*change_state) (GstElement *element);
/* request a new pad */
GstPad* (*request_new_pad) (GstElement *element, GstPadTemplate *templ, const gchar* name);
void (*send_event) (GstElement *element, GstEvent *event);
};
void gst_element_class_add_padtemplate (GstElementClass *klass, GstPadTemplate *templ);
@ -228,8 +226,7 @@ gboolean gst_element_connect_elements_many (GstElement *element_1, GstElement *
void gst_element_set_eos (GstElement *element);
void gst_element_send_event (GstElement *element, GstEvent *event);
void gst_element_error (GstElement *element, const gchar *error, ...);
GstElementState gst_element_get_state (GstElement *element);
gint gst_element_set_state (GstElement *element, GstElementState state);
@ -238,9 +235,6 @@ void gst_element_wait_state_change (GstElement *element);
const gchar* gst_element_statename (GstElementState state);
void gst_element_info (GstElement *element, const gchar *info, ...);
void gst_element_error (GstElement *element, const gchar *error, ...);
GstElementFactory* gst_element_get_factory (GstElement *element);
void gst_element_class_install_std_props (GstElementClass *klass,

View file

@ -535,7 +535,7 @@ gst_pad_disconnect (GstPad *srcpad,
realsink = GST_PAD_REALIZE (sinkpad);
g_return_if_fail (GST_RPAD_PEER (realsrc) != NULL);
g_return_if_fail (GST_RPAD_PEER (realsink) != NULL);
g_return_if_fail (GST_RPAD_PEER (realsink) == realsrc);
if ((GST_RPAD_DIRECTION (realsrc) == GST_PAD_SINK) &&
(GST_RPAD_DIRECTION (realsink) == GST_PAD_SRC)) {
@ -1013,8 +1013,8 @@ gst_pad_try_set_caps_func (GstRealPad *pad, GstCaps *caps, gboolean notify)
debug_string = "DELAYED";
break;
default:
g_warning ("unknown return code from connect function of pad %s:%s",
GST_DEBUG_PAD_NAME (pad));
g_warning ("unknown return code from connect function of pad %s:%s %d",
GST_DEBUG_PAD_NAME (pad), res);
return GST_PAD_CONNECT_REFUSED;
}
@ -1337,9 +1337,9 @@ gst_pad_proxy_connect (GstPad *pad, GstCaps *caps)
GST_INFO (GST_CAT_CAPS, "proxy connect to pad %s:%s",
GST_DEBUG_PAD_NAME (realpad));
if (peer && !gst_pad_try_set_caps_func (peer, caps, TRUE))
if (peer && gst_pad_try_set_caps_func (peer, caps, TRUE) < 0)
return GST_PAD_CONNECT_REFUSED;
if (!gst_pad_try_set_caps_func (realpad, caps, FALSE))
if (gst_pad_try_set_caps_func (realpad, caps, FALSE) < 0)
return GST_PAD_CONNECT_REFUSED;
return GST_PAD_CONNECT_OK;

View file

@ -40,7 +40,7 @@ extern GType _gst_pad_type;
extern GType _gst_real_pad_type;
extern GType _gst_ghost_pad_type;
/*#define GST_TYPE_PARANOID */
#define GST_TYPE_PARANOID
/*
* Pad base class
@ -118,10 +118,10 @@ typedef enum {
} GstRegionType;
typedef enum {
GST_PAD_CONNECT_REFUSED = 0,
GST_PAD_CONNECT_OK = 1,
GST_PAD_CONNECT_DONE = 2,
GST_PAD_CONNECT_DELAYED = 3,
GST_PAD_CONNECT_REFUSED = -1,
GST_PAD_CONNECT_DELAYED = 0,
GST_PAD_CONNECT_OK = 1,
GST_PAD_CONNECT_DONE = 2,
} GstPadConnectReturn;
/* this defines the functions used to chain buffers

View file

@ -25,7 +25,39 @@
#include "gstlog.h"
#include "gstprops.h"
#include "gstpropsprivate.h"
GType _gst_props_type;
#define GST_PROPS_ENTRY_IS_VARIABLE(a) (((GstPropsEntry*)(a))->propstype > GST_PROPS_VAR_TYPE)
struct _GstPropsEntry {
GQuark propid;
GstPropsType propstype;
union {
/* flat values */
gboolean bool_data;
guint32 fourcc_data;
gint int_data;
gfloat float_data;
/* structured values */
struct {
GList *entries;
} list_data;
struct {
gchar *string;
} string_data;
struct {
gint min;
gint max;
} int_range_data;
struct {
gfloat min;
gfloat max;
} float_range_data;
} data;
};
static GMemChunk *_gst_props_entries_chunk;
static GMutex *_gst_props_entries_chunk_lock;
@ -49,6 +81,11 @@ _gst_props_initialize (void)
sizeof (GstProps), sizeof (GstProps) * 256,
G_ALLOC_AND_FREE);
_gst_props_chunk_lock = g_mutex_new ();
_gst_props_type = g_boxed_type_register_static ("GstProps",
(GBoxedCopyFunc) gst_props_ref,
(GBoxedFreeFunc) gst_props_unref);
}
static void
@ -57,31 +94,31 @@ gst_props_debug_entry (GstPropsEntry *entry)
const gchar *name = g_quark_to_string (entry->propid);
switch (entry->propstype) {
case GST_PROPS_INT_ID:
GST_DEBUG (GST_CAT_PROPERTIES, "%s: int %d", name, entry->data.int_data);
case GST_PROPS_INT_TYPE:
GST_DEBUG (GST_CAT_PROPERTIES, "%s: int %d\n", name, entry->data.int_data);
break;
case GST_PROPS_FLOAT_ID:
GST_DEBUG (GST_CAT_PROPERTIES, "%s: float %f", name, entry->data.float_data);
case GST_PROPS_FLOAT_TYPE:
GST_DEBUG (GST_CAT_PROPERTIES, "%s: float %f\n", name, entry->data.float_data);
break;
case GST_PROPS_FOURCC_ID:
GST_DEBUG (GST_CAT_PROPERTIES, "%s: fourcc %4.4s", name, (gchar*)&entry->data.fourcc_data);
case GST_PROPS_FOURCC_TYPE:
GST_DEBUG (GST_CAT_PROPERTIES, "%s: fourcc %4.4s\n", name, (gchar*)&entry->data.fourcc_data);
break;
case GST_PROPS_BOOL_ID:
GST_DEBUG (GST_CAT_PROPERTIES, "%s: bool %d", name, entry->data.bool_data);
case GST_PROPS_BOOL_TYPE:
GST_DEBUG (GST_CAT_PROPERTIES, "%s: bool %d\n", name, entry->data.bool_data);
break;
case GST_PROPS_STRING_ID:
GST_DEBUG (GST_CAT_PROPERTIES, "%s: string %s", name, entry->data.string_data.string);
case GST_PROPS_STRING_TYPE:
GST_DEBUG (GST_CAT_PROPERTIES, "%s: string %s\n", name, entry->data.string_data.string);
break;
case GST_PROPS_INT_RANGE_ID:
GST_DEBUG (GST_CAT_PROPERTIES, "%s: int range %d-%d", name, entry->data.int_range_data.min,
case GST_PROPS_INT_RANGE_TYPE:
GST_DEBUG (GST_CAT_PROPERTIES, "%s: int range %d-%d\n", name, entry->data.int_range_data.min,
entry->data.int_range_data.max);
break;
case GST_PROPS_FLOAT_RANGE_ID:
GST_DEBUG (GST_CAT_PROPERTIES, "%s: float range %f-%f", name, entry->data.float_range_data.min,
case GST_PROPS_FLOAT_RANGE_TYPE:
GST_DEBUG (GST_CAT_PROPERTIES, "%s: float range %f-%f\n", name, entry->data.float_range_data.min,
entry->data.float_range_data.max);
break;
case GST_PROPS_LIST_ID:
GST_DEBUG (GST_CAT_PROPERTIES, "[list]");
case GST_PROPS_LIST_TYPE:
GST_DEBUG (GST_CAT_PROPERTIES, "[list]\n");
{
GList *entries = entry->data.list_data.entries;
@ -122,30 +159,30 @@ props_find_func (gconstpointer a,
*/
#define GST_PROPS_ENTRY_FILL(entry, var_args) \
G_STMT_START { \
entry->propstype = va_arg (var_args, GstPropsId); \
entry->propstype = va_arg (var_args, GstPropsType); \
\
switch (entry->propstype) { \
case GST_PROPS_INT_ID: \
case GST_PROPS_INT_TYPE: \
entry->data.int_data = va_arg (var_args, gint); \
break; \
case GST_PROPS_INT_RANGE_ID: \
case GST_PROPS_INT_RANGE_TYPE: \
entry->data.int_range_data.min = va_arg (var_args, gint); \
entry->data.int_range_data.max = va_arg (var_args, gint); \
break; \
case GST_PROPS_FLOAT_ID: \
case GST_PROPS_FLOAT_TYPE: \
entry->data.float_data = va_arg (var_args, gdouble); \
break; \
case GST_PROPS_FLOAT_RANGE_ID: \
case GST_PROPS_FLOAT_RANGE_TYPE: \
entry->data.float_range_data.min = va_arg (var_args, gdouble); \
entry->data.float_range_data.max = va_arg (var_args, gdouble); \
break; \
case GST_PROPS_FOURCC_ID: \
case GST_PROPS_FOURCC_TYPE: \
entry->data.fourcc_data = va_arg (var_args, gulong); \
break; \
case GST_PROPS_BOOL_ID: \
case GST_PROPS_BOOL_TYPE: \
entry->data.bool_data = va_arg (var_args, gboolean); \
break; \
case GST_PROPS_STRING_ID: \
case GST_PROPS_STRING_TYPE: \
entry->data.string_data.string = g_strdup (va_arg (var_args, gchar*)); \
break; \
default: \
@ -153,6 +190,52 @@ G_STMT_START { \
} \
} G_STMT_END
#define GST_PROPS_ENTRY_READ(entry, var_args, safe, result) \
G_STMT_START { \
*result = TRUE; \
\
if (safe) { \
GstPropsType propstype = va_arg (var_args, GstPropsType); \
if (propstype != entry->propstype) { \
*result = FALSE; \
} \
} \
if (*result) { \
switch (entry->propstype) { \
case GST_PROPS_INT_TYPE: \
*(va_arg (var_args, gint*)) = entry->data.int_data; \
break; \
case GST_PROPS_INT_RANGE_TYPE: \
*(va_arg (var_args, gint*)) = entry->data.int_range_data.min; \
*(va_arg (var_args, gint*)) = entry->data.int_range_data.max; \
break; \
case GST_PROPS_FLOAT_TYPE: \
*(va_arg (var_args, gfloat*)) = entry->data.float_data; \
break; \
case GST_PROPS_FLOAT_RANGE_TYPE: \
*(va_arg (var_args, gfloat*)) = entry->data.float_range_data.min; \
*(va_arg (var_args, gfloat*)) = entry->data.float_range_data.max; \
break; \
case GST_PROPS_FOURCC_TYPE: \
*(va_arg (var_args, guint32*)) = entry->data.fourcc_data; \
break; \
case GST_PROPS_BOOL_TYPE: \
*(va_arg (var_args, gboolean*)) = entry->data.bool_data; \
break; \
case GST_PROPS_STRING_TYPE: \
*(va_arg (var_args, gchar**)) = entry->data.string_data.string; \
break; \
case GST_PROPS_LIST_TYPE: \
*(va_arg (var_args, GList**)) = entry->data.list_data.entries; \
break; \
default: \
*result = FALSE; \
break; \
} \
} \
} G_STMT_END
static GstPropsEntry*
gst_props_alloc_entry (void)
{
@ -169,10 +252,10 @@ static void
gst_props_entry_destroy (GstPropsEntry *entry)
{
switch (entry->propstype) {
case GST_PROPS_STRING_ID:
case GST_PROPS_STRING_TYPE:
g_free (entry->data.string_data.string);
break;
case GST_PROPS_LIST_ID:
case GST_PROPS_LIST_TYPE:
{
GList *entries = entry->data.list_data.entries;
@ -275,7 +358,7 @@ gst_props_merge_int_entries(GstPropsEntry * newentry, GstPropsEntry * oldentry)
gint new_min, new_max, old_min, old_max;
gboolean can_merge = FALSE;
if (newentry->propstype == GST_PROPS_INT_ID) {
if (newentry->propstype == GST_PROPS_INT_TYPE) {
new_min = newentry->data.int_data;
new_max = newentry->data.int_data;
} else {
@ -283,7 +366,7 @@ gst_props_merge_int_entries(GstPropsEntry * newentry, GstPropsEntry * oldentry)
new_max = newentry->data.int_range_data.max;
}
if (oldentry->propstype == GST_PROPS_INT_ID) {
if (oldentry->propstype == GST_PROPS_INT_TYPE) {
old_min = oldentry->data.int_data;
old_max = oldentry->data.int_data;
} else {
@ -312,10 +395,10 @@ gst_props_merge_int_entries(GstPropsEntry * newentry, GstPropsEntry * oldentry)
if (can_merge) {
if (new_min == new_max) {
newentry->propstype = GST_PROPS_INT_ID;
newentry->propstype = GST_PROPS_INT_TYPE;
newentry->data.int_data = new_min;
} else {
newentry->propstype = GST_PROPS_INT_RANGE_ID;
newentry->propstype = GST_PROPS_INT_RANGE_TYPE;
newentry->data.int_range_data.min = new_min;
newentry->data.int_range_data.max = new_max;
}
@ -411,27 +494,27 @@ gst_props_newv (const gchar *firstname, va_list var_args)
GST_PROPS_ENTRY_FILL (entry, var_args);
switch (entry->propstype) {
case GST_PROPS_INT_ID:
case GST_PROPS_INT_RANGE_ID:
case GST_PROPS_INT_TYPE:
case GST_PROPS_INT_RANGE_TYPE:
entry_type = GST_PROPS_LIST_T_INTS;
break;
case GST_PROPS_FLOAT_ID:
case GST_PROPS_FLOAT_RANGE_ID:
case GST_PROPS_FLOAT_TYPE:
case GST_PROPS_FLOAT_RANGE_TYPE:
entry_type = GST_PROPS_LIST_T_FLOATS;
break;
case GST_PROPS_FOURCC_ID:
case GST_PROPS_BOOL_ID:
case GST_PROPS_STRING_ID:
case GST_PROPS_FOURCC_TYPE:
case GST_PROPS_BOOL_TYPE:
case GST_PROPS_STRING_TYPE:
entry_type = GST_PROPS_LIST_T_MISC;
break;
case GST_PROPS_LIST_ID:
case GST_PROPS_LIST_TYPE:
g_return_val_if_fail (inlist == FALSE, NULL);
inlist = TRUE;
list_entry = entry;
list_type = GST_PROPS_LIST_T_UNSET;
list_entry->data.list_data.entries = NULL;
break;
case GST_PROPS_END_ID:
case GST_PROPS_END_TYPE:
g_return_val_if_fail (inlist == TRUE, NULL);
/* if list was of size 1, replace the list by a the item it contains */
@ -605,10 +688,10 @@ gst_props_entry_copy (GstPropsEntry *entry)
newentry = gst_props_alloc_entry ();
memcpy (newentry, entry, sizeof (GstPropsEntry));
if (entry->propstype == GST_PROPS_LIST_ID) {
if (entry->propstype == GST_PROPS_LIST_TYPE) {
newentry->data.list_data.entries = gst_props_list_copy (entry->data.list_data.entries);
}
else if (entry->propstype == GST_PROPS_STRING_ID) {
else if (entry->propstype == GST_PROPS_STRING_TYPE) {
newentry->data.string_data.string = g_strdup (entry->data.string_data.string);
}
@ -679,8 +762,8 @@ gst_props_copy_on_write (GstProps *props)
return new;
}
static GstPropsEntry*
gst_props_get_entry_func (GstProps *props, const gchar *name)
const GstPropsEntry*
gst_props_get_entry (GstProps *props, const gchar *name)
{
GList *lentry;
GQuark quark;
@ -703,134 +786,168 @@ gst_props_get_entry_func (GstProps *props, const gchar *name)
gboolean
gst_props_has_property (GstProps *props, const gchar *name)
{
return (gst_props_get_entry_func (props, name) != NULL);
return (gst_props_get_entry (props, name) != NULL);
}
/**
* gst_props_get_int:
* @props: the props to get the int value from
* @name: the name of the props entry to get.
*
* Get the named entry as an integer.
*
* Returns: the integer value of the named entry, 0 if not found.
*/
gint
gst_props_get_int (GstProps *props, const gchar *name)
{
GstPropsEntry *thisentry;
thisentry = gst_props_get_entry_func (props, name);
if (thisentry) {
return thisentry->data.int_data;
}
else {
g_warning ("props: property %s not found", name);
}
return 0;
}
/**
* gst_props_get_float:
* @props: the props to get the float value from
* @name: the name of the props entry to get.
*
* Get the named entry as a float.
*
* Returns: the float value of the named entry, 0.0 if not found.
*/
gfloat
gst_props_get_float (GstProps *props, const gchar *name)
{
GstPropsEntry *thisentry;
thisentry = gst_props_get_entry_func (props, name);
if (thisentry) {
return thisentry->data.float_data;
}
else {
g_warning ("props: property %s not found", name);
}
return 0.0F;
}
/**
* gst_props_get_fourcc_int:
* @props: the props to get the fourcc value from
* @name: the name of the props entry to get.
*
* Get the named entry as a gulong fourcc.
*
* Returns: the fourcc value of the named entry, 0 if not found.
*/
gulong
gst_props_get_fourcc_int (GstProps *props, const gchar *name)
{
GstPropsEntry *thisentry;
thisentry = gst_props_get_entry_func (props, name);
if (thisentry) {
return thisentry->data.fourcc_data;
}
else {
g_warning ("props: property %s not found", name);
}
return 0;
}
/**
* gst_props_get_boolean:
* @props: the props to get the fourcc value from
* @name: the name of the props entry to get.
*
* Get the named entry as a boolean value.
*
* Returns: the boolean value of the named entry, 0 if not found.
*/
gboolean
gst_props_get_boolean (GstProps *props, const gchar *name)
gst_props_has_property_typed (GstProps *props, const gchar *name, GstPropsType type)
{
GstPropsEntry *thisentry;
const GstPropsEntry *entry;
thisentry = gst_props_get_entry_func (props, name);
entry = gst_props_get_entry (props, name);
if (!entry)
return FALSE;
if (thisentry) {
return thisentry->data.bool_data;
}
else {
g_warning ("props: property %s not found", name);
}
return 0;
return (entry->propstype == type);
}
gboolean
gst_props_has_fixed_property (GstProps *props, const gchar *name)
{
const GstPropsEntry *entry;
entry = gst_props_get_entry (props, name);
if (!entry)
return FALSE;
return !GST_PROPS_ENTRY_IS_VARIABLE (entry);
}
GstPropsType
gst_props_entry_get_type (const GstPropsEntry *entry)
{
g_return_val_if_fail (entry != NULL, GST_PROPS_INVALID_TYPE);
return entry->propstype;
}
/**
* gst_props_get_string:
* @props: the props to get the fourcc value from
* @name: the name of the props entry to get.
*
* Get the named entry as a string value.
*
* Returns: the string value of the named entry, NULL if not found.
*/
const gchar*
gst_props_get_string (GstProps *props, const gchar *name)
gst_props_entry_get_name (const GstPropsEntry *entry)
{
GstPropsEntry *thisentry;
g_return_val_if_fail (entry != NULL, NULL);
thisentry = gst_props_get_entry_func (props, name);
if (thisentry) {
return thisentry->data.string_data.string;
}
else {
g_warning ("props: property %s not found", name);
}
return NULL;
return g_quark_to_string (entry->propid);
}
gboolean
gst_props_entry_is_fixed (const GstPropsEntry *entry)
{
g_return_val_if_fail (entry != NULL, FALSE);
return !GST_PROPS_ENTRY_IS_VARIABLE (entry);
}
static gboolean
gst_props_entry_getv (const GstPropsEntry *entry, gboolean safe, va_list var_args)
{
gboolean result;
GST_PROPS_ENTRY_READ (entry, var_args, safe, &result);
return result;
}
gboolean
gst_props_entry_get (const GstPropsEntry *entry, ...)
{
gboolean result;
va_list var_args;
g_return_val_if_fail (entry != NULL, FALSE);
va_start (var_args, entry);
result = gst_props_entry_getv (entry, FALSE, var_args);
va_end (var_args);
return result;
}
static gboolean
gst_props_entry_get_safe (const GstPropsEntry *entry, ...)
{
gboolean result;
va_list var_args;
g_return_val_if_fail (entry != NULL, FALSE);
va_start (var_args, entry);
result = gst_props_entry_getv (entry, TRUE, var_args);
va_end (var_args);
return result;
}
gboolean
gst_props_get (GstProps *props, gchar *first_name, ...)
{
va_list var_args;
va_start (var_args, first_name);
while (first_name) {
const GstPropsEntry *entry = gst_props_get_entry (props, first_name);
gboolean result;
if (!entry) return FALSE;
GST_PROPS_ENTRY_READ (entry, var_args, FALSE, &result);
if (!result) return FALSE;
first_name = va_arg (var_args, gchar *);
}
va_end (var_args);
return TRUE;
}
gboolean
gst_props_entry_get_int (const GstPropsEntry *entry, gint *val)
{
return gst_props_entry_get_safe (entry, GST_PROPS_INT_TYPE, val);
}
gboolean
gst_props_entry_get_float (const GstPropsEntry *entry, gfloat *val)
{
return gst_props_entry_get_safe (entry, GST_PROPS_FLOAT_TYPE, val);
}
gboolean
gst_props_entry_get_fourcc_int (const GstPropsEntry *entry, guint32 *val)
{
return gst_props_entry_get_safe (entry, GST_PROPS_FOURCC_TYPE, val);
}
gboolean
gst_props_entry_get_boolean (const GstPropsEntry *entry, gboolean *val)
{
return gst_props_entry_get_safe (entry, GST_PROPS_BOOL_TYPE, val);
}
gboolean
gst_props_entry_get_string (const GstPropsEntry *entry, const gchar **val)
{
return gst_props_entry_get_safe (entry, GST_PROPS_STRING_TYPE, val);
}
gboolean
gst_props_entry_get_int_range (const GstPropsEntry *entry, gint *min, gint *max)
{
return gst_props_entry_get_safe (entry, GST_PROPS_INT_RANGE_TYPE, min, max);
}
gboolean
gst_props_entry_get_float_range (const GstPropsEntry *entry, gfloat *min, gfloat *max)
{
return gst_props_entry_get_safe (entry, GST_PROPS_FLOAT_RANGE_TYPE, min, max);
}
gboolean
gst_props_entry_get_list (const GstPropsEntry *entry, const GList **val)
{
return gst_props_entry_get_safe (entry, GST_PROPS_LIST_TYPE, val);
}
/**
* gst_props_merge:
* @props: the property to merge into
@ -887,12 +1004,12 @@ gst_props_entry_check_compatibility (GstPropsEntry *entry1, GstPropsEntry *entry
GST_DEBUG (GST_CAT_PROPERTIES,"compare: %s %s", g_quark_to_string (entry1->propid),
g_quark_to_string (entry2->propid));
if (entry2->propstype == GST_PROPS_LIST_ID && entry1->propstype != GST_PROPS_LIST_ID) {
if (entry2->propstype == GST_PROPS_LIST_TYPE && entry1->propstype != GST_PROPS_LIST_TYPE) {
return gst_props_entry_check_list_compatibility (entry1, entry2);
}
switch (entry1->propstype) {
case GST_PROPS_LIST_ID:
case GST_PROPS_LIST_TYPE:
{
GList *entrylist = entry1->data.list_data.entries;
gboolean valid = TRUE; /* innocent until proven guilty */
@ -907,79 +1024,79 @@ gst_props_entry_check_compatibility (GstPropsEntry *entry1, GstPropsEntry *entry
return valid;
}
case GST_PROPS_INT_RANGE_ID:
case GST_PROPS_INT_RANGE_TYPE:
switch (entry2->propstype) {
/* a - b <---> a - c */
case GST_PROPS_INT_RANGE_ID:
case GST_PROPS_INT_RANGE_TYPE:
return (entry2->data.int_range_data.min <= entry1->data.int_range_data.min &&
entry2->data.int_range_data.max >= entry1->data.int_range_data.max);
default:
break;
}
break;
case GST_PROPS_FLOAT_RANGE_ID:
case GST_PROPS_FLOAT_RANGE_TYPE:
switch (entry2->propstype) {
/* a - b <---> a - c */
case GST_PROPS_FLOAT_RANGE_ID:
case GST_PROPS_FLOAT_RANGE_TYPE:
return (entry2->data.float_range_data.min <= entry1->data.float_range_data.min &&
entry2->data.float_range_data.max >= entry1->data.float_range_data.max);
default:
break;
}
break;
case GST_PROPS_FOURCC_ID:
case GST_PROPS_FOURCC_TYPE:
switch (entry2->propstype) {
/* b <---> a */
case GST_PROPS_FOURCC_ID:
GST_DEBUG(GST_CAT_PROPERTIES,"\"%4.4s\" <--> \"%4.4s\" ?",
case GST_PROPS_FOURCC_TYPE:
GST_DEBUG(GST_CAT_PROPERTIES,"\"%4.4s\" <--> \"%4.4s\" ?\n",
(char*) &entry2->data.fourcc_data, (char*) &entry1->data.fourcc_data);
return (entry2->data.fourcc_data == entry1->data.fourcc_data);
default:
break;
}
break;
case GST_PROPS_INT_ID:
case GST_PROPS_INT_TYPE:
switch (entry2->propstype) {
/* b <---> a - d */
case GST_PROPS_INT_RANGE_ID:
GST_DEBUG(GST_CAT_PROPERTIES,"%d <= %d <= %d ?",entry2->data.int_range_data.min,
case GST_PROPS_INT_RANGE_TYPE:
GST_DEBUG(GST_CAT_PROPERTIES,"%d <= %d <= %d ?\n",entry2->data.int_range_data.min,
entry1->data.int_data,entry2->data.int_range_data.max);
return (entry2->data.int_range_data.min <= entry1->data.int_data &&
entry2->data.int_range_data.max >= entry1->data.int_data);
/* b <---> a */
case GST_PROPS_INT_ID:
GST_DEBUG(GST_CAT_PROPERTIES,"%d == %d ?",entry1->data.int_data,entry2->data.int_data);
case GST_PROPS_INT_TYPE:
GST_DEBUG(GST_CAT_PROPERTIES,"%d == %d ?\n",entry1->data.int_data,entry2->data.int_data);
return (entry2->data.int_data == entry1->data.int_data);
default:
break;
}
break;
case GST_PROPS_FLOAT_ID:
case GST_PROPS_FLOAT_TYPE:
switch (entry2->propstype) {
/* b <---> a - d */
case GST_PROPS_FLOAT_RANGE_ID:
case GST_PROPS_FLOAT_RANGE_TYPE:
return (entry2->data.float_range_data.min <= entry1->data.float_data &&
entry2->data.float_range_data.max >= entry1->data.float_data);
/* b <---> a */
case GST_PROPS_FLOAT_ID:
case GST_PROPS_FLOAT_TYPE:
return (entry2->data.float_data == entry1->data.float_data);
default:
break;
}
break;
case GST_PROPS_BOOL_ID:
case GST_PROPS_BOOL_TYPE:
switch (entry2->propstype) {
/* t <---> t */
case GST_PROPS_BOOL_ID:
case GST_PROPS_BOOL_TYPE:
return (entry2->data.bool_data == entry1->data.bool_data);
default:
break;
}
case GST_PROPS_STRING_ID:
case GST_PROPS_STRING_TYPE:
switch (entry2->propstype) {
/* t <---> t */
case GST_PROPS_STRING_ID:
GST_DEBUG(GST_CAT_PROPERTIES,"\"%s\" <--> \"%s\" ?",
case GST_PROPS_STRING_TYPE:
GST_DEBUG(GST_CAT_PROPERTIES,"\"%s\" <--> \"%s\" ?\n",
entry2->data.string_data.string, entry1->data.string_data.string);
return (!strcmp (entry2->data.string_data.string, entry1->data.string_data.string));
default:
@ -1065,9 +1182,9 @@ gst_props_entry_intersect (GstPropsEntry *entry1, GstPropsEntry *entry2)
/* try to move the ranges and lists first */
switch (entry2->propstype) {
case GST_PROPS_INT_RANGE_ID:
case GST_PROPS_FLOAT_RANGE_ID:
case GST_PROPS_LIST_ID:
case GST_PROPS_INT_RANGE_TYPE:
case GST_PROPS_FLOAT_RANGE_TYPE:
case GST_PROPS_LIST_TYPE:
{
GstPropsEntry *temp;
@ -1080,7 +1197,7 @@ gst_props_entry_intersect (GstPropsEntry *entry1, GstPropsEntry *entry2)
}
switch (entry1->propstype) {
case GST_PROPS_LIST_ID:
case GST_PROPS_LIST_TYPE:
{
GList *entrylist = entry1->data.list_data.entries;
GList *intersection = NULL;
@ -1092,7 +1209,7 @@ gst_props_entry_intersect (GstPropsEntry *entry1, GstPropsEntry *entry2)
intersectentry = gst_props_entry_intersect (entry2, entry);
if (intersectentry) {
if (intersectentry->propstype == GST_PROPS_LIST_ID) {
if (intersectentry->propstype == GST_PROPS_LIST_TYPE) {
intersection = g_list_concat (intersection, intersectentry->data.list_data.entries);
/* set the list to NULL because the entries are concatenated to the above
* list and we don't want to free them */
@ -1115,16 +1232,16 @@ gst_props_entry_intersect (GstPropsEntry *entry1, GstPropsEntry *entry2)
else {
result = gst_props_alloc_entry ();
result->propid = entry1->propid;
result->propstype = GST_PROPS_LIST_ID;
result->propstype = GST_PROPS_LIST_TYPE;
result->data.list_data.entries = g_list_reverse (intersection);
}
}
return result;
}
case GST_PROPS_INT_RANGE_ID:
case GST_PROPS_INT_RANGE_TYPE:
switch (entry2->propstype) {
/* a - b <---> a - c */
case GST_PROPS_INT_RANGE_ID:
case GST_PROPS_INT_RANGE_TYPE:
{
gint lower = MAX (entry1->data.int_range_data.min, entry2->data.int_range_data.min);
gint upper = MIN (entry1->data.int_range_data.max, entry2->data.int_range_data.max);
@ -1134,27 +1251,27 @@ gst_props_entry_intersect (GstPropsEntry *entry1, GstPropsEntry *entry2)
result->propid = entry1->propid;
if (lower == upper) {
result->propstype = GST_PROPS_INT_ID;
result->propstype = GST_PROPS_INT_TYPE;
result->data.int_data = lower;
}
else {
result->propstype = GST_PROPS_INT_RANGE_ID;
result->propstype = GST_PROPS_INT_RANGE_TYPE;
result->data.int_range_data.min = lower;
result->data.int_range_data.max = upper;
}
}
break;
}
case GST_PROPS_LIST_ID:
case GST_PROPS_LIST_TYPE:
{
GList *entries = entry2->data.list_data.entries;
result = gst_props_alloc_entry ();
result->propid = entry1->propid;
result->propstype = GST_PROPS_LIST_ID;
result->propstype = GST_PROPS_LIST_TYPE;
result->data.list_data.entries = NULL;
while (entries) {
GstPropsEntry * this = (GstPropsEntry *)entries->data;
if (this->propstype != GST_PROPS_INT_ID) {
if (this->propstype != GST_PROPS_INT_TYPE) {
/* no hope, this list doesn't even contain ints! */
gst_props_entry_destroy (result);
result = NULL;
@ -1169,7 +1286,7 @@ gst_props_entry_intersect (GstPropsEntry *entry1, GstPropsEntry *entry2)
}
break;
}
case GST_PROPS_INT_ID:
case GST_PROPS_INT_TYPE:
{
if (entry1->data.int_range_data.min <= entry2->data.int_data &&
entry1->data.int_range_data.max >= entry2->data.int_data) {
@ -1181,10 +1298,10 @@ gst_props_entry_intersect (GstPropsEntry *entry1, GstPropsEntry *entry2)
break;
}
break;
case GST_PROPS_FLOAT_RANGE_ID:
case GST_PROPS_FLOAT_RANGE_TYPE:
switch (entry2->propstype) {
/* a - b <---> a - c */
case GST_PROPS_FLOAT_RANGE_ID:
case GST_PROPS_FLOAT_RANGE_TYPE:
{
gfloat lower = MAX (entry1->data.float_range_data.min, entry2->data.float_range_data.min);
gfloat upper = MIN (entry1->data.float_range_data.max, entry2->data.float_range_data.max);
@ -1194,18 +1311,18 @@ gst_props_entry_intersect (GstPropsEntry *entry1, GstPropsEntry *entry2)
result->propid = entry1->propid;
if (lower == upper) {
result->propstype = GST_PROPS_FLOAT_ID;
result->propstype = GST_PROPS_FLOAT_TYPE;
result->data.float_data = lower;
}
else {
result->propstype = GST_PROPS_FLOAT_RANGE_ID;
result->propstype = GST_PROPS_FLOAT_RANGE_TYPE;
result->data.float_range_data.min = lower;
result->data.float_range_data.max = upper;
}
}
break;
}
case GST_PROPS_FLOAT_ID:
case GST_PROPS_FLOAT_TYPE:
if (entry1->data.float_range_data.min <= entry2->data.float_data &&
entry1->data.float_range_data.max >= entry2->data.float_data) {
result = gst_props_entry_copy (entry2);
@ -1214,49 +1331,49 @@ gst_props_entry_intersect (GstPropsEntry *entry1, GstPropsEntry *entry2)
break;
}
break;
case GST_PROPS_FOURCC_ID:
case GST_PROPS_FOURCC_TYPE:
switch (entry2->propstype) {
/* b <---> a */
case GST_PROPS_FOURCC_ID:
case GST_PROPS_FOURCC_TYPE:
if (entry1->data.fourcc_data == entry2->data.fourcc_data)
result = gst_props_entry_copy (entry1);
default:
break;
}
break;
case GST_PROPS_INT_ID:
case GST_PROPS_INT_TYPE:
switch (entry2->propstype) {
/* b <---> a */
case GST_PROPS_INT_ID:
case GST_PROPS_INT_TYPE:
if (entry1->data.int_data == entry2->data.int_data)
result = gst_props_entry_copy (entry1);
default:
break;
}
break;
case GST_PROPS_FLOAT_ID:
case GST_PROPS_FLOAT_TYPE:
switch (entry2->propstype) {
/* b <---> a */
case GST_PROPS_FLOAT_ID:
case GST_PROPS_FLOAT_TYPE:
if (entry1->data.float_data == entry2->data.float_data)
result = gst_props_entry_copy (entry1);
default:
break;
}
break;
case GST_PROPS_BOOL_ID:
case GST_PROPS_BOOL_TYPE:
switch (entry2->propstype) {
/* t <---> t */
case GST_PROPS_BOOL_ID:
case GST_PROPS_BOOL_TYPE:
if (entry1->data.bool_data == entry2->data.bool_data)
result = gst_props_entry_copy (entry1);
default:
break;
}
case GST_PROPS_STRING_ID:
case GST_PROPS_STRING_TYPE:
switch (entry2->propstype) {
/* t <---> t */
case GST_PROPS_STRING_ID:
case GST_PROPS_STRING_TYPE:
if (!strcmp (entry1->data.string_data.string, entry2->data.string_data.string))
result = gst_props_entry_copy (entry1);
default:
@ -1392,7 +1509,7 @@ gst_props_normalize (GstProps *props)
while (entries) {
GstPropsEntry *entry = (GstPropsEntry *) entries->data;
if (entry->propstype == GST_PROPS_LIST_ID) {
if (entry->propstype == GST_PROPS_LIST_TYPE) {
GList *list_entries = entry->data.list_data.entries;
while (list_entries) {
@ -1443,14 +1560,14 @@ gst_props_save_thyself_func (GstPropsEntry *entry, xmlNodePtr parent)
gchar *str;
switch (entry->propstype) {
case GST_PROPS_INT_ID:
case GST_PROPS_INT_TYPE:
subtree = xmlNewChild (parent, NULL, "int", NULL);
xmlNewProp (subtree, "name", g_quark_to_string (entry->propid));
str = g_strdup_printf ("%d", entry->data.int_data);
xmlNewProp (subtree, "value", str);
g_free(str);
break;
case GST_PROPS_INT_RANGE_ID:
case GST_PROPS_INT_RANGE_TYPE:
subtree = xmlNewChild (parent, NULL, "range", NULL);
xmlNewProp (subtree, "name", g_quark_to_string (entry->propid));
str = g_strdup_printf ("%d", entry->data.int_range_data.min);
@ -1460,14 +1577,14 @@ gst_props_save_thyself_func (GstPropsEntry *entry, xmlNodePtr parent)
xmlNewProp (subtree, "max", str);
g_free(str);
break;
case GST_PROPS_FLOAT_ID:
case GST_PROPS_FLOAT_TYPE:
subtree = xmlNewChild (parent, NULL, "float", NULL);
xmlNewProp (subtree, "name", g_quark_to_string (entry->propid));
str = g_strdup_printf ("%f", entry->data.float_data);
xmlNewProp (subtree, "value", str);
g_free(str);
break;
case GST_PROPS_FLOAT_RANGE_ID:
case GST_PROPS_FLOAT_RANGE_TYPE:
subtree = xmlNewChild (parent, NULL, "floatrange", NULL);
xmlNewProp (subtree, "name", g_quark_to_string (entry->propid));
str = g_strdup_printf ("%f", entry->data.float_range_data.min);
@ -1477,7 +1594,7 @@ gst_props_save_thyself_func (GstPropsEntry *entry, xmlNodePtr parent)
xmlNewProp (subtree, "max", str);
g_free(str);
break;
case GST_PROPS_FOURCC_ID:
case GST_PROPS_FOURCC_TYPE:
str = g_strdup_printf ("%4.4s", (gchar *)&entry->data.fourcc_data);
xmlAddChild (parent, xmlNewComment (str));
g_free(str);
@ -1487,12 +1604,12 @@ gst_props_save_thyself_func (GstPropsEntry *entry, xmlNodePtr parent)
xmlNewProp (subtree, "hexvalue", str);
g_free(str);
break;
case GST_PROPS_BOOL_ID:
case GST_PROPS_BOOL_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"));
break;
case GST_PROPS_STRING_ID:
case GST_PROPS_STRING_TYPE:
subtree = xmlNewChild (parent, NULL, "string", NULL);
xmlNewProp (subtree, "name", g_quark_to_string (entry->propid));
xmlNewProp (subtree, "value", entry->data.string_data.string);
@ -1528,7 +1645,7 @@ gst_props_save_thyself (GstProps *props, xmlNodePtr parent)
GstPropsEntry *entry = (GstPropsEntry *) proplist->data;
switch (entry->propstype) {
case GST_PROPS_LIST_ID:
case GST_PROPS_LIST_TYPE:
subtree = xmlNewChild (parent, NULL, "list", NULL);
xmlNewProp (subtree, "name", g_quark_to_string (entry->propid));
g_list_foreach (entry->data.list_data.entries, (GFunc) gst_props_save_thyself_func, subtree);
@ -1552,7 +1669,7 @@ gst_props_load_thyself_func (xmlNodePtr field)
entry = gst_props_alloc_entry ();
if (!strcmp(field->name, "int")) {
entry->propstype = GST_PROPS_INT_ID;
entry->propstype = GST_PROPS_INT_TYPE;
prop = xmlGetProp(field, "name");
entry->propid = g_quark_from_string (prop);
g_free (prop);
@ -1561,7 +1678,7 @@ gst_props_load_thyself_func (xmlNodePtr field)
g_free (prop);
}
else if (!strcmp(field->name, "range")) {
entry->propstype = GST_PROPS_INT_RANGE_ID;
entry->propstype = GST_PROPS_INT_RANGE_TYPE;
prop = xmlGetProp(field, "name");
entry->propid = g_quark_from_string (prop);
g_free (prop);
@ -1573,7 +1690,7 @@ gst_props_load_thyself_func (xmlNodePtr field)
g_free (prop);
}
else if (!strcmp(field->name, "float")) {
entry->propstype = GST_PROPS_FLOAT_ID;
entry->propstype = GST_PROPS_FLOAT_TYPE;
prop = xmlGetProp(field, "name");
entry->propid = g_quark_from_string (prop);
g_free (prop);
@ -1582,7 +1699,7 @@ gst_props_load_thyself_func (xmlNodePtr field)
g_free (prop);
}
else if (!strcmp(field->name, "floatrange")) {
entry->propstype = GST_PROPS_FLOAT_RANGE_ID;
entry->propstype = GST_PROPS_FLOAT_RANGE_TYPE;
prop = xmlGetProp(field, "name");
entry->propid = g_quark_from_string (prop);
g_free (prop);
@ -1594,7 +1711,7 @@ gst_props_load_thyself_func (xmlNodePtr field)
g_free (prop);
}
else if (!strcmp(field->name, "boolean")) {
entry->propstype = GST_PROPS_BOOL_ID;
entry->propstype = GST_PROPS_BOOL_TYPE;
prop = xmlGetProp(field, "name");
entry->propid = g_quark_from_string (prop);
g_free (prop);
@ -1604,7 +1721,7 @@ gst_props_load_thyself_func (xmlNodePtr field)
g_free (prop);
}
else if (!strcmp(field->name, "fourcc")) {
entry->propstype = GST_PROPS_FOURCC_ID;
entry->propstype = GST_PROPS_FOURCC_TYPE;
prop = xmlGetProp(field, "name");
entry->propid = g_quark_from_string (prop);
g_free (prop);
@ -1613,7 +1730,7 @@ gst_props_load_thyself_func (xmlNodePtr field)
g_free (prop);
}
else if (!strcmp(field->name, "string")) {
entry->propstype = GST_PROPS_STRING_ID;
entry->propstype = GST_PROPS_STRING_TYPE;
prop = xmlGetProp(field, "name");
entry->propid = g_quark_from_string (prop);
g_free (prop);
@ -1655,7 +1772,7 @@ gst_props_load_thyself (xmlNodePtr parent)
prop = xmlGetProp (field, "name");
entry->propid = g_quark_from_string (prop);
g_free (prop);
entry->propstype = GST_PROPS_LIST_ID;
entry->propstype = GST_PROPS_LIST_TYPE;
entry->data.list_data.entries = NULL;
while (subfield) {

View file

@ -26,86 +26,110 @@
#include <gst/gstconfig.h>
#include <glib.h>
#include <glib-object.h>
typedef struct _GstProps GstProps;
extern GType _gst_props_type;
#define GST_TYPE_PROPS (_get_props_type)
typedef enum {
GST_PROPS_END_ID = 0,
GST_PROPS_INT_ID,
GST_PROPS_FLOAT_ID,
GST_PROPS_FOURCC_ID,
GST_PROPS_BOOL_ID,
GST_PROPS_STRING_ID,
GST_PROPS_END_TYPE = 0,
GST_PROPS_VAR_ID, /* after this marker start the variable properties */
GST_PROPS_INVALID_TYPE,
GST_PROPS_LIST_ID,
GST_PROPS_FLOAT_RANGE_ID,
GST_PROPS_INT_RANGE_ID,
GST_PROPS_INT_TYPE,
GST_PROPS_FLOAT_TYPE,
GST_PROPS_FOURCC_TYPE,
GST_PROPS_BOOL_TYPE,
GST_PROPS_STRING_TYPE,
GST_PROPS_LAST_ID = GST_PROPS_END_ID + 16,
} GstPropsId;
GST_PROPS_VAR_TYPE, /* after this marker start the variable properties */
GST_PROPS_LIST_TYPE,
GST_PROPS_FLOAT_RANGE_TYPE,
GST_PROPS_INT_RANGE_TYPE,
GST_PROPS_LAST_TYPE = GST_PROPS_END_TYPE + 16,
} GstPropsType;
#define GST_MAKE_FOURCC(a,b,c,d) ((a)|(b)<<8|(c)<<16|(d)<<24)
#define GST_STR_FOURCC(f) (((f)[0])|((f)[1]<<8)|((f)[2]<<16)|((f)[3]<<24))
#define GST_PROPS_LIST(a...) GST_PROPS_LIST_ID,##a,NULL
#define GST_PROPS_INT(a) GST_PROPS_INT_ID,(a)
#define GST_PROPS_INT_RANGE(a,b) GST_PROPS_INT_RANGE_ID,(a),(b)
#define GST_PROPS_FLOAT(a) GST_PROPS_FLOAT_ID,(a)
#define GST_PROPS_FLOAT_RANGE(a,b) GST_PROPS_FLOAT_RANGE_ID,(a),(b)
#define GST_PROPS_FOURCC(a) GST_PROPS_FOURCC_ID,(a)
#define GST_PROPS_BOOLEAN(a) GST_PROPS_BOOL_ID,(a)
#define GST_PROPS_STRING(a) GST_PROPS_STRING_ID,(a)
#define GST_PROPS_LIST(a...) GST_PROPS_LIST_TYPE,##a,NULL
#define GST_PROPS_INT(a) GST_PROPS_INT_TYPE,(a)
#define GST_PROPS_INT_RANGE(a,b) GST_PROPS_INT_RANGE_TYPE,(a),(b)
#define GST_PROPS_FLOAT(a) GST_PROPS_FLOAT_TYPE,(a)
#define GST_PROPS_FLOAT_RANGE(a,b) GST_PROPS_FLOAT_RANGE_TYPE,(a),(b)
#define GST_PROPS_FOURCC(a) GST_PROPS_FOURCC_TYPE,(a)
#define GST_PROPS_BOOLEAN(a) GST_PROPS_BOOL_TYPE,(a)
#define GST_PROPS_STRING(a) GST_PROPS_STRING_TYPE,(a)
#define GST_PROPS_INT_POSITIVE GST_PROPS_INT_RANGE(0,G_MAXINT)
#define GST_PROPS_INT_NEGATIVE GST_PROPS_INT_RANGE(G_MININT,0)
#define GST_PROPS_INT_ANY GST_PROPS_INT_RANGE(G_MININT,G_MAXINT)
typedef struct _GstPropsEntry GstPropsEntry;
struct _GstProps {
gint refcount;
GMutex *lock;
gboolean fixed;
GList *properties; /* real properties for this property */
};
/* initialize the subsystem */
void _gst_props_initialize (void);
void _gst_props_initialize (void);
GstProps* gst_props_new (const gchar *firstname, ...);
GstProps* gst_props_newv (const gchar *firstname, va_list var_args);
GstProps* gst_props_new (const gchar *firstname, ...);
GstProps* gst_props_newv (const gchar *firstname, va_list var_args);
void gst_props_unref (GstProps *props);
void gst_props_ref (GstProps *props);
void gst_props_destroy (GstProps *props);
void gst_props_unref (GstProps *props);
void gst_props_ref (GstProps *props);
void gst_props_destroy (GstProps *props);
void gst_props_debug (GstProps *props);
void gst_props_debug (GstProps *props);
GstProps* gst_props_copy (GstProps *props);
GstProps* gst_props_copy_on_write (GstProps *props);
GstProps* gst_props_copy (GstProps *props);
GstProps* gst_props_copy_on_write (GstProps *props);
GstProps* gst_props_merge (GstProps *props, GstProps *tomerge);
GstProps* gst_props_merge (GstProps *props, GstProps *tomerge);
gboolean gst_props_check_compatibility (GstProps *fromprops, GstProps *toprops);
GstProps* gst_props_intersect (GstProps *props1, GstProps *props2);
GList* gst_props_normalize (GstProps *props);
gboolean gst_props_check_compatibility (GstProps *fromprops, GstProps *toprops);
GstProps* gst_props_intersect (GstProps *props1, GstProps *props2);
GList* gst_props_normalize (GstProps *props);
GstProps* gst_props_set (GstProps *props, const gchar *name, ...);
GstProps* gst_props_set (GstProps *props, const gchar *name, ...);
gboolean gst_props_get (GstProps *props, gchar *first_name, ...);
gboolean gst_props_has_property (GstProps *props, const gchar *name);
gboolean gst_props_has_property (GstProps *props, const gchar *name);
gboolean gst_props_has_property_typed (GstProps *props, const gchar *name, GstPropsType type);
gboolean gst_props_has_fixed_property (GstProps *props, const gchar *name);
/* working with props entries */
const GstPropsEntry* gst_props_get_entry (GstProps *props, const gchar *name);
GstPropsType gst_props_entry_get_type (const GstPropsEntry *entry);
const gchar* gst_props_entry_get_name (const GstPropsEntry *entry);
gboolean gst_props_entry_is_fixed (const GstPropsEntry *entry);
gboolean gst_props_entry_get (const GstPropsEntry *props, ...);
gboolean gst_props_entry_get_int (const GstPropsEntry *entry, gint *val);
gboolean gst_props_entry_get_float (const GstPropsEntry *entry, gfloat *val);
gboolean gst_props_entry_get_fourcc_int (const GstPropsEntry *entry, guint32 *val);
gboolean gst_props_entry_get_boolean (const GstPropsEntry *entry, gboolean *val);
gboolean gst_props_entry_get_string (const GstPropsEntry *entry, const gchar **val);
gboolean gst_props_entry_get_int_range (const GstPropsEntry *entry, gint *min, gint *max);
gboolean gst_props_entry_get_float_range (const GstPropsEntry *entry, gfloat *min, gfloat *max);
gboolean gst_props_entry_get_list (const GstPropsEntry *entry, const GList **val);
gint gst_props_get_int (GstProps *props, const gchar *name);
gfloat gst_props_get_float (GstProps *props, const gchar *name);
gulong gst_props_get_fourcc_int (GstProps *props, const gchar *name);
gboolean gst_props_get_boolean (GstProps *props, const gchar *name);
const gchar* gst_props_get_string (GstProps *props, const gchar *name);
#ifndef GST_DISABLE_LOADSAVE
xmlNodePtr gst_props_save_thyself (GstProps *props, xmlNodePtr parent);
GstProps* gst_props_load_thyself (xmlNodePtr parent);
xmlNodePtr gst_props_save_thyself (GstProps *props, xmlNodePtr parent);
GstProps* gst_props_load_thyself (xmlNodePtr parent);
#endif
#endif /* __GST_PROPS_H__ */

View file

@ -1,62 +0,0 @@
/* GStreamer
* Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
* 2000 Wim Taymans <wtay@chello.be>
*
* gstpropsprivate.h: Private header for properties subsystem
*
* 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_PROPS_PRIV_H__
#define __GST_PROPS_PRIV_H__
#include <gst/gstprops.h>
#define GST_PROPS_ENTRY_IS_VARIABLE(a) (((GstPropsEntry*)(a))->propstype > GST_PROPS_VAR_ID)
typedef struct _GstPropsEntry GstPropsEntry;
struct _GstPropsEntry {
GQuark propid;
GstPropsId propstype;
union {
/* flat values */
gboolean bool_data;
guint32 fourcc_data;
gint int_data;
gfloat float_data;
/* structured values */
struct {
GList *entries;
} list_data;
struct {
gchar *string;
} string_data;
struct {
gint min;
gint max;
} int_range_data;
struct {
gfloat min;
gfloat max;
} float_range_data;
} data;
};
#endif /* __GST_PROPS_PRIV_H__ */

View file

@ -83,7 +83,6 @@ static GstBuffer * gst_queue_get (GstPad *pad);
static GstBufferPool* gst_queue_get_bufferpool (GstPad *pad);
static void gst_queue_locked_flush (GstQueue *queue);
static void gst_queue_flush (GstQueue *queue);
static GstElementStateReturn gst_queue_change_state (GstElement *element);
@ -274,15 +273,6 @@ gst_queue_locked_flush (GstQueue *queue)
queue->timeval = NULL;
}
static void
gst_queue_flush (GstQueue *queue)
{
g_mutex_lock (queue->qlock);
gst_queue_locked_flush (queue);
g_mutex_unlock (queue->qlock);
}
static void
gst_queue_chain (GstPad *pad, GstBuffer *buf)
{
@ -378,7 +368,7 @@ restart:
return;
}
else {
gst_element_info (GST_ELEMENT (queue), "waiting for the app to restart source pad elements");
g_print ("%s: waiting for the app to restart source pad elements\n", GST_ELEMENT_NAME (queue));
}
}
@ -459,7 +449,7 @@ restart:
goto restart;
}
else {
gst_element_info (GST_ELEMENT (queue), "waiting for the app to restart sink pad elements");
g_print ("%s: waiting for the app to restart source pad elements\n", GST_ELEMENT_NAME (queue));
}
}

View file

@ -24,6 +24,7 @@
#include "gst_private.h"
#include "gstsystemclock.h"
#include "gstscheduler.h"
static void gst_scheduler_class_init (GstSchedulerClass *klass);
@ -67,6 +68,13 @@ gst_scheduler_class_init (GstSchedulerClass *klass)
static void
gst_scheduler_init (GstScheduler *sched)
{
sched->clock_providers = NULL;
sched->clock_receivers = NULL;
sched->schedulers = NULL;
sched->state = GST_SCHEDULER_STATE_NONE;
sched->parent = NULL;
sched->parent_sched = NULL;
sched->clock = NULL;
}
/**
@ -171,10 +179,47 @@ gst_scheduler_add_element (GstScheduler *sched, GstElement *element)
g_return_if_fail (GST_IS_SCHEDULER (sched));
g_return_if_fail (GST_IS_ELEMENT (element));
if (element->getclockfunc) {
sched->clock_providers = g_list_prepend (sched->clock_providers, element);
}
if (element->setclockfunc) {
sched->clock_receivers = g_list_prepend (sched->clock_receivers, element);
}
if (CLASS (sched)->add_element)
CLASS (sched)->add_element (sched, element);
}
/**
* gst_scheduler_remove_element:
* @sched: the schedulerr
* @element: the element to remov
*
* Remove an element from the schedulerr.
*/
void
gst_scheduler_remove_element (GstScheduler *sched, GstElement *element)
{
GList *pads;
g_return_if_fail (GST_IS_SCHEDULER (sched));
g_return_if_fail (GST_IS_ELEMENT (element));
sched->clock_providers = g_list_remove (sched->clock_providers, element);
sched->clock_receivers = g_list_remove (sched->clock_receivers, element);
if (CLASS (sched)->remove_element)
CLASS (sched)->remove_element (sched, element);
for (pads = element->pads; pads; pads = pads->next) {
GstPad *pad = GST_PAD (pads->data);
if (GST_IS_REAL_PAD (pad)) {
gst_pad_unset_sched (GST_PAD (pads->data));
}
}
}
/**
* gst_scheduler_state_transition:
* @sched: the scheduler
@ -192,39 +237,66 @@ gst_scheduler_state_transition (GstScheduler *sched, GstElement *element, gint t
g_return_val_if_fail (GST_IS_SCHEDULER (sched), GST_STATE_FAILURE);
g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_FAILURE);
if (element == sched->parent && sched->parent_sched == NULL) {
switch (transition) {
case GST_STATE_READY_TO_PAUSED:
{
GstClock *clock = gst_scheduler_get_clock (sched);
if (clock)
gst_clock_reset (clock);
sched->current_clock = clock;
break;
}
case GST_STATE_PAUSED_TO_PLAYING:
{
gst_scheduler_set_clock (sched, sched->current_clock);
if (sched->current_clock)
gst_clock_activate (sched->current_clock, TRUE);
break;
}
case GST_STATE_PLAYING_TO_PAUSED:
if (sched->current_clock)
gst_clock_activate (sched->current_clock, FALSE);
break;
}
}
if (CLASS (sched)->state_transition)
return CLASS (sched)->state_transition (sched, element, transition);
return GST_STATE_SUCCESS;
}
/**
* gst_scheduler_remove_element:
* @sched: the schedulerr
* @element: the element to remov
*
* Remove an element from the schedulerr.
*/
void
gst_scheduler_remove_element (GstScheduler *sched, GstElement *element)
gst_scheduler_add_scheduler (GstScheduler *sched, GstScheduler *sched2)
{
GList *pads;
g_return_if_fail (GST_IS_SCHEDULER (sched));
g_return_if_fail (GST_IS_ELEMENT (element));
g_return_if_fail (GST_IS_SCHEDULER (sched2));
if (CLASS (sched)->remove_element)
CLASS (sched)->remove_element (sched, element);
for (pads = element->pads; pads; pads = pads->next) {
GstPad *pad = GST_PAD (pads->data);
if (GST_IS_REAL_PAD (pad)) {
gst_pad_unset_sched (GST_PAD (pads->data));
}
}
sched->schedulers = g_list_prepend (sched->schedulers, sched2);
sched2->parent_sched = sched;
if (CLASS (sched)->add_scheduler)
CLASS (sched)->add_scheduler (sched, sched2);
}
void
gst_scheduler_remove_scheduler (GstScheduler *sched, GstScheduler *sched2)
{
g_return_if_fail (GST_IS_SCHEDULER (sched));
g_return_if_fail (GST_IS_SCHEDULER (sched2));
sched->schedulers = g_list_remove (sched->schedulers, sched2);
sched2->parent_sched = NULL;
if (CLASS (sched)->remove_scheduler)
CLASS (sched)->remove_scheduler (sched, sched2);
}
/**
* gst_scheduler_lock_element:
* @sched: the scheduler
@ -315,6 +387,106 @@ gst_scheduler_interrupt (GstScheduler *sched, GstElement *element)
return FALSE;
}
GstClock*
gst_scheduler_get_clock (GstScheduler *sched)
{
GstClock *clock = NULL;
if (GST_FLAG_IS_SET (sched, GST_SCHEDULER_FLAG_FIXED_CLOCK)) {
clock = sched->clock;
}
else {
if (sched->schedulers) {
GList *schedulers = sched->schedulers;
while (schedulers) {
GstScheduler *scheduler = GST_SCHEDULER (schedulers->data);
clock = gst_scheduler_get_clock (scheduler);
if (clock)
break;
schedulers = g_list_next (schedulers);
}
}
if (!clock && sched->clock_providers) {
clock = gst_element_get_clock (GST_ELEMENT (sched->clock_providers->data));
}
if (!clock && sched->parent_sched == NULL) {
clock = gst_system_clock_obtain ();
}
}
return clock;
}
void
gst_scheduler_use_clock (GstScheduler *sched, GstClock *clock)
{
g_return_if_fail (sched != NULL);
g_return_if_fail (GST_IS_SCHEDULER (sched));
GST_FLAG_SET (sched, GST_SCHEDULER_FLAG_FIXED_CLOCK);
sched->clock = clock;
}
void
gst_scheduler_set_clock (GstScheduler *sched, GstClock *clock)
{
GList *receivers;
GList *schedulers;
g_return_if_fail (sched != NULL);
g_return_if_fail (GST_IS_SCHEDULER (sched));
receivers = sched->clock_receivers;
schedulers = sched->schedulers;
sched->current_clock = clock;
while (receivers) {
GstElement *element = GST_ELEMENT (receivers->data);
gst_element_set_clock (element, clock);
receivers = g_list_next (receivers);
}
while (schedulers) {
GstScheduler *scheduler = GST_SCHEDULER (schedulers->data);
gst_scheduler_set_clock (scheduler, clock);
schedulers = g_list_next (schedulers);
}
}
void
gst_scheduler_auto_clock (GstScheduler *sched)
{
g_return_if_fail (sched != NULL);
g_return_if_fail (GST_IS_SCHEDULER (sched));
GST_FLAG_UNSET (sched, GST_SCHEDULER_FLAG_FIXED_CLOCK);
sched->clock = NULL;
}
/**
* gst_scheduler_clock_wait:
* @sched: the scheduler
*
* Perform one iteration on the schedulerr.
*
* Returns: a boolean indicating something usefull has happened.
*/
GstClockReturn
gst_scheduler_clock_wait (GstScheduler *sched, GstElement *element, GstClock *clock, GstClockTime time)
{
g_return_val_if_fail (GST_IS_SCHEDULER (sched), GST_CLOCK_ERROR);
if (CLASS (sched)->clock_wait)
return CLASS (sched)->clock_wait (sched, element, clock, time);
return GST_CLOCK_TIMEOUT;
}
/**
* gst_scheduler_iterate:
* @sched: the scheduler

View file

@ -44,6 +44,13 @@ extern "C" {
#define GST_IS_SCHEDULER_CLASS(obj) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_SCHEDULER))
typedef enum {
/* this scheduler works with a fixed clock */
GST_SCHEDULER_FLAG_FIXED_CLOCK = GST_OBJECT_FLAG_LAST,
/* padding */
GST_SCHEDULER_FLAG_LAST = GST_OBJECT_FLAG_LAST + 4,
} GstSchedulerFlags;
#define GST_SCHEDULER_PARENT(sched) ((sched)->parent)
#define GST_SCHEDULER_STATE(sched) ((sched)->state)
@ -58,11 +65,19 @@ typedef enum {
} GstSchedulerState;
struct _GstScheduler {
GstObject object;
GstObject object;
GstElement *parent;
GstElement *parent;
GstScheduler *parent_sched;
GstSchedulerState state;
GstSchedulerState state;
GstClock *clock;
GstClock *current_clock;
GList *clock_providers;
GList *clock_receivers;
GList *schedulers;
};
struct _GstSchedulerClass {
@ -73,6 +88,8 @@ struct _GstSchedulerClass {
void (*reset) (GstScheduler *sched);
void (*add_element) (GstScheduler *sched, GstElement *element);
void (*remove_element) (GstScheduler *sched, GstElement *element);
void (*add_scheduler) (GstScheduler *sched, GstScheduler *sched2);
void (*remove_scheduler) (GstScheduler *sched, GstScheduler *sched2);
GstElementStateReturn (*state_transition) (GstScheduler *sched, GstElement *element, gint transition);
void (*lock_element) (GstScheduler *sched, GstElement *element);
void (*unlock_element) (GstScheduler *sched, GstElement *element);
@ -82,6 +99,8 @@ struct _GstSchedulerClass {
void (*pad_connect) (GstScheduler *sched, GstPad *srcpad, GstPad *sinkpad);
void (*pad_disconnect) (GstScheduler *sched, GstPad *srcpad, GstPad *sinkpad);
void (*pad_select) (GstScheduler *sched, GList *padlist);
GstClockReturn (*clock_wait) (GstScheduler *sched, GstElement *element,
GstClock *clock, GstClockTime time);
GstSchedulerState (*iterate) (GstScheduler *sched);
/* for debugging */
void (*show) (GstScheduler *sched);
@ -98,6 +117,8 @@ void gst_scheduler_setup (GstScheduler *sched);
void gst_scheduler_reset (GstScheduler *sched);
void gst_scheduler_add_element (GstScheduler *sched, GstElement *element);
void gst_scheduler_remove_element (GstScheduler *sched, GstElement *element);
void gst_scheduler_add_scheduler (GstScheduler *sched, GstScheduler *sched2);
void gst_scheduler_remove_scheduler (GstScheduler *sched, GstScheduler *sched2);
GstElementStateReturn gst_scheduler_state_transition (GstScheduler *sched, GstElement *element, gint transition);
void gst_scheduler_lock_element (GstScheduler *sched, GstElement *element);
void gst_scheduler_unlock_element (GstScheduler *sched, GstElement *element);
@ -107,8 +128,17 @@ void gst_scheduler_error (GstScheduler *sched, GstElement *element);
void gst_scheduler_pad_connect (GstScheduler *sched, GstPad *srcpad, GstPad *sinkpad);
void gst_scheduler_pad_disconnect (GstScheduler *sched, GstPad *srcpad, GstPad *sinkpad);
GstPad* gst_scheduler_pad_select (GstScheduler *sched, GList *padlist);
GstClock* gst_scheduler_get_clock (GstScheduler *sched);
GstClock* gst_scheduler_get_clock (GstScheduler *sched);
GstClockReturn gst_scheduler_clock_wait (GstScheduler *sched, GstElement *element,
GstClock *clock, GstClockTime time);
gboolean gst_scheduler_iterate (GstScheduler *sched);
void gst_scheduler_use_clock (GstScheduler *sched, GstClock *clock);
void gst_scheduler_set_clock (GstScheduler *sched, GstClock *clock);
GstClock* gst_scheduler_get_clock (GstScheduler *sched);
void gst_scheduler_auto_clock (GstScheduler *sched);
void gst_scheduler_show (GstScheduler *sched);
/*

View file

@ -34,11 +34,7 @@ static GstClock *_the_system_clock = NULL;
static void gst_system_clock_class_init (GstSystemClockClass *klass);
static void gst_system_clock_init (GstSystemClock *clock);
static void gst_system_clock_activate (GstClock *clock, gboolean active);
static void gst_system_clock_reset (GstClock *clock);
static void gst_system_clock_set_time (GstClock *clock, GstClockTime time);
static GstClockTime gst_system_clock_get_time (GstClock *clock);
static GstClockReturn gst_system_clock_wait (GstClock *clock, GstClockTime time);
static GstClockTime gst_system_clock_get_internal_time (GstClock *clock);
static guint64 gst_system_clock_get_resolution (GstClock *clock);
@ -82,11 +78,7 @@ gst_system_clock_class_init (GstSystemClockClass *klass)
parent_class = g_type_class_ref (GST_TYPE_CLOCK);
gstclock_class->activate = gst_system_clock_activate;
gstclock_class->reset = gst_system_clock_reset;
gstclock_class->set_time = gst_system_clock_set_time;
gstclock_class->get_time = gst_system_clock_get_time;
gstclock_class->wait = gst_system_clock_wait;
gstclock_class->get_internal_time = gst_system_clock_get_internal_time;
gstclock_class->get_resolution = gst_system_clock_get_resolution;
}
@ -105,89 +97,12 @@ gst_system_clock_obtain (void)
return _the_system_clock;
}
static void
gst_system_clock_activate (GstClock *clock, gboolean active)
{
GTimeVal timeval;
GstSystemClock *sys_clock = GST_SYSTEM_CLOCK (clock);
g_get_current_time (&timeval);
GST_LOCK (clock);
if (active) {
sys_clock->absolute_start = GST_TIMEVAL_TO_TIME (timeval) - sys_clock->current_time;;
}
else {
sys_clock->current_time = GST_TIMEVAL_TO_TIME (timeval) - sys_clock->absolute_start;
}
GST_UNLOCK (clock);
}
static void
gst_system_clock_set_time (GstClock *clock, GstClockTime time)
{
GTimeVal timeval;
GstSystemClock *sys_clock = GST_SYSTEM_CLOCK (clock);
g_get_current_time (&timeval);
GST_LOCK (clock);
sys_clock->absolute_start = GST_TIMEVAL_TO_TIME (timeval) - time;
sys_clock->current_time = time;
GST_UNLOCK (clock);
}
static void
gst_system_clock_reset (GstClock *clock)
{
gst_system_clock_set_time (clock, 0LL);
}
static GstClockTime
gst_system_clock_get_time (GstClock *clock)
gst_system_clock_get_internal_time (GstClock *clock)
{
GstSystemClock *sys_clock = GST_SYSTEM_CLOCK (clock);
GstClockTime res;
if (!clock->active) {
GST_LOCK (clock);
res = sys_clock->current_time;
}
else {
GTimeVal timeval;
g_get_current_time (&timeval);
GST_LOCK (clock);
res = GST_TIMEVAL_TO_TIME (timeval) - sys_clock->absolute_start;
}
GST_UNLOCK (clock);
return res;
}
static GstClockReturn
gst_system_clock_wait (GstClock *clock, GstClockTime time)
{
GstClockTime target;
GTimeVal timeval;
GCond *cond = g_cond_new ();
GstSystemClock *sys_clock = GST_SYSTEM_CLOCK (clock);
GstClockReturn ret;
GST_LOCK (clock);
target = time + sys_clock->absolute_start;
timeval.tv_usec = target % 1000000;
timeval.tv_sec = target / 1000000;
g_cond_timed_wait (cond, GST_GET_LOCK (clock), &timeval);
GST_UNLOCK (clock);
ret = GST_CLOCK_TIMEOUT;
g_cond_free (cond);
return ret;
g_get_current_time (&timeval);
return GST_TIMEVAL_TO_TIME (timeval);
}
static guint64

View file

@ -47,9 +47,6 @@ typedef struct _GstSystemClockClass GstSystemClockClass;
struct _GstSystemClock {
GstClock clock;
GstClockTime absolute_start;
GstClockTime current_time;
};
struct _GstSystemClockClass {

View file

@ -140,6 +140,7 @@ gst_thread_init (GstThread *thread)
/* we're a manager by default */
GST_FLAG_SET (thread, GST_BIN_FLAG_MANAGER);
GST_FLAG_SET (thread, GST_BIN_SELF_SCHEDULABLE);
schedname = gst_schedulerfactory_get_default_name ();

View file

@ -198,28 +198,6 @@ gst_util_get_pointer_arg (GObject * object, const gchar * argname)
return g_value_get_pointer (&value);
}
/**
* gst_util_get_widget_property:
* @object: the object to query
* @argname: the name of the argument
*
* Retrieves a property of an object as a widget.
*
* Returns: the property of the object
*/
/* COMMENTED OUT BECAUSE WE HAVE NO MORE gtk.h
GtkWidget*
gst_util_get_widget_property (GObject *object, const gchar *argname)
{
GtkArg arg;
arg.name = argname;
gtk_object_getv(G_OBJECT(object),1,&arg);
return GTK_WIDGET(G_VALUE_OBJECT(arg));
}
*/
/**
* gst_util_dump_mem:
* @mem: a pointer to the memory to dump
@ -448,7 +426,6 @@ gst_util_set_object_arg (GObject * object, const gchar * name, const gchar * val
#include "gstpad.h"
#include "gsttype.h"
#include "gstprops.h"
#include "gstpropsprivate.h"
static void
string_append_indent (GString * str, gint count)
@ -460,15 +437,16 @@ string_append_indent (GString * str, gint count)
}
static void
gst_print_props (GString * buf, gint indent, GList * props, gboolean showname)
gst_print_props (GString *buf, gint indent, GList *props, gboolean showname)
{
GList *elem;
guint width = 0;
GstPropsType type;
if (showname)
for (elem = props; elem; elem = g_list_next (elem)) {
GstPropsEntry *prop = elem->data;
const gchar *name = g_quark_to_string (prop->propid);
const gchar *name = gst_props_entry_get_name (prop);
if (width < strlen (name))
width = strlen (name);
@ -479,45 +457,76 @@ gst_print_props (GString * buf, gint indent, GList * props, gboolean showname)
string_append_indent (buf, indent);
if (showname) {
const gchar *name = g_quark_to_string (prop->propid);
const gchar *name = gst_props_entry_get_name (prop);
g_string_append (buf, name);
string_append_indent (buf, 2 + width - strlen (name));
}
switch (prop->propstype) {
case GST_PROPS_INT_ID:
g_string_append_printf (buf, "%d (int)\n", prop->data.int_data);
type = gst_props_entry_get_type (prop);
switch (type) {
case GST_PROPS_INT_TYPE:
{
gint val;
gst_props_entry_get_int (prop, &val);
g_string_append_printf (buf, "%d (int)\n", val);
break;
case GST_PROPS_INT_RANGE_ID:
g_string_append_printf (buf, "%d - %d (int)\n",
prop->data.int_range_data.min, prop->data.int_range_data.max);
}
case GST_PROPS_INT_RANGE_TYPE:
{
gint min, max;
gst_props_entry_get_int_range (prop, &min, &max);
g_string_append_printf (buf, "%d - %d (int)\n", min, max);
break;
case GST_PROPS_FLOAT_ID:
g_string_append_printf (buf, "%f (float)\n", prop->data.float_data);
}
case GST_PROPS_FLOAT_TYPE:
{
gfloat val;
gst_props_entry_get_float (prop, &val);
g_string_append_printf (buf, "%f (float)\n", val);
break;
case GST_PROPS_FLOAT_RANGE_ID:
g_string_append_printf (buf, "%f - %f (float)\n",
prop->data.float_range_data.min, prop->data.float_range_data.max);
}
case GST_PROPS_FLOAT_RANGE_TYPE:
{
gfloat min, max;
gst_props_entry_get_float_range (prop, &min, &max);
g_string_append_printf (buf, "%f - %f (float)\n", min, max);
break;
case GST_PROPS_BOOL_ID:
g_string_append_printf (buf, "%s\n", prop->data.bool_data ? "TRUE" : "FALSE");
}
case GST_PROPS_BOOL_TYPE:
{
gboolean val;
gst_props_entry_get_boolean (prop, &val);
g_string_append_printf (buf, "%s\n", val ? "TRUE" : "FALSE");
break;
case GST_PROPS_STRING_ID:
g_string_append_printf (buf, "\"%s\"\n", prop->data.string_data.string);
}
case GST_PROPS_STRING_TYPE:
{
const gchar *val;
gst_props_entry_get_string (prop, &val);
g_string_append_printf (buf, "\"%s\"\n", val);
break;
case GST_PROPS_FOURCC_ID:
}
case GST_PROPS_FOURCC_TYPE:
{
guint32 val;
gst_props_entry_get_fourcc_int (prop, &val);
g_string_append_printf (buf, "'%c%c%c%c' (fourcc)\n",
prop->data.fourcc_data & 0xff,
prop->data.fourcc_data >> 8 & 0xff,
prop->data.fourcc_data >> 16 & 0xff,
prop->data.fourcc_data >> 24 & 0xff);
(gchar)( val & 0xff),
(gchar)((val >> 8) & 0xff),
(gchar)((val >> 16) & 0xff),
(gchar)((val >> 24) & 0xff));
break;
case GST_PROPS_LIST_ID:
gst_print_props (buf, indent + 2, prop->data.list_data.entries, FALSE);
}
case GST_PROPS_LIST_TYPE:
{
const GList *list;
gst_props_entry_get_list (prop, &list);
gst_print_props (buf, indent + 2, (GList *)list, FALSE);
break;
}
default:
g_string_append_printf (buf, "unknown proptype %d\n", prop->propstype);
g_string_append_printf (buf, "unknown proptype %d\n", type);
break;
}
}

View file

@ -41,8 +41,7 @@ gfloat gst_util_get_float_arg (GObject *object, const gchar *argname);
gdouble gst_util_get_double_arg (GObject *object, const gchar *argname);
const gchar* gst_util_get_string_arg (GObject *object, const gchar *argname);
gpointer gst_util_get_pointer_arg (GObject *object, const gchar *argname);
/*GtkWidget* gst_util_get_widget_property (GObject *object, const gchar *argname);*/
void gst_util_set_value_from_string(GValue *value, const gchar *value_str);
void gst_util_set_value_from_string (GValue *value, const gchar *value_str);
void gst_util_set_object_arg (GObject *object, const gchar *name, const gchar *value);
void gst_util_dump_mem (guchar *mem, guint size);

View file

@ -1,6 +1,6 @@
plugindir = $(libdir)/gst
plugin_LTLIBRARIES = libgstbasicscheduler.la libgststandardscheduler.la
plugin_LTLIBRARIES = libgstbasicscheduler.la libgststandardscheduler.la libgstfastscheduler.la
libgstbasicscheduler_la_SOURCES = gstbasicscheduler.c
libgstbasicscheduler_la_CFLAGS = $(GST_CFLAGS)
@ -12,6 +12,11 @@ libgststandardscheduler_la_CFLAGS = $(GST_CFLAGS) -I$(top_srcdir)/libs/ext/cothr
libgststandardscheduler_la_LIBADD = $(top_builddir)/libs/ext/cothreads/cothreads/libcothreads-gthreads.la
libgststandardscheduler_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
libgstfastscheduler_la_SOURCES = gstfastscheduler.c
libgstfastscheduler_la_CFLAGS = $(GST_CFLAGS)
libgstfastscheduler_la_LIBADD = $(GST_LIBS) ../libcothreads.la
libgstfastscheduler_la_LDFLAGS = @GST_LT_LDFLAGS@
## this is a REALLY evil hack
## but we need to keep it as long as we have libs/gst and libs/ext
$(top_builddir)/libs/ext/cothreads/cothreads/libcothreads-gthreads.la:

View file

@ -72,7 +72,7 @@ typedef enum {
typedef enum {
/* something important has changed inside the scheduler */
GST_BASIC_SCHEDULER_CHANGE = GST_OBJECT_FLAG_LAST,
GST_BASIC_SCHEDULER_CHANGE = GST_SCHEDULER_FLAG_LAST,
} GstBasicSchedulerFlags;
struct _GstBasicScheduler {
@ -112,6 +112,8 @@ static void gst_basic_scheduler_error (GstScheduler *sched, GstElement *elem
static void gst_basic_scheduler_pad_connect (GstScheduler *sched, GstPad *srcpad, GstPad *sinkpad);
static void gst_basic_scheduler_pad_disconnect (GstScheduler *sched, GstPad *srcpad, GstPad *sinkpad);
static GstPad* gst_basic_scheduler_pad_select (GstScheduler *sched, GList *padlist);
static GstClockReturn gst_basic_scheduler_clock_wait (GstScheduler *sched, GstElement *element,
GstClock *clock, GstClockTime time);
static GstSchedulerState
gst_basic_scheduler_iterate (GstScheduler *sched);
@ -169,6 +171,7 @@ gst_basic_scheduler_class_init (GstBasicSchedulerClass * klass)
gstscheduler_class->pad_connect = GST_DEBUG_FUNCPTR (gst_basic_scheduler_pad_connect);
gstscheduler_class->pad_disconnect = GST_DEBUG_FUNCPTR (gst_basic_scheduler_pad_disconnect);
gstscheduler_class->pad_select = GST_DEBUG_FUNCPTR (gst_basic_scheduler_pad_select);
gstscheduler_class->clock_wait = GST_DEBUG_FUNCPTR (gst_basic_scheduler_clock_wait);
gstscheduler_class->iterate = GST_DEBUG_FUNCPTR (gst_basic_scheduler_iterate);
gstscheduler_class->show = GST_DEBUG_FUNCPTR (gst_basic_scheduler_show);
@ -424,6 +427,9 @@ gst_basic_scheduler_gethandler_proxy (GstPad * pad)
if (GST_RPAD_PEER (peer) != (GstRealPad *) pad) {
GST_DEBUG (GST_CAT_DATAFLOW, "new pad in mid-switch!");
pad = (GstPad *) GST_RPAD_PEER (peer);
if (!pad) {
gst_element_error (GST_ELEMENT (GST_PAD_PARENT (peer)), "pad unconnected");
}
}
}
GST_DEBUG (GST_CAT_DATAFLOW, "done switching");
@ -530,7 +536,7 @@ gst_basic_scheduler_cothreaded_chain (GstBin * bin, GstSchedulerChain * chain)
if (!GST_IS_REAL_PAD (pad))
continue;
peerpad = GST_PAD (GST_RPAD_PEER (pad));
peerpad = GST_PAD_PEER (pad);
/* if the element is DECOUPLED or outside the manager, we have to chain */
if ((wrapper_function == NULL) ||
@ -677,6 +683,7 @@ gst_basic_scheduler_chain_enable_element (GstSchedulerChain * chain, GstElement
/* notify the scheduler that something changed */
GST_FLAG_SET(chain->sched, GST_BASIC_SCHEDULER_CHANGE);
//GST_FLAG_UNSET(element, GST_ELEMENT_COTHREAD_STOPPING);
/* reschedule the chain */
return gst_basic_scheduler_cothreaded_chain (GST_BIN (GST_SCHEDULER (chain->sched)->parent), chain);
@ -696,6 +703,7 @@ gst_basic_scheduler_chain_disable_element (GstSchedulerChain * chain, GstElement
/* notify the scheduler that something changed */
GST_FLAG_SET(chain->sched, GST_BASIC_SCHEDULER_CHANGE);
GST_FLAG_SET(element, GST_ELEMENT_COTHREAD_STOPPING);
/* reschedule the chain */
/* FIXME this should be done only if manager state != NULL */
@ -969,19 +977,6 @@ gst_basic_scheduler_remove_element (GstScheduler * sched, GstElement * element)
/* find what chain the element is in */
chain = gst_basic_scheduler_find_chain (bsched, element);
if (GST_ELEMENT_IS_COTHREAD_STOPPING (element)) {
GstElement *entry = GST_ELEMENT (cothread_get_private (cothread_current ()));
if (entry == element) {
g_warning ("removing currently running element! %s", GST_ELEMENT_NAME (entry));
}
else if (entry) {
GST_INFO (GST_CAT_SCHEDULING, "moving stopping to element \"%s\"",
GST_ELEMENT_NAME (entry));
GST_FLAG_SET (entry, GST_ELEMENT_COTHREAD_STOPPING);
}
}
/* remove it from its chain */
gst_basic_scheduler_chain_remove_element (chain, element);
@ -1196,6 +1191,13 @@ gst_basic_scheduler_pad_select (GstScheduler * sched, GList * padlist)
return pad;
}
static GstClockReturn
gst_basic_scheduler_clock_wait (GstScheduler *sched, GstElement *element,
GstClock *clock, GstClockTime time)
{
return gst_clock_wait (clock, time);
}
static GstSchedulerState
gst_basic_scheduler_iterate (GstScheduler * sched)
{

File diff suppressed because it is too large Load diff

View file

@ -46,6 +46,7 @@ enum {
ARG_NUM_SINKS,
ARG_SILENT,
ARG_DUMP,
ARG_SYNC,
ARG_LAST_MESSAGE,
};
@ -60,6 +61,7 @@ GST_PADTEMPLATE_FACTORY (fakesink_sink_factory,
static void gst_fakesink_class_init (GstFakeSinkClass *klass);
static void gst_fakesink_init (GstFakeSink *fakesink);
static void gst_fakesink_set_clock (GstElement *element, GstClock *clock);
static GstPad* gst_fakesink_request_new_pad (GstElement *element, GstPadTemplate *templ, const
gchar *unused);
@ -106,12 +108,14 @@ gst_fakesink_class_init (GstFakeSinkClass *klass)
parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_NUM_SINKS,
g_param_spec_int ("num_sinks", "num_sinks", "num_sinks",
g_param_spec_int ("num_sinks", "Number of sinks", "The number of sinkpads",
1, G_MAXINT, 1, G_PARAM_READABLE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_LAST_MESSAGE,
g_param_spec_string ("last_message", "last_message", "last_message",
NULL, G_PARAM_READABLE));
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_SYNC,
g_param_spec_boolean("sync","Sync","Sync on the clock",
FALSE, G_PARAM_READWRITE)); /* CHECKME */
gst_element_class_install_std_props (
GST_ELEMENT_CLASS (klass),
@ -141,9 +145,22 @@ gst_fakesink_init (GstFakeSink *fakesink)
fakesink->silent = FALSE;
fakesink->dump = FALSE;
fakesink->sync = FALSE;
fakesink->last_message = NULL;
GST_ELEMENT (fakesink)->setclockfunc = gst_fakesink_set_clock;
}
static void
gst_fakesink_set_clock (GstElement *element, GstClock *clock)
{
GstFakeSink *sink;
sink = GST_FAKESINK (element);
sink->clock = clock;
}
static GstPad*
gst_fakesink_request_new_pad (GstElement *element, GstPadTemplate *templ, const gchar *unused)
{
@ -183,6 +200,9 @@ gst_fakesink_set_property (GObject *object, guint prop_id, const GValue *value,
case ARG_DUMP:
sink->dump = g_value_get_boolean (value);
break;
case ARG_SYNC:
sink->sync = g_value_get_boolean (value);
break;
default:
break;
}
@ -208,6 +228,9 @@ gst_fakesink_get_property (GObject *object, guint prop_id, GValue *value, GParam
case ARG_DUMP:
g_value_set_boolean (value, sink->dump);
break;
case ARG_SYNC:
g_value_set_boolean (value, sink->sync);
break;
case ARG_LAST_MESSAGE:
g_value_set_string (value, sink->last_message);
break;
@ -228,9 +251,12 @@ gst_fakesink_chain (GstPad *pad, GstBuffer *buf)
fakesink = GST_FAKESINK (gst_pad_get_parent (pad));
if (fakesink->sync) {
gst_element_clock_wait (GST_ELEMENT (fakesink), fakesink->clock, GST_BUFFER_TIMESTAMP (buf));
}
if (!fakesink->silent) {
if (fakesink->last_message)
g_free (fakesink->last_message);
g_free (fakesink->last_message);
fakesink->last_message = g_strdup_printf ("chain ******* (%s:%s)< (%d bytes, %lld) %p",
GST_DEBUG_PAD_NAME (pad), GST_BUFFER_SIZE (buf), GST_BUFFER_TIMESTAMP (buf), buf);

View file

@ -52,11 +52,14 @@ typedef struct _GstFakeSink GstFakeSink;
typedef struct _GstFakeSinkClass GstFakeSinkClass;
struct _GstFakeSink {
GstElement element;
GstElement element;
gboolean silent;
gboolean dump;
gchar *last_message;
gboolean silent;
gboolean dump;
gboolean sync;
GstClock *clock;
gchar *last_message;
};
struct _GstFakeSinkClass {

View file

@ -321,6 +321,7 @@ gst_fakesrc_event_handler (GstPad *pad, GstEvent *event)
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_SEEK:
src->buffer_count = GST_EVENT_SEEK_OFFSET (event);
if (!GST_EVENT_SEEK_FLUSH (event)) {
gst_event_free (event);
break;

View file

@ -105,7 +105,8 @@ struct _GstFakeSrc {
gboolean silent;
gboolean dump;
gboolean need_flush;
gchar *last_message;
gchar *last_message;
};
struct _GstFakeSrcClass {

View file

@ -78,7 +78,7 @@ GstElementDetails gst_filesrc_details = {
"(C) 1999",
};
/*#define fs_print(format,args...) g_print(format, ## args)*/
/*#define fs_print(format,args...) g_print(format, ## args) */
#define fs_print(format,args...)
/* FileSrc signals and args */
@ -549,7 +549,7 @@ gst_filesrc_get (GstPad *pad)
/* we're done, return the buffer */
src->curoffset += GST_BUFFER_SIZE(buf);
g_object_notify (G_OBJECT (src), "offset");
//g_object_notify (G_OBJECT (src), "offset");
return buf;
}
@ -590,7 +590,7 @@ gst_filesrc_open_file (GstFileSrc *src)
/* now notify of the changes */
g_object_freeze_notify (G_OBJECT (src));
g_object_notify (G_OBJECT (src), "filesize");
g_object_notify (G_OBJECT (src), "offset");
//g_object_notify (G_OBJECT (src), "offset");
g_object_thaw_notify (G_OBJECT (src));
GST_FLAG_SET (src, GST_FILESRC_OPEN);
@ -614,7 +614,7 @@ gst_filesrc_close_file (GstFileSrc *src)
/* and notify that things changed */
g_object_freeze_notify (G_OBJECT (src));
g_object_notify (G_OBJECT (src), "filesize");
g_object_notify (G_OBJECT (src), "offset");
//g_object_notify (G_OBJECT (src), "offset");
g_object_thaw_notify (G_OBJECT (src));
if (src->mapbuf)

View file

@ -83,7 +83,6 @@ static GstBuffer * gst_queue_get (GstPad *pad);
static GstBufferPool* gst_queue_get_bufferpool (GstPad *pad);
static void gst_queue_locked_flush (GstQueue *queue);
static void gst_queue_flush (GstQueue *queue);
static GstElementStateReturn gst_queue_change_state (GstElement *element);
@ -274,15 +273,6 @@ gst_queue_locked_flush (GstQueue *queue)
queue->timeval = NULL;
}
static void
gst_queue_flush (GstQueue *queue)
{
g_mutex_lock (queue->qlock);
gst_queue_locked_flush (queue);
g_mutex_unlock (queue->qlock);
}
static void
gst_queue_chain (GstPad *pad, GstBuffer *buf)
{
@ -378,7 +368,7 @@ restart:
return;
}
else {
gst_element_info (GST_ELEMENT (queue), "waiting for the app to restart source pad elements");
g_print ("%s: waiting for the app to restart source pad elements\n", GST_ELEMENT_NAME (queue));
}
}
@ -459,7 +449,7 @@ restart:
goto restart;
}
else {
gst_element_info (GST_ELEMENT (queue), "waiting for the app to restart sink pad elements");
g_print ("%s: waiting for the app to restart source pad elements\n", GST_ELEMENT_NAME (queue));
}
}

View file

@ -181,7 +181,7 @@ gst_tee_request_new_pad (GstElement *element, GstPadTemplate *templ, const gchar
GList *pads;
g_return_val_if_fail (GST_IS_TEE (element), NULL);
if (templ->direction != GST_PAD_SRC) {
g_warning ("gsttee: request new pad that is not a SRC pad\n");
return NULL;