mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-26 11:41:09 +00:00
- 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:
parent
2ed5aa240c
commit
f0326eea55
39 changed files with 2274 additions and 820 deletions
|
@ -145,7 +145,6 @@ 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)"\" \
|
||||
|
|
|
@ -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,7 +145,20 @@ 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*
|
||||
|
@ -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,8 +251,11 @@ 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);
|
||||
|
||||
fakesink->last_message = g_strdup_printf ("chain ******* (%s:%s)< (%d bytes, %lld) %p",
|
||||
|
|
|
@ -56,6 +56,9 @@ struct _GstFakeSink {
|
|||
|
||||
gboolean silent;
|
||||
gboolean dump;
|
||||
gboolean sync;
|
||||
GstClock *clock;
|
||||
|
||||
gchar *last_message;
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -105,6 +105,7 @@ struct _GstFakeSrc {
|
|||
gboolean silent;
|
||||
gboolean dump;
|
||||
gboolean need_flush;
|
||||
|
||||
gchar *last_message;
|
||||
};
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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>
|
||||
|
|
138
gst/gstbin.c
138
gst/gstbin.c
|
@ -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);
|
||||
|
@ -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),
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
286
gst/gstclock.c
286
gst/gstclock.c
|
@ -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,13 +110,13 @@ 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
|
||||
|
@ -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)->activate)
|
||||
CLASS (clock)->activate (clock, active);
|
||||
if (CLASS (clock)->get_internal_time) {
|
||||
time = CLASS (clock)->get_internal_time (clock);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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,19 +79,7 @@ struct _GstClockClass {
|
|||
GstObjectClass parent_class;
|
||||
|
||||
/* vtable */
|
||||
void (*activate) (GstClock *clock, gboolean active);
|
||||
void (*reset) (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);
|
||||
GstClockTime (*get_internal_time) (GstClock *clock);
|
||||
|
||||
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);
|
||||
|
|
|
@ -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);
|
||||
|
@ -1727,7 +1709,7 @@ 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,
|
||||
gst_element_set_loop_function (GstElement *element,
|
||||
GstElementLoopFunction loop)
|
||||
{
|
||||
g_return_if_fail (GST_IS_ELEMENT (element));
|
||||
|
|
|
@ -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,
|
||||
|
|
10
gst/gstpad.c
10
gst/gstpad.c
|
@ -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;
|
||||
|
|
|
@ -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_REFUSED = -1,
|
||||
GST_PAD_CONNECT_DELAYED = 0,
|
||||
GST_PAD_CONNECT_OK = 1,
|
||||
GST_PAD_CONNECT_DONE = 2,
|
||||
GST_PAD_CONNECT_DELAYED = 3,
|
||||
} GstPadConnectReturn;
|
||||
|
||||
/* this defines the functions used to chain buffers
|
||||
|
|
571
gst/gstprops.c
571
gst/gstprops.c
|
@ -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) {
|
||||
|
|
|
@ -26,47 +26,53 @@
|
|||
|
||||
#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 */
|
||||
|
@ -94,18 +100,36 @@ GstProps* gst_props_intersect (GstProps *props1, GstProps *props2);
|
|||
GList* gst_props_normalize (GstProps *props);
|
||||
|
||||
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_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);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#endif /* __GST_PROPS_H__ */
|
||||
|
|
|
@ -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__ */
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
sched->schedulers = g_list_prepend (sched->schedulers, sched2);
|
||||
sched2->parent_sched = sched;
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
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
|
||||
|
|
|
@ -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)
|
||||
|
@ -61,8 +68,16 @@ struct _GstScheduler {
|
|||
GstObject object;
|
||||
|
||||
GstElement *parent;
|
||||
GstScheduler *parent_sched;
|
||||
|
||||
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);
|
||||
|
||||
/*
|
||||
|
|
|
@ -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;
|
||||
return GST_TIMEVAL_TO_TIME (timeval);
|
||||
}
|
||||
|
||||
static guint64
|
||||
|
|
|
@ -47,9 +47,6 @@ typedef struct _GstSystemClockClass GstSystemClockClass;
|
|||
|
||||
struct _GstSystemClock {
|
||||
GstClock clock;
|
||||
|
||||
GstClockTime absolute_start;
|
||||
GstClockTime current_time;
|
||||
};
|
||||
|
||||
struct _GstSystemClockClass {
|
||||
|
|
|
@ -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 ();
|
||||
|
||||
|
|
107
gst/gstutils.c
107
gst/gstutils.c
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
1095
gst/schedulers/gstfastscheduler.c
Normal file
1095
gst/schedulers/gstfastscheduler.c
Normal file
File diff suppressed because it is too large
Load diff
|
@ -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,7 +145,20 @@ 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*
|
||||
|
@ -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,8 +251,11 @@ 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);
|
||||
|
||||
fakesink->last_message = g_strdup_printf ("chain ******* (%s:%s)< (%d bytes, %lld) %p",
|
||||
|
|
|
@ -56,6 +56,9 @@ struct _GstFakeSink {
|
|||
|
||||
gboolean silent;
|
||||
gboolean dump;
|
||||
gboolean sync;
|
||||
GstClock *clock;
|
||||
|
||||
gchar *last_message;
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -105,6 +105,7 @@ struct _GstFakeSrc {
|
|||
gboolean silent;
|
||||
gboolean dump;
|
||||
gboolean need_flush;
|
||||
|
||||
gchar *last_message;
|
||||
};
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue