mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-22 07:08:23 +00:00
More MT fixes. Header cleanups, design doc update.
Original commit message from CVS: * docs/design/part-MT-refcounting.txt: * gst/gstbin.c: (gst_bin_set_index), (gst_bin_set_clock), (gst_bin_add_func), (gst_bin_add), (gst_bin_remove_func), (gst_bin_remove), (gst_bin_iterate_elements), (bin_element_is_sink), (gst_bin_get_state), (gst_bin_change_state), (gst_bin_get_by_name), (gst_bin_get_by_name_recurse_up), (gst_bin_get_by_interface), (gst_bin_get_all_by_interface): * gst/gstbin.h: * gst/gstbuffer.h: * gst/gstbus.h: * gst/gstcaps.h: * gst/gstclock.h: * gst/gstdata.h: * gst/gstelement.h: * gst/gstevent.h: * gst/gstmessage.h: * gst/gststructure.h: More MT fixes. Header cleanups, design doc update.
This commit is contained in:
parent
aed37ff5c3
commit
5b1065d625
13 changed files with 251 additions and 115 deletions
21
ChangeLog
21
ChangeLog
|
@ -1,3 +1,24 @@
|
||||||
|
2004-12-10 Wim Taymans <wim@fluendo.com>
|
||||||
|
|
||||||
|
* docs/design/part-MT-refcounting.txt:
|
||||||
|
* gst/gstbin.c: (gst_bin_set_index), (gst_bin_set_clock),
|
||||||
|
(gst_bin_add_func), (gst_bin_add), (gst_bin_remove_func),
|
||||||
|
(gst_bin_remove), (gst_bin_iterate_elements),
|
||||||
|
(bin_element_is_sink), (gst_bin_get_state), (gst_bin_change_state),
|
||||||
|
(gst_bin_get_by_name), (gst_bin_get_by_name_recurse_up),
|
||||||
|
(gst_bin_get_by_interface), (gst_bin_get_all_by_interface):
|
||||||
|
* gst/gstbin.h:
|
||||||
|
* gst/gstbuffer.h:
|
||||||
|
* gst/gstbus.h:
|
||||||
|
* gst/gstcaps.h:
|
||||||
|
* gst/gstclock.h:
|
||||||
|
* gst/gstdata.h:
|
||||||
|
* gst/gstelement.h:
|
||||||
|
* gst/gstevent.h:
|
||||||
|
* gst/gstmessage.h:
|
||||||
|
* gst/gststructure.h:
|
||||||
|
More MT fixes. Header cleanups, design doc update.
|
||||||
|
|
||||||
2004-12-09 Wim Taymans <wim@fluendo.com>
|
2004-12-09 Wim Taymans <wim@fluendo.com>
|
||||||
|
|
||||||
* gst/gstpad.c: (gst_pad_custom_new), (gst_pad_get_direction),
|
* gst/gstpad.c: (gst_pad_custom_new), (gst_pad_get_direction),
|
||||||
|
|
|
@ -225,15 +225,18 @@ Objects
|
||||||
* Accessing lists
|
* Accessing lists
|
||||||
|
|
||||||
If the object property is a list concurrent list iteration is needed to get the
|
If the object property is a list concurrent list iteration is needed to get the
|
||||||
contents of the list. GStreamer uses the cookie design pattern mechanism to
|
contents of the list. GStreamer uses the cookie mechanism to mark the last update
|
||||||
mark the last update of a list. The list and the cookie are protected by the
|
of a list. The list and the cookie are protected by the same lock. Each update to
|
||||||
same lock. Each update to a list requires the following actions:
|
a list requires the following actions:
|
||||||
|
|
||||||
- acquire lock
|
- acquire lock
|
||||||
- update list
|
- update list
|
||||||
- update cookie
|
- update cookie
|
||||||
- release lock
|
- release lock
|
||||||
|
|
||||||
|
Updating the cookie is usually done by incrementing its value by one. Since cookies
|
||||||
|
use guint32 its wraparound is for all practical reasons is not a problem.
|
||||||
|
|
||||||
Iterating a list can safely be done by surrounding the list iteration with a
|
Iterating a list can safely be done by surrounding the list iteration with a
|
||||||
lock/unlock of the lock.
|
lock/unlock of the lock.
|
||||||
|
|
||||||
|
@ -266,9 +269,10 @@ Objects
|
||||||
|
|
||||||
GST_LOCK (lock);
|
GST_LOCK (lock);
|
||||||
if (cookie != object->list_cookie) {
|
if (cookie != object->list_cookie) {
|
||||||
/* concurrent modification of the list here */
|
/* handle rollback caused by concurrent modification
|
||||||
|
* of the list here */
|
||||||
|
|
||||||
...undo changes to items...
|
...rollback changes to items...
|
||||||
|
|
||||||
/* grab new cookie and list */
|
/* grab new cookie and list */
|
||||||
cookie = object->list_cookie;
|
cookie = object->list_cookie;
|
||||||
|
|
262
gst/gstbin.c
262
gst/gstbin.c
|
@ -62,8 +62,8 @@ static void gst_bin_set_index (GstElement * element, GstIndex * index);
|
||||||
static void gst_bin_set_clock (GstElement * element, GstClock * clock);
|
static void gst_bin_set_clock (GstElement * element, GstClock * clock);
|
||||||
static GstClock *gst_bin_get_clock (GstElement * element);
|
static GstClock *gst_bin_get_clock (GstElement * element);
|
||||||
|
|
||||||
static void gst_bin_add_func (GstBin * bin, GstElement * element);
|
static gboolean gst_bin_add_func (GstBin * bin, GstElement * element);
|
||||||
static void gst_bin_remove_func (GstBin * bin, GstElement * element);
|
static gboolean gst_bin_remove_func (GstBin * bin, GstElement * element);
|
||||||
|
|
||||||
#ifndef GST_DISABLE_LOADSAVE
|
#ifndef GST_DISABLE_LOADSAVE
|
||||||
static xmlNodePtr gst_bin_save_thyself (GstObject * object, xmlNodePtr parent);
|
static xmlNodePtr gst_bin_save_thyself (GstObject * object, xmlNodePtr parent);
|
||||||
|
@ -252,46 +252,71 @@ gst_bin_get_clock (GstElement * element)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static gboolean
|
||||||
gst_bin_add_func (GstBin * bin, GstElement * element)
|
gst_bin_add_func (GstBin * bin, GstElement * element)
|
||||||
{
|
{
|
||||||
GstPipeline *manager;
|
GstPipeline *manager;
|
||||||
|
gchar *elem_name;
|
||||||
|
|
||||||
|
GST_LOCK (element);
|
||||||
/* the element must not already have a parent */
|
/* the element must not already have a parent */
|
||||||
g_return_if_fail (GST_ELEMENT_PARENT (element) == NULL);
|
if (G_UNLIKELY (GST_ELEMENT_PARENT (element) != NULL))
|
||||||
|
goto had_parent;
|
||||||
|
|
||||||
|
elem_name = g_strdup (GST_ELEMENT_NAME (element));
|
||||||
|
GST_UNLOCK (element);
|
||||||
|
|
||||||
GST_LOCK (bin);
|
GST_LOCK (bin);
|
||||||
|
/* we obviously can't add ourself to ourself */
|
||||||
|
if (G_UNLIKELY (GST_ELEMENT_CAST (element) == GST_ELEMENT_CAST (bin)))
|
||||||
|
goto adding_itself;
|
||||||
|
|
||||||
/* then check to see if the element's name is already taken in the bin,
|
/* then check to see if the element's name is already taken in the bin,
|
||||||
* we can sefely take the lock here. */
|
* we can safely take the lock here. We can leave the element locked
|
||||||
if (gst_object_check_uniqueness (bin->children,
|
* as it will not be in the bin. This check is probably bogus because
|
||||||
GST_ELEMENT_NAME (element)) == FALSE) {
|
* you can safely change the element name after adding it to the bin. */
|
||||||
g_warning ("Name %s is not unique in bin %s, not adding\n",
|
if (G_UNLIKELY (gst_object_check_uniqueness (bin->children,
|
||||||
GST_ELEMENT_NAME (element), GST_ELEMENT_NAME (bin));
|
elem_name) == FALSE))
|
||||||
GST_UNLOCK (bin);
|
goto duplicate_name;
|
||||||
return;
|
|
||||||
}
|
|
||||||
manager = GST_ELEMENT (bin)->manager;
|
manager = GST_ELEMENT (bin)->manager;
|
||||||
gst_element_set_manager (element, manager);
|
gst_element_set_manager (element, manager);
|
||||||
|
|
||||||
if (GST_STATE (element) > GST_STATE (bin)) {
|
|
||||||
GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, bin,
|
|
||||||
"setting state to receive element \"%s\"", GST_OBJECT_NAME (element));
|
|
||||||
gst_element_set_state ((GstElement *) bin, GST_STATE (element));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* set the element's parent and add the element to the bin's list of children */
|
/* set the element's parent and add the element to the bin's list of children */
|
||||||
gst_object_set_parent (GST_OBJECT (element), GST_OBJECT (bin));
|
gst_object_set_parent (GST_OBJECT (element), GST_OBJECT (bin));
|
||||||
|
|
||||||
bin->children = g_list_prepend (bin->children, element);
|
bin->children = g_list_prepend (bin->children, element);
|
||||||
bin->numchildren++;
|
bin->numchildren++;
|
||||||
bin->children_cookie++;
|
bin->children_cookie++;
|
||||||
|
|
||||||
GST_CAT_DEBUG_OBJECT (GST_CAT_PARENTAGE, bin, "added element \"%s\"",
|
|
||||||
GST_OBJECT_NAME (element));
|
|
||||||
|
|
||||||
GST_UNLOCK (bin);
|
GST_UNLOCK (bin);
|
||||||
|
|
||||||
|
GST_CAT_DEBUG_OBJECT (GST_CAT_PARENTAGE, bin, "added element \"%s\"",
|
||||||
|
elem_name);
|
||||||
|
g_free (elem_name);
|
||||||
|
|
||||||
g_signal_emit (G_OBJECT (bin), gst_bin_signals[ELEMENT_ADDED], 0, element);
|
g_signal_emit (G_OBJECT (bin), gst_bin_signals[ELEMENT_ADDED], 0, element);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
/* ERROR handling here */
|
||||||
|
had_parent:
|
||||||
|
g_warning ("Element %s already has parent %p", GST_ELEMENT_NAME (element),
|
||||||
|
bin);
|
||||||
|
GST_UNLOCK (element);
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
adding_itself:
|
||||||
|
g_warning ("Cannot add bin %s to itself", GST_ELEMENT_NAME (bin));
|
||||||
|
GST_UNLOCK (bin);
|
||||||
|
g_free (elem_name);
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
duplicate_name:
|
||||||
|
g_warning ("Name %s is not unique in bin %s, not adding",
|
||||||
|
elem_name, GST_ELEMENT_NAME (bin));
|
||||||
|
GST_UNLOCK (bin);
|
||||||
|
g_free (elem_name);
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -301,64 +326,88 @@ gst_bin_add_func (GstBin * bin, GstElement * element)
|
||||||
*
|
*
|
||||||
* Adds the given element to the bin. Sets the element's parent, and thus
|
* Adds the given element to the bin. Sets the element's parent, and thus
|
||||||
* takes ownership of the element. An element can only be added to one bin.
|
* takes ownership of the element. An element can only be added to one bin.
|
||||||
|
*
|
||||||
|
* Returns: TRUE if the element could be added, FALSE on wrong parameters or
|
||||||
|
* the bin does not want to accept the element.
|
||||||
|
*
|
||||||
|
* MT safe.
|
||||||
*/
|
*/
|
||||||
void
|
gboolean
|
||||||
gst_bin_add (GstBin * bin, GstElement * element)
|
gst_bin_add (GstBin * bin, GstElement * element)
|
||||||
{
|
{
|
||||||
GstBinClass *bclass;
|
GstBinClass *bclass;
|
||||||
|
gboolean result;
|
||||||
|
|
||||||
g_return_if_fail (GST_IS_BIN (bin));
|
g_return_val_if_fail (GST_IS_BIN (bin), FALSE);
|
||||||
g_return_if_fail (GST_IS_ELEMENT (element));
|
g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
|
||||||
|
|
||||||
GST_CAT_INFO_OBJECT (GST_CAT_PARENTAGE, bin, "adding element \"%s\"",
|
|
||||||
GST_OBJECT_NAME (element));
|
|
||||||
|
|
||||||
bclass = GST_BIN_GET_CLASS (bin);
|
bclass = GST_BIN_GET_CLASS (bin);
|
||||||
|
|
||||||
if (bclass->add_element) {
|
if (G_UNLIKELY (bclass->add_element == NULL))
|
||||||
bclass->add_element (bin, element);
|
goto no_function;
|
||||||
} else {
|
|
||||||
g_warning ("cannot add element %s to bin %s",
|
GST_CAT_DEBUG (GST_CAT_PARENTAGE, "adding element %s to bin %s",
|
||||||
GST_ELEMENT_NAME (element), GST_ELEMENT_NAME (bin));
|
GST_ELEMENT_NAME (element), GST_ELEMENT_NAME (bin));
|
||||||
}
|
|
||||||
|
result = bclass->add_element (bin, element);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
no_function:
|
||||||
|
g_warning ("adding elements to bin %s is not supported",
|
||||||
|
GST_ELEMENT_NAME (bin));
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static gboolean
|
||||||
gst_bin_remove_func (GstBin * bin, GstElement * element)
|
gst_bin_remove_func (GstBin * bin, GstElement * element)
|
||||||
{
|
{
|
||||||
|
gchar *elem_name;
|
||||||
|
|
||||||
/* the element must have its parent set to the current bin */
|
/* the element must have its parent set to the current bin */
|
||||||
g_return_if_fail (GST_ELEMENT_PARENT (element) == (GstObject *) bin);
|
GST_LOCK (element);
|
||||||
|
/* the element must not already have a parent */
|
||||||
|
if (G_UNLIKELY (GST_ELEMENT_PARENT (element) != GST_ELEMENT_CAST (bin)))
|
||||||
|
goto wrong_parent;
|
||||||
|
|
||||||
|
elem_name = g_strdup (GST_ELEMENT_NAME (element));
|
||||||
|
GST_UNLOCK (element);
|
||||||
|
|
||||||
GST_LOCK (bin);
|
GST_LOCK (bin);
|
||||||
|
/* the element must be in the bin's list of children, is this
|
||||||
/* the element must be in the bin's list of children */
|
* check redundant with PARENT checking? */
|
||||||
if (g_list_find (bin->children, element) == NULL) {
|
if (G_UNLIKELY (g_list_find (bin->children, element) == NULL))
|
||||||
g_warning ("no element \"%s\" in bin \"%s\"\n", GST_ELEMENT_NAME (element),
|
goto not_in_bin;
|
||||||
GST_ELEMENT_NAME (bin));
|
|
||||||
GST_UNLOCK (bin);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* now remove the element from the list of elements */
|
/* now remove the element from the list of elements */
|
||||||
bin->children = g_list_remove (bin->children, element);
|
bin->children = g_list_remove (bin->children, element);
|
||||||
bin->numchildren--;
|
bin->numchildren--;
|
||||||
bin->children_cookie++;
|
bin->children_cookie++;
|
||||||
|
GST_UNLOCK (bin);
|
||||||
|
|
||||||
GST_CAT_INFO_OBJECT (GST_CAT_PARENTAGE, bin, "removed child \"%s\"",
|
GST_CAT_INFO_OBJECT (GST_CAT_PARENTAGE, bin, "removed child \"%s\"",
|
||||||
GST_OBJECT_NAME (element));
|
elem_name);
|
||||||
|
g_free (elem_name);
|
||||||
GST_UNLOCK (bin);
|
|
||||||
|
|
||||||
gst_element_set_manager (element, NULL);
|
gst_element_set_manager (element, NULL);
|
||||||
|
|
||||||
/* ref as we're going to emit a signal */
|
/* we should ref here to avoid bad app behaviour.. */
|
||||||
gst_object_ref (GST_OBJECT (element));
|
|
||||||
gst_object_unparent (GST_OBJECT (element));
|
gst_object_unparent (GST_OBJECT (element));
|
||||||
|
|
||||||
g_signal_emit (G_OBJECT (bin), gst_bin_signals[ELEMENT_REMOVED], 0, element);
|
g_signal_emit (G_OBJECT (bin), gst_bin_signals[ELEMENT_REMOVED], 0, element);
|
||||||
|
|
||||||
/* element is really out of our control now */
|
return TRUE;
|
||||||
gst_object_unref (GST_OBJECT (element));
|
|
||||||
|
wrong_parent:
|
||||||
|
g_warning ("Element %s is not in bin %p", GST_ELEMENT_NAME (element), bin);
|
||||||
|
GST_UNLOCK (element);
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
not_in_bin:
|
||||||
|
g_warning ("Element %s is not in bin %s", elem_name, GST_ELEMENT_NAME (bin));
|
||||||
|
GST_UNLOCK (bin);
|
||||||
|
g_free (elem_name);
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -372,27 +421,42 @@ gst_bin_remove_func (GstBin * bin, GstElement * element)
|
||||||
* will be freed in the process of removing it from the bin. If you
|
* will be freed in the process of removing it from the bin. If you
|
||||||
* want the element to still exist after removing, you need to call
|
* want the element to still exist after removing, you need to call
|
||||||
* #gst_object_ref before removing it from the bin.
|
* #gst_object_ref before removing it from the bin.
|
||||||
|
*
|
||||||
|
* Returns: TRUE if the element could be removed, FALSE on wrong parameters or
|
||||||
|
* the bin does not want to remove the element.
|
||||||
|
*
|
||||||
|
* MT safe.
|
||||||
*/
|
*/
|
||||||
void
|
gboolean
|
||||||
gst_bin_remove (GstBin * bin, GstElement * element)
|
gst_bin_remove (GstBin * bin, GstElement * element)
|
||||||
{
|
{
|
||||||
GstBinClass *bclass;
|
GstBinClass *bclass;
|
||||||
|
gboolean result;
|
||||||
|
|
||||||
GST_CAT_DEBUG (GST_CAT_PARENTAGE, "[%s]: trying to remove child %s",
|
g_return_val_if_fail (GST_IS_BIN (bin), FALSE);
|
||||||
GST_ELEMENT_NAME (bin), GST_ELEMENT_NAME (element));
|
g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
|
||||||
|
|
||||||
g_return_if_fail (GST_IS_BIN (bin));
|
|
||||||
g_return_if_fail (GST_IS_ELEMENT (element));
|
|
||||||
|
|
||||||
bclass = GST_BIN_GET_CLASS (bin);
|
bclass = GST_BIN_GET_CLASS (bin);
|
||||||
|
|
||||||
if (bclass->remove_element) {
|
if (G_UNLIKELY (bclass->remove_element == NULL))
|
||||||
bclass->remove_element (bin, element);
|
goto no_function;
|
||||||
} else {
|
|
||||||
g_warning ("cannot remove elements from bin %s\n", GST_ELEMENT_NAME (bin));
|
GST_CAT_DEBUG (GST_CAT_PARENTAGE, "removing element %s from bin %s",
|
||||||
}
|
GST_ELEMENT_NAME (element), GST_ELEMENT_NAME (bin));
|
||||||
|
|
||||||
|
result = bclass->remove_element (bin, element);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
no_function:
|
||||||
|
g_warning ("removing elements from bin %s is not supported",
|
||||||
|
GST_ELEMENT_NAME (bin));
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* bin iterator
|
||||||
|
*/
|
||||||
typedef struct _GstBinIterator
|
typedef struct _GstBinIterator
|
||||||
{
|
{
|
||||||
GstIterator iterator;
|
GstIterator iterator;
|
||||||
|
@ -436,14 +500,18 @@ gst_bin_iterator_free (GstBinIterator * it)
|
||||||
* after usage.
|
* after usage.
|
||||||
*
|
*
|
||||||
* Returns: a #GstIterator of #GstElements. gst_iterator_free after
|
* Returns: a #GstIterator of #GstElements. gst_iterator_free after
|
||||||
* use.
|
* use. returns NULL when passing bad parameters.
|
||||||
|
*
|
||||||
|
* MT safe.
|
||||||
*/
|
*/
|
||||||
GstIterator *
|
GstIterator *
|
||||||
gst_bin_iterate_elements (GstBin * bin)
|
gst_bin_iterate_elements (GstBin * bin)
|
||||||
{
|
{
|
||||||
GstBinIterator *result;
|
GstBinIterator *result;
|
||||||
|
|
||||||
GST_LOCK (bin);
|
g_return_val_if_fail (GST_IS_BIN (bin), NULL);
|
||||||
|
|
||||||
|
/* ne need to lock, nothing can change here */
|
||||||
result = (GstBinIterator *) gst_iterator_new (sizeof (GstBinIterator),
|
result = (GstBinIterator *) gst_iterator_new (sizeof (GstBinIterator),
|
||||||
GST_GET_LOCK (bin),
|
GST_GET_LOCK (bin),
|
||||||
&bin->children_cookie,
|
&bin->children_cookie,
|
||||||
|
@ -451,6 +519,7 @@ gst_bin_iterate_elements (GstBin * bin)
|
||||||
(GstIteratorResyncFunction) gst_bin_iterator_resync,
|
(GstIteratorResyncFunction) gst_bin_iterator_resync,
|
||||||
(GstIteratorFreeFunction) gst_bin_iterator_free);
|
(GstIteratorFreeFunction) gst_bin_iterator_free);
|
||||||
|
|
||||||
|
GST_LOCK (bin);
|
||||||
result->bin = GST_BIN (gst_object_ref (GST_OBJECT (bin)));
|
result->bin = GST_BIN (gst_object_ref (GST_OBJECT (bin)));
|
||||||
result->list = bin->children;
|
result->list = bin->children;
|
||||||
GST_UNLOCK (bin);
|
GST_UNLOCK (bin);
|
||||||
|
@ -478,6 +547,7 @@ bin_element_is_sink (GstElement * child, GstBin * bin)
|
||||||
GList *pads;
|
GList *pads;
|
||||||
gboolean connected_src = FALSE;
|
gboolean connected_src = FALSE;
|
||||||
|
|
||||||
|
/* FIXME not MT safe */
|
||||||
for (pads = child->srcpads; pads; pads = g_list_next (pads)) {
|
for (pads = child->srcpads; pads; pads = g_list_next (pads)) {
|
||||||
GstPad *pad = GST_PAD (pads->data);
|
GstPad *pad = GST_PAD (pads->data);
|
||||||
|
|
||||||
|
@ -514,6 +584,8 @@ bin_element_is_sink (GstElement * child, GstBin * bin)
|
||||||
* after usage.
|
* after usage.
|
||||||
*
|
*
|
||||||
* Returns: a #GstIterator of #GstElements. gst_iterator_free after use.
|
* Returns: a #GstIterator of #GstElements. gst_iterator_free after use.
|
||||||
|
*
|
||||||
|
* MT safe.
|
||||||
*/
|
*/
|
||||||
GstIterator *
|
GstIterator *
|
||||||
gst_bin_iterate_sinks (GstBin * bin)
|
gst_bin_iterate_sinks (GstBin * bin)
|
||||||
|
@ -556,6 +628,8 @@ gst_bin_get_state (GstElement * element, GstElementState * state,
|
||||||
|
|
||||||
/* we cannot take the state lock yet as we might block when querying
|
/* we cannot take the state lock yet as we might block when querying
|
||||||
* the children, holding the lock too long for no reason */
|
* the children, holding the lock too long for no reason */
|
||||||
|
/* FIXME, we can loop the list ourselves instead of creating the
|
||||||
|
* iterator */
|
||||||
children = gst_bin_iterate_sinks (bin);
|
children = gst_bin_iterate_sinks (bin);
|
||||||
child = gst_iterator_find_custom (children, timeout,
|
child = gst_iterator_find_custom (children, timeout,
|
||||||
(GCompareFunc) bin_find_pending_child);
|
(GCompareFunc) bin_find_pending_child);
|
||||||
|
@ -597,8 +671,6 @@ gst_bin_change_state (GstElement * element)
|
||||||
|
|
||||||
GQueue *elem_queue; /* list of elements waiting for a state change */
|
GQueue *elem_queue; /* list of elements waiting for a state change */
|
||||||
|
|
||||||
g_return_val_if_fail (GST_IS_BIN (element), GST_STATE_FAILURE);
|
|
||||||
|
|
||||||
bin = GST_BIN (element);
|
bin = GST_BIN (element);
|
||||||
|
|
||||||
old_state = GST_STATE (element);
|
old_state = GST_STATE (element);
|
||||||
|
@ -616,6 +688,7 @@ gst_bin_change_state (GstElement * element)
|
||||||
|
|
||||||
/* first step, find all sink elements, these are the elements
|
/* first step, find all sink elements, these are the elements
|
||||||
* without (linked) source pads. */
|
* without (linked) source pads. */
|
||||||
|
/* FIXME, we can iterate the list ourselves */
|
||||||
sinks = gst_bin_iterate_sinks (bin);
|
sinks = gst_bin_iterate_sinks (bin);
|
||||||
while (!done) {
|
while (!done) {
|
||||||
gpointer child;
|
gpointer child;
|
||||||
|
@ -767,27 +840,30 @@ gst_bin_dispose (GObject * object)
|
||||||
* Get the element with the given name from this bin. This
|
* Get the element with the given name from this bin. This
|
||||||
* function recurses into subbins.
|
* function recurses into subbins.
|
||||||
*
|
*
|
||||||
* Returns: the element with the given name
|
* Returns: the element with the given name. Returns NULL if the
|
||||||
|
* element is not found or when bad parameters were given.
|
||||||
|
*
|
||||||
|
* MT safe.
|
||||||
*/
|
*/
|
||||||
GstElement *
|
GstElement *
|
||||||
gst_bin_get_by_name (GstBin * bin, const gchar * name)
|
gst_bin_get_by_name (GstBin * bin, const gchar * name)
|
||||||
{
|
{
|
||||||
const GList *children;
|
GList *children;
|
||||||
GstElement *result = NULL;
|
GstElement *result = NULL;
|
||||||
|
|
||||||
g_return_val_if_fail (bin != NULL, result);
|
g_return_val_if_fail (GST_IS_BIN (bin), NULL);
|
||||||
g_return_val_if_fail (GST_IS_BIN (bin), result);
|
g_return_val_if_fail (name != NULL, NULL);
|
||||||
g_return_val_if_fail (name != NULL, result);
|
|
||||||
|
|
||||||
GST_CAT_INFO (GST_CAT_PARENTAGE, "[%s]: looking up child element %s",
|
GST_CAT_INFO (GST_CAT_PARENTAGE, "[%s]: looking up child element %s",
|
||||||
GST_ELEMENT_NAME (bin), name);
|
GST_ELEMENT_NAME (bin), name);
|
||||||
|
|
||||||
GST_LOCK (bin);
|
GST_LOCK (bin);
|
||||||
children = bin->children;
|
for (children = bin->children; children; children = g_list_next (children)) {
|
||||||
while (children) {
|
GstElement *child = GST_ELEMENT_CAST (children->data);
|
||||||
GstElement *child = GST_ELEMENT (children->data);
|
|
||||||
|
|
||||||
if (!strcmp (GST_OBJECT_NAME (child), name)) {
|
GST_LOCK (child);
|
||||||
|
if (!strcmp (GST_ELEMENT_NAME (child), name)) {
|
||||||
|
GST_UNLOCK (child);
|
||||||
result = child;
|
result = child;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -797,7 +873,6 @@ gst_bin_get_by_name (GstBin * bin, const gchar * name)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
children = g_list_next (children);
|
|
||||||
}
|
}
|
||||||
GST_UNLOCK (bin);
|
GST_UNLOCK (bin);
|
||||||
|
|
||||||
|
@ -812,25 +887,28 @@ gst_bin_get_by_name (GstBin * bin, const gchar * name)
|
||||||
* Get the element with the given name from this bin. If the
|
* Get the element with the given name from this bin. If the
|
||||||
* element is not found, a recursion is performed on the parent bin.
|
* element is not found, a recursion is performed on the parent bin.
|
||||||
*
|
*
|
||||||
* Returns: the element with the given name
|
* Returns: the element with the given name or NULL when the element
|
||||||
|
* was not found or bad parameters were given.
|
||||||
|
*
|
||||||
|
* MT safe.
|
||||||
*/
|
*/
|
||||||
GstElement *
|
GstElement *
|
||||||
gst_bin_get_by_name_recurse_up (GstBin * bin, const gchar * name)
|
gst_bin_get_by_name_recurse_up (GstBin * bin, const gchar * name)
|
||||||
{
|
{
|
||||||
GstElement *result = NULL;
|
GstElement *result;
|
||||||
GstObject *parent;
|
|
||||||
|
|
||||||
g_return_val_if_fail (bin != NULL, NULL);
|
|
||||||
g_return_val_if_fail (GST_IS_BIN (bin), NULL);
|
g_return_val_if_fail (GST_IS_BIN (bin), NULL);
|
||||||
g_return_val_if_fail (name != NULL, NULL);
|
g_return_val_if_fail (name != NULL, NULL);
|
||||||
|
|
||||||
result = gst_bin_get_by_name (bin, name);
|
result = gst_bin_get_by_name (bin, name);
|
||||||
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
parent = gst_object_get_parent (GST_OBJECT (bin));
|
GstObject *parent;
|
||||||
|
|
||||||
|
parent = gst_object_get_parent (GST_OBJECT_CAST (bin));
|
||||||
|
|
||||||
if (parent && GST_IS_BIN (parent)) {
|
if (parent && GST_IS_BIN (parent)) {
|
||||||
result = gst_bin_get_by_name_recurse_up (GST_BIN (parent), name);
|
result = gst_bin_get_by_name_recurse_up (GST_BIN_CAST (parent), name);
|
||||||
}
|
}
|
||||||
gst_object_unref (parent);
|
gst_object_unref (parent);
|
||||||
}
|
}
|
||||||
|
@ -850,21 +928,22 @@ gst_bin_get_by_name_recurse_up (GstBin * bin, const gchar * name)
|
||||||
* gst_bin_get_all_by_interface(). The function recurses bins inside bins.
|
* gst_bin_get_all_by_interface(). The function recurses bins inside bins.
|
||||||
*
|
*
|
||||||
* Returns: An element inside the bin implementing the interface.
|
* Returns: An element inside the bin implementing the interface.
|
||||||
|
*
|
||||||
|
* MT safe.
|
||||||
*/
|
*/
|
||||||
GstElement *
|
GstElement *
|
||||||
gst_bin_get_by_interface (GstBin * bin, GType interface)
|
gst_bin_get_by_interface (GstBin * bin, GType interface)
|
||||||
{
|
{
|
||||||
const GList *walk;
|
GList *walk;
|
||||||
GstElement *result = NULL;
|
GstElement *result = NULL;
|
||||||
|
|
||||||
g_return_val_if_fail (GST_IS_BIN (bin), NULL);
|
g_return_val_if_fail (GST_IS_BIN (bin), NULL);
|
||||||
g_return_val_if_fail (G_TYPE_IS_INTERFACE (interface), NULL);
|
g_return_val_if_fail (G_TYPE_IS_INTERFACE (interface), NULL);
|
||||||
|
|
||||||
GST_LOCK (bin);
|
GST_LOCK (bin);
|
||||||
walk = bin->children;
|
for (walk = bin->children; walk; walk = g_list_next (walk)) {
|
||||||
while (walk) {
|
|
||||||
if (G_TYPE_CHECK_INSTANCE_TYPE (walk->data, interface)) {
|
if (G_TYPE_CHECK_INSTANCE_TYPE (walk->data, interface)) {
|
||||||
result = GST_ELEMENT (walk->data);
|
result = GST_ELEMENT_CAST (walk->data);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (GST_IS_BIN (walk->data)) {
|
if (GST_IS_BIN (walk->data)) {
|
||||||
|
@ -872,7 +951,6 @@ gst_bin_get_by_interface (GstBin * bin, GType interface)
|
||||||
if (result)
|
if (result)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
walk = g_list_next (walk);
|
|
||||||
}
|
}
|
||||||
GST_UNLOCK (bin);
|
GST_UNLOCK (bin);
|
||||||
|
|
||||||
|
@ -890,29 +968,27 @@ gst_bin_get_by_interface (GstBin * bin, GType interface)
|
||||||
* g_list_free() after use.
|
* g_list_free() after use.
|
||||||
*
|
*
|
||||||
* Returns: The elements inside the bin implementing the interface.
|
* Returns: The elements inside the bin implementing the interface.
|
||||||
|
*
|
||||||
|
* MT safe.
|
||||||
*/
|
*/
|
||||||
GList *
|
GList *
|
||||||
gst_bin_get_all_by_interface (GstBin * bin, GType interface)
|
gst_bin_get_all_by_interface (GstBin * bin, GType interface)
|
||||||
{
|
{
|
||||||
const GList *walk;
|
GList *walk;
|
||||||
GList *ret = NULL;
|
GList *ret = NULL;
|
||||||
|
|
||||||
g_return_val_if_fail (GST_IS_BIN (bin), NULL);
|
g_return_val_if_fail (GST_IS_BIN (bin), NULL);
|
||||||
g_return_val_if_fail (G_TYPE_IS_INTERFACE (interface), NULL);
|
g_return_val_if_fail (G_TYPE_IS_INTERFACE (interface), NULL);
|
||||||
|
|
||||||
GST_LOCK (bin);
|
GST_LOCK (bin);
|
||||||
walk = bin->children;
|
for (walk = bin->children; walk; walk = g_list_next (walk)) {
|
||||||
while (walk) {
|
|
||||||
if (G_TYPE_CHECK_INSTANCE_TYPE (walk->data, interface)) {
|
if (G_TYPE_CHECK_INSTANCE_TYPE (walk->data, interface)) {
|
||||||
GST_DEBUG_OBJECT (bin, "element %s implements requested interface",
|
|
||||||
GST_ELEMENT_NAME (GST_ELEMENT (walk->data)));
|
|
||||||
ret = g_list_prepend (ret, walk->data);
|
ret = g_list_prepend (ret, walk->data);
|
||||||
}
|
}
|
||||||
if (GST_IS_BIN (walk->data)) {
|
if (GST_IS_BIN (walk->data)) {
|
||||||
ret = g_list_concat (ret,
|
ret = g_list_concat (ret,
|
||||||
gst_bin_get_all_by_interface (GST_BIN (walk->data), interface));
|
gst_bin_get_all_by_interface (GST_BIN (walk->data), interface));
|
||||||
}
|
}
|
||||||
walk = g_list_next (walk);
|
|
||||||
}
|
}
|
||||||
GST_UNLOCK (bin);
|
GST_UNLOCK (bin);
|
||||||
|
|
||||||
|
|
20
gst/gstbin.h
20
gst/gstbin.h
|
@ -37,6 +37,7 @@ GST_EXPORT GType _gst_bin_type;
|
||||||
#define GST_BIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_BIN, GstBinClass))
|
#define GST_BIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_BIN, GstBinClass))
|
||||||
#define GST_BIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_BIN, GstBin))
|
#define GST_BIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_BIN, GstBin))
|
||||||
#define GST_BIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_BIN, GstBinClass))
|
#define GST_BIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_BIN, GstBinClass))
|
||||||
|
#define GST_BIN_CAST(obj) ((GstBin*)(obj))
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
GST_BIN_FLAG_FIXED_CLOCK,
|
GST_BIN_FLAG_FIXED_CLOCK,
|
||||||
|
@ -56,25 +57,30 @@ struct _GstBin {
|
||||||
GstElement element;
|
GstElement element;
|
||||||
|
|
||||||
/*< public >*/ /* with LOCK */
|
/*< public >*/ /* with LOCK */
|
||||||
/* our children */
|
/* our children, subclass are supposed to update these
|
||||||
|
* fields to reflect their state with _iterate_*() */
|
||||||
gint numchildren;
|
gint numchildren;
|
||||||
GList *children;
|
GList *children;
|
||||||
guint32 children_cookie;
|
guint32 children_cookie;
|
||||||
|
|
||||||
|
/*< private >*/
|
||||||
gpointer _gst_reserved[GST_PADDING];
|
gpointer _gst_reserved[GST_PADDING];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstBinClass {
|
struct _GstBinClass {
|
||||||
GstElementClass parent_class;
|
GstElementClass parent_class;
|
||||||
|
|
||||||
/* vtable */
|
/*< public >*/
|
||||||
void (*add_element) (GstBin *bin, GstElement *element);
|
|
||||||
void (*remove_element) (GstBin *bin, GstElement *element);
|
|
||||||
|
|
||||||
/* signals */
|
/* signals */
|
||||||
void (*element_added) (GstBin *bin, GstElement *child);
|
void (*element_added) (GstBin *bin, GstElement *child);
|
||||||
void (*element_removed) (GstBin *bin, GstElement *child);
|
void (*element_removed) (GstBin *bin, GstElement *child);
|
||||||
|
|
||||||
|
/*< protected >*/
|
||||||
|
/* vtable */
|
||||||
|
gboolean (*add_element) (GstBin *bin, GstElement *element);
|
||||||
|
gboolean (*remove_element) (GstBin *bin, GstElement *element);
|
||||||
|
|
||||||
|
/*< private >*/
|
||||||
gpointer _gst_reserved[GST_PADDING];
|
gpointer _gst_reserved[GST_PADDING];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -82,8 +88,8 @@ GType gst_bin_get_type (void);
|
||||||
GstElement* gst_bin_new (const gchar *name);
|
GstElement* gst_bin_new (const gchar *name);
|
||||||
|
|
||||||
/* add and remove elements from the bin */
|
/* add and remove elements from the bin */
|
||||||
void gst_bin_add (GstBin *bin, GstElement *element);
|
gboolean gst_bin_add (GstBin *bin, GstElement *element);
|
||||||
void gst_bin_remove (GstBin *bin, GstElement *element);
|
gboolean gst_bin_remove (GstBin *bin, GstElement *element);
|
||||||
|
|
||||||
/* retrieve a single child */
|
/* retrieve a single child */
|
||||||
GstElement* gst_bin_get_by_name (GstBin *bin, const gchar *name);
|
GstElement* gst_bin_get_by_name (GstBin *bin, const gchar *name);
|
||||||
|
|
|
@ -108,6 +108,7 @@ typedef enum {
|
||||||
struct _GstBuffer {
|
struct _GstBuffer {
|
||||||
GstData data_type;
|
GstData data_type;
|
||||||
|
|
||||||
|
/*< public >*/ /* with COW */
|
||||||
/* pointer to data and its size */
|
/* pointer to data and its size */
|
||||||
guint8 *data; /* pointer to buffer data */
|
guint8 *data; /* pointer to buffer data */
|
||||||
guint size; /* size of buffer data */
|
guint size; /* size of buffer data */
|
||||||
|
@ -130,9 +131,11 @@ struct _GstBuffer {
|
||||||
guint64 offset;
|
guint64 offset;
|
||||||
guint64 offset_end;
|
guint64 offset_end;
|
||||||
|
|
||||||
|
/*< protected >*/
|
||||||
GstBufferFreeDataFunc free_data;
|
GstBufferFreeDataFunc free_data;
|
||||||
gpointer buffer_private;
|
gpointer buffer_private;
|
||||||
|
|
||||||
|
/*< private >*/
|
||||||
gpointer _gst_reserved[GST_PADDING];
|
gpointer _gst_reserved[GST_PADDING];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -167,7 +170,7 @@ GstBuffer* gst_buffer_merge (GstBuffer *buf1, GstBuffer *buf2);
|
||||||
gboolean gst_buffer_is_span_fast (GstBuffer *buf1, GstBuffer *buf2);
|
gboolean gst_buffer_is_span_fast (GstBuffer *buf1, GstBuffer *buf2);
|
||||||
GstBuffer* gst_buffer_span (GstBuffer *buf1, guint32 offset, GstBuffer *buf2, guint32 len);
|
GstBuffer* gst_buffer_span (GstBuffer *buf1, guint32 offset, GstBuffer *buf2, guint32 len);
|
||||||
|
|
||||||
/* --- private --- */
|
/* --- protected --- */
|
||||||
void _gst_buffer_initialize (void);
|
void _gst_buffer_initialize (void);
|
||||||
|
|
||||||
void gst_buffer_default_free (GstBuffer *buffer);
|
void gst_buffer_default_free (GstBuffer *buffer);
|
||||||
|
|
|
@ -34,6 +34,7 @@ G_BEGIN_DECLS
|
||||||
#define GST_BUS_CLASS(bclass) (G_TYPE_CHECK_CLASS_CAST ((bclass), GST_TYPE_BUS, GstBusClass))
|
#define GST_BUS_CLASS(bclass) (G_TYPE_CHECK_CLASS_CAST ((bclass), GST_TYPE_BUS, GstBusClass))
|
||||||
#define GST_IS_BUS_CLASS(bclass) (G_TYPE_CHECK_CLASS_TYPE ((bclass), GST_TYPE_BUS))
|
#define GST_IS_BUS_CLASS(bclass) (G_TYPE_CHECK_CLASS_TYPE ((bclass), GST_TYPE_BUS))
|
||||||
#define GST_BUS_GET_CLASS(bus) (G_TYPE_INSTANCE_GET_CLASS ((bus), GST_TYPE_BUS, GstBusClass))
|
#define GST_BUS_GET_CLASS(bus) (G_TYPE_INSTANCE_GET_CLASS ((bus), GST_TYPE_BUS, GstBusClass))
|
||||||
|
#define GST_BUS_CAST(bus) ((GstBus*)(bus))
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
|
@ -51,6 +52,7 @@ typedef gboolean (*GstBusHandler) (GstBus *bus, GstMessage *message, gpointer da
|
||||||
struct _GstBus {
|
struct _GstBus {
|
||||||
GstObject object;
|
GstObject object;
|
||||||
|
|
||||||
|
/*< private >*/
|
||||||
GAsyncQueue *queue;
|
GAsyncQueue *queue;
|
||||||
|
|
||||||
GstBusSyncHandler sync_handler;
|
GstBusSyncHandler sync_handler;
|
||||||
|
@ -59,12 +61,14 @@ struct _GstBus {
|
||||||
gint control_socket[2];
|
gint control_socket[2];
|
||||||
GIOChannel *io_channel;
|
GIOChannel *io_channel;
|
||||||
|
|
||||||
|
/*< private >*/
|
||||||
gpointer _gst_reserved[GST_PADDING];
|
gpointer _gst_reserved[GST_PADDING];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstBusClass {
|
struct _GstBusClass {
|
||||||
GstObjectClass parent_class;
|
GstObjectClass parent_class;
|
||||||
|
|
||||||
|
/*< private >*/
|
||||||
gpointer _gst_reserved[GST_PADDING];
|
gpointer _gst_reserved[GST_PADDING];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -59,18 +59,23 @@ typedef struct _GstStaticCaps GstStaticCaps;
|
||||||
struct _GstCaps {
|
struct _GstCaps {
|
||||||
GType type;
|
GType type;
|
||||||
|
|
||||||
|
/*< public >*/ /* with COW */
|
||||||
/* refcounting */
|
/* refcounting */
|
||||||
GstAtomicInt refcount;
|
GstAtomicInt refcount;
|
||||||
|
|
||||||
guint16 flags;
|
guint16 flags;
|
||||||
GPtrArray *structs;
|
GPtrArray *structs;
|
||||||
|
|
||||||
|
/*< private >*/
|
||||||
gpointer _gst_reserved[GST_PADDING];
|
gpointer _gst_reserved[GST_PADDING];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstStaticCaps {
|
struct _GstStaticCaps {
|
||||||
|
/*< public >*/
|
||||||
GstCaps caps;
|
GstCaps caps;
|
||||||
const char *string;
|
const char *string;
|
||||||
|
|
||||||
|
/*< private >*/
|
||||||
gpointer _gst_reserved[GST_PADDING];
|
gpointer _gst_reserved[GST_PADDING];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,7 @@ G_BEGIN_DECLS
|
||||||
#define GST_CLOCK_CLASS(cclass) (G_TYPE_CHECK_CLASS_CAST ((cclass), GST_TYPE_CLOCK, GstClockClass))
|
#define GST_CLOCK_CLASS(cclass) (G_TYPE_CHECK_CLASS_CAST ((cclass), GST_TYPE_CLOCK, GstClockClass))
|
||||||
#define GST_IS_CLOCK_CLASS(cclass) (G_TYPE_CHECK_CLASS_TYPE ((cclass), GST_TYPE_CLOCK))
|
#define GST_IS_CLOCK_CLASS(cclass) (G_TYPE_CHECK_CLASS_TYPE ((cclass), GST_TYPE_CLOCK))
|
||||||
#define GST_CLOCK_GET_CLASS(clock) (G_TYPE_INSTANCE_GET_CLASS ((clock), GST_TYPE_CLOCK, GstClockClass))
|
#define GST_CLOCK_GET_CLASS(clock) (G_TYPE_INSTANCE_GET_CLASS ((clock), GST_TYPE_CLOCK, GstClockClass))
|
||||||
|
#define GST_CLOCK_CAST(clock) ((GstClock*)(clock))
|
||||||
|
|
||||||
typedef guint64 GstClockTime;
|
typedef guint64 GstClockTime;
|
||||||
typedef gint64 GstClockTimeDiff;
|
typedef gint64 GstClockTimeDiff;
|
||||||
|
@ -73,14 +74,14 @@ typedef gboolean (*GstClockCallback) (GstClock *clock, GstClockTime time,
|
||||||
GstClockID id, gpointer user_data);
|
GstClockID id, gpointer user_data);
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
/* --- protected --- */
|
/*< protected >*/
|
||||||
GST_CLOCK_ENTRY_OK,
|
GST_CLOCK_ENTRY_OK,
|
||||||
GST_CLOCK_ENTRY_EARLY,
|
GST_CLOCK_ENTRY_EARLY,
|
||||||
GST_CLOCK_ENTRY_RESTART
|
GST_CLOCK_ENTRY_RESTART
|
||||||
} GstClockEntryStatus;
|
} GstClockEntryStatus;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
/* --- protected --- */
|
/*< protected >*/
|
||||||
GST_CLOCK_ENTRY_SINGLE,
|
GST_CLOCK_ENTRY_SINGLE,
|
||||||
GST_CLOCK_ENTRY_PERIODIC
|
GST_CLOCK_ENTRY_PERIODIC
|
||||||
} GstClockEntryType;
|
} GstClockEntryType;
|
||||||
|
@ -93,7 +94,7 @@ typedef enum {
|
||||||
#define GST_CLOCK_ENTRY_STATUS(entry) ((entry)->status)
|
#define GST_CLOCK_ENTRY_STATUS(entry) ((entry)->status)
|
||||||
|
|
||||||
struct _GstClockEntry {
|
struct _GstClockEntry {
|
||||||
/* --- protected --- */
|
/*< protected >*/
|
||||||
GstClock *clock;
|
GstClock *clock;
|
||||||
GstClockEntryType type;
|
GstClockEntryType type;
|
||||||
GstClockTime time;
|
GstClockTime time;
|
||||||
|
@ -128,13 +129,14 @@ typedef enum
|
||||||
struct _GstClock {
|
struct _GstClock {
|
||||||
GstObject object;
|
GstObject object;
|
||||||
|
|
||||||
|
/*< public >*/
|
||||||
GstClockFlags flags;
|
GstClockFlags flags;
|
||||||
|
|
||||||
/* --- protected --- */
|
/*< protected >*/
|
||||||
GstClockTime start_time;
|
GstClockTime start_time;
|
||||||
GstClockTime last_time;
|
GstClockTime last_time;
|
||||||
|
|
||||||
/* --- private --- */
|
/*< private >*/
|
||||||
guint64 resolution;
|
guint64 resolution;
|
||||||
GList *entries;
|
GList *entries;
|
||||||
GMutex *active_mutex;
|
GMutex *active_mutex;
|
||||||
|
@ -147,6 +149,7 @@ struct _GstClock {
|
||||||
struct _GstClockClass {
|
struct _GstClockClass {
|
||||||
GstObjectClass parent_class;
|
GstObjectClass parent_class;
|
||||||
|
|
||||||
|
/*< protected >*/
|
||||||
/* vtable */
|
/* vtable */
|
||||||
gdouble (*change_speed) (GstClock *clock,
|
gdouble (*change_speed) (GstClock *clock,
|
||||||
gdouble oldspeed, gdouble newspeed);
|
gdouble oldspeed, gdouble newspeed);
|
||||||
|
@ -162,6 +165,8 @@ struct _GstClockClass {
|
||||||
GstClockEntryStatus (*wait_async) (GstClock *clock, GstClockEntry *entry);
|
GstClockEntryStatus (*wait_async) (GstClock *clock, GstClockEntry *entry);
|
||||||
void (*unschedule) (GstClock *clock, GstClockEntry *entry);
|
void (*unschedule) (GstClock *clock, GstClockEntry *entry);
|
||||||
void (*unlock) (GstClock *clock, GstClockEntry *entry);
|
void (*unlock) (GstClock *clock, GstClockEntry *entry);
|
||||||
|
|
||||||
|
/*< private >*/
|
||||||
gpointer _gst_reserved[GST_PADDING];
|
gpointer _gst_reserved[GST_PADDING];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -69,15 +69,18 @@ typedef enum
|
||||||
struct _GstData {
|
struct _GstData {
|
||||||
GType type;
|
GType type;
|
||||||
|
|
||||||
|
/*< public >*/ /* with COW */
|
||||||
/* refcounting */
|
/* refcounting */
|
||||||
GstAtomicInt refcount;
|
GstAtomicInt refcount;
|
||||||
|
|
||||||
guint16 flags;
|
guint16 flags;
|
||||||
|
|
||||||
|
/*< protected >*/
|
||||||
/* utility function pointers, can override default */
|
/* utility function pointers, can override default */
|
||||||
GstDataFreeFunction free; /* free the data */
|
GstDataFreeFunction free; /* free the data */
|
||||||
GstDataCopyFunction copy; /* copy the data */
|
GstDataCopyFunction copy; /* copy the data */
|
||||||
|
|
||||||
|
/*< private >*/
|
||||||
gpointer _gst_reserved[GST_PADDING];
|
gpointer _gst_reserved[GST_PADDING];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -115,7 +115,7 @@ typedef enum {
|
||||||
} GstElementFlags;
|
} GstElementFlags;
|
||||||
|
|
||||||
#define GST_ELEMENT_NAME(obj) (GST_OBJECT_NAME(obj))
|
#define GST_ELEMENT_NAME(obj) (GST_OBJECT_NAME(obj))
|
||||||
#define GST_ELEMENT_PARENT(obj) (GST_OBJECT_PARENT(obj))
|
#define GST_ELEMENT_PARENT(obj) (GST_ELEMENT_CAST(GST_OBJECT_PARENT(obj)))
|
||||||
#define GST_ELEMENT_MANAGER(obj) (GST_ELEMENT_CAST(obj)->manager)
|
#define GST_ELEMENT_MANAGER(obj) (GST_ELEMENT_CAST(obj)->manager)
|
||||||
#define GST_ELEMENT_CLOCK(obj) (GST_ELEMENT_CAST(obj)->clock)
|
#define GST_ELEMENT_CLOCK(obj) (GST_ELEMENT_CAST(obj)->clock)
|
||||||
#define GST_ELEMENT_PADS(obj) (GST_ELEMENT_CAST(obj)->pads)
|
#define GST_ELEMENT_PADS(obj) (GST_ELEMENT_CAST(obj)->pads)
|
||||||
|
@ -182,6 +182,7 @@ struct _GstElement {
|
||||||
struct _GstElementClass {
|
struct _GstElementClass {
|
||||||
GstObjectClass parent_class;
|
GstObjectClass parent_class;
|
||||||
|
|
||||||
|
/*< public >*/
|
||||||
/* the element details */
|
/* the element details */
|
||||||
GstElementDetails details;
|
GstElementDetails details;
|
||||||
|
|
||||||
|
@ -199,6 +200,7 @@ struct _GstElementClass {
|
||||||
void (*pad_removed) (GstElement *element, GstPad *pad);
|
void (*pad_removed) (GstElement *element, GstPad *pad);
|
||||||
void (*no_more_pads) (GstElement *element);
|
void (*no_more_pads) (GstElement *element);
|
||||||
|
|
||||||
|
/*< protected >*/
|
||||||
/* vtable */
|
/* vtable */
|
||||||
|
|
||||||
/* request/release pads */
|
/* request/release pads */
|
||||||
|
@ -232,6 +234,7 @@ struct _GstElementClass {
|
||||||
gboolean (*query) (GstElement *element, GstQueryType type,
|
gboolean (*query) (GstElement *element, GstQueryType type,
|
||||||
GstFormat *format, gint64 *value);
|
GstFormat *format, gint64 *value);
|
||||||
|
|
||||||
|
/*< private >*/
|
||||||
gpointer _gst_reserved[GST_PADDING - 1];
|
gpointer _gst_reserved[GST_PADDING - 1];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -154,6 +154,7 @@ typedef struct
|
||||||
struct _GstEvent {
|
struct _GstEvent {
|
||||||
GstData data;
|
GstData data;
|
||||||
|
|
||||||
|
/*< public >*/ /* with COW */
|
||||||
GstEventType type;
|
GstEventType type;
|
||||||
guint64 timestamp;
|
guint64 timestamp;
|
||||||
GstObject *src;
|
GstObject *src;
|
||||||
|
@ -182,6 +183,7 @@ struct _GstEvent {
|
||||||
} structure;
|
} structure;
|
||||||
} event_data;
|
} event_data;
|
||||||
|
|
||||||
|
/*< private >*/
|
||||||
gpointer _gst_reserved[GST_PADDING];
|
gpointer _gst_reserved[GST_PADDING];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -62,13 +62,15 @@ typedef enum {
|
||||||
struct _GstMessage {
|
struct _GstMessage {
|
||||||
GstData data;
|
GstData data;
|
||||||
|
|
||||||
|
/*< public >*/ /* with MESSAGE_LOCK */
|
||||||
|
GMutex *lock; /* lock and cond for async delivery */
|
||||||
|
GCond *cond;
|
||||||
|
|
||||||
|
/*< public >*/ /* with COW */
|
||||||
GstMessageType type;
|
GstMessageType type;
|
||||||
guint64 timestamp;
|
guint64 timestamp;
|
||||||
GstObject *src;
|
GstObject *src;
|
||||||
|
|
||||||
GMutex *lock; /* lock and cond for async delivery */
|
|
||||||
GCond *cond;
|
|
||||||
|
|
||||||
union {
|
union {
|
||||||
struct {
|
struct {
|
||||||
GError *error;
|
GError *error;
|
||||||
|
@ -82,6 +84,7 @@ struct _GstMessage {
|
||||||
} tag;
|
} tag;
|
||||||
} message_data;
|
} message_data;
|
||||||
|
|
||||||
|
/*< private >*/
|
||||||
gpointer _gst_reserved[GST_PADDING];
|
gpointer _gst_reserved[GST_PADDING];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,7 @@ typedef gboolean (*GstStructureForeachFunc) (GQuark field_id,
|
||||||
struct _GstStructure {
|
struct _GstStructure {
|
||||||
GType type;
|
GType type;
|
||||||
|
|
||||||
|
/*< private >*/
|
||||||
GQuark name;
|
GQuark name;
|
||||||
|
|
||||||
GArray *fields;
|
GArray *fields;
|
||||||
|
|
Loading…
Reference in a new issue