+2005-09-28 Wim Taymans <wim@fluendo.com>
+
+ * gst/gstbin.c: (gst_bin_class_init), (gst_bin_provide_clock_func),
+ (add_to_queue), (clear_queue), (reset_degree), (update_degree),
+ (find_element), (gst_bin_sort_iterator_next),
+ (gst_bin_sort_iterator_resync), (gst_bin_sort_iterator_free),
+ (gst_bin_iterate_sorted), (gst_bin_element_set_state),
+ (gst_bin_change_state), (gst_bin_dispose):
+ Small doc fixes. get_clock -> provide_clock.
+
+ * gst/gstelement.c: (gst_element_class_init),
+ (gst_element_provides_clock), (gst_element_provide_clock),
+ (gst_element_get_clock), (gst_element_commit_state),
+ (gst_element_lost_state):
+ * gst/gstelement.h:
+ Make get/set_clock() symetric. Add provide_clock vmethod since
+ that is actually what this function does.
+
+ * gst/gstpipeline.c: (gst_pipeline_class_init),
+ (gst_pipeline_change_state), (gst_pipeline_provide_clock_func),
+ (gst_pipeline_get_clock):
+ get_clock -> provide_clock.
+
2005-09-28 Andy Wingo <wingo@pobox.com>
* gst/base/gstbasesrc.c (gst_base_src_unlock): Comment a bit in
#ifndef GST_DISABLE_INDEX
static void gst_bin_set_index_func (GstElement * element, GstIndex * index);
#endif
-static GstClock *gst_bin_get_clock_func (GstElement * element);
+static GstClock *gst_bin_provide_clock_func (GstElement * element);
static void gst_bin_set_clock_func (GstElement * element, GstClock * clock);
static gboolean gst_bin_send_event (GstElement * element, GstEvent * event);
#ifndef GST_DISABLE_INDEX
gstelement_class->set_index = GST_DEBUG_FUNCPTR (gst_bin_set_index_func);
#endif
- gstelement_class->get_clock = GST_DEBUG_FUNCPTR (gst_bin_get_clock_func);
+ gstelement_class->provide_clock =
+ GST_DEBUG_FUNCPTR (gst_bin_provide_clock_func);
gstelement_class->set_clock = GST_DEBUG_FUNCPTR (gst_bin_set_clock_func);
gstelement_class->send_event = GST_DEBUG_FUNCPTR (gst_bin_send_event);
/* get the clock for this bin by asking all of the children in this bin
*
+ * The ref of the returned clock in increased so unref after usage.
+ *
* MT safe
+ *
+ * FIXME, clock selection is not correct here.
*/
static GstClock *
-gst_bin_get_clock_func (GstElement * element)
+gst_bin_provide_clock_func (GstElement * element)
{
GstClock *result = NULL;
GstBin *bin;
for (children = bin->children; children; children = g_list_next (children)) {
GstElement *child = GST_ELEMENT (children->data);
- result = gst_element_get_clock (child);
+ result = gst_element_provide_clock (child);
if (result)
break;
}
gst_object_unref (p);
}
-/* set all outdegrees to 0. Elements marked as a sink are
+/* set all degrees to 0. Elements marked as a sink are
* added to the queue immediatly. */
static void
-reset_outdegree (GstElement * element, GstBinSortIterator * bit)
+reset_degree (GstElement * element, GstBinSortIterator * bit)
{
/* sinks are added right away */
if (GST_FLAG_IS_SET (element, GST_ELEMENT_IS_SINK)) {
}
}
-/* adjust the outdegree of all elements connected to the given
- * element. If an outdegree of an element drops to 0, it is
+/* adjust the degree of all elements connected to the given
+ * element. If an degree of an element drops to 0, it is
* added to the queue of elements to schedule next.
*
* We have to make sure not to cross the bin boundary this element
* belongs to.
*/
static void
-update_outdegree (GstElement * element, GstBinSortIterator * bit)
+update_degree (GstElement * element, GstBinSortIterator * bit)
{
gboolean linked = FALSE;
GST_LOCK (element);
- /* don't touch outdegree is element has no sourcepads */
+ /* don't touch degree is element has no sourcepads */
if (element->numsinkpads != 0) {
- /* loop over all sinkpads, decrement outdegree for all connected
+ /* loop over all sinkpads, decrement degree for all connected
* elements in this bin */
GList *pads;
GST_ELEMENT_NAME (peer_element),
old_deg, new_deg, GST_ELEMENT_NAME (element));
- /* update outdegree */
+ /* update degree */
if (new_deg == 0) {
- /* outdegree hit 0, add to queue */
+ /* degree hit 0, add to queue */
add_to_queue (bit, peer_element);
} else {
HASH_SET_DEGREE (bit, peer_element, new_deg);
}
/* find the next best element not handled yet. This is the one
- * with the lowest non-negative outdegree */
+ * with the lowest non-negative degree */
static void
find_element (GstElement * element, GstBinSortIterator * bit)
{
- gint outdegree;
+ gint degree;
/* element is already handled */
- if ((outdegree = HASH_GET_DEGREE (bit, element)) < 0)
+ if ((degree = HASH_GET_DEGREE (bit, element)) < 0)
return;
- /* first element or element with smaller outdegree */
- if (bit->best == NULL || bit->best_deg > outdegree) {
+ /* first element or element with smaller degree */
+ if (bit->best == NULL || bit->best_deg > degree) {
bit->best = element;
- bit->best_deg = outdegree;
+ bit->best_deg = degree;
}
}
}
GST_DEBUG ("queue head gives %s", GST_ELEMENT_NAME (*result));
- /* update outdegrees of linked elements */
- update_outdegree (GST_ELEMENT_CAST (*result), bit);
+ /* update degrees of linked elements */
+ update_degree (GST_ELEMENT_CAST (*result), bit);
return GST_ITERATOR_OK;
}
-/* clear queues, recalculate the outdegrees and restart. */
+/* clear queues, recalculate the degrees and restart. */
static void
gst_bin_sort_iterator_resync (GstBinSortIterator * bit)
{
clear_queue (bit->queue);
- /* reset outdegrees */
- g_list_foreach (bit->bin->children, (GFunc) reset_outdegree, bit);
- /* calc outdegrees, incrementing */
+ /* reset degrees */
+ g_list_foreach (bit->bin->children, (GFunc) reset_degree, bit);
+ /* calc degrees, incrementing */
bit->mode = 1;
- g_list_foreach (bit->bin->children, (GFunc) update_outdegree, bit);
- /* for the rest of the function we decrement the outdegrees */
+ g_list_foreach (bit->bin->children, (GFunc) update_degree, bit);
+ /* for the rest of the function we decrement the degrees */
bit->mode = -1;
}
*
* You can get and set a #GstClock on an element using gst_element_get_clock()
* and gst_element_set_clock().
+ * Some elements can provide a clock for the pipeline if
+ * gst_element_provides_clock() returns TRUE. With the gst_element_provide_clock()
+ * method one can retrieve the clock provided by such an element.
+ * Not all elements require a clock to operate correctly. If
+ * gst_element_requires_clock() returns TRUE, a clock should be set on the element
+ * with gst_element_set_clock().
+ * Note that clock slection and distribution is normally handled by the toplevel
+ * GstPipeline so the clock functions are only to be used in very specific situations.
*/
#include "gst_private.h"
#include <glib.h>
parent_class = g_type_class_ref (GST_TYPE_OBJECT);
/**
- * GstElement::state-changed:
- * @gstelement: the object which received the signal
- * @old_state: the GST_STATE_XXX before the change
- * @new_state: the GST_STATE_XXX after the change
- *
- * the #GstState of the element has been changed
- */
- gst_element_signals[STATE_CHANGE] =
- g_signal_new ("state-changed", G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstElementClass, state_changed), NULL,
- NULL, gst_marshal_VOID__INT_INT, G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_INT);
- /**
* GstElement::pad-added:
* @gstelement: the object which received the signal
* @new_pad: the pad that has been added
*
- * a new #GstPad has been added to the element
+ * a new #GstPad has been added to the element.
*/
gst_element_signals[NEW_PAD] =
g_signal_new ("pad-added", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
- result = (GST_ELEMENT_GET_CLASS (element)->get_clock != NULL);
+ result = (GST_ELEMENT_GET_CLASS (element)->provide_clock != NULL);
+
+ return result;
+}
+
+/**
+ * gst_element_provide_clock:
+ * @element: a #GstElement to query
+ *
+ * Get the clock provided by the given element.
+ *
+ * Returns: the GstClock provided by the element or NULL
+ * if no clock could be provided.
+ *
+ * MT safe.
+ */
+GstClock *
+gst_element_provide_clock (GstElement * element)
+{
+ GstClock *result = NULL;
+ GstElementClass *oclass;
+
+ g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
+
+ oclass = GST_ELEMENT_GET_CLASS (element);
+
+ if (oclass->provide_clock)
+ result = oclass->provide_clock (element);
return result;
}
* gst_element_get_clock:
* @element: a #GstElement to get the clock of.
*
- * Gets the clock of the element. If the element provides a clock,
- * this function will return this clock. For elements that do not
- * provide a clock, this function returns NULL.
+ * Gets the currently configured clock of the element.
*
* Returns: the #GstClock of the element. unref after usage.
*
GstClock *
gst_element_get_clock (GstElement * element)
{
- GstElementClass *oclass;
+ GstClock *result;
g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
- oclass = GST_ELEMENT_GET_CLASS (element);
-
- if (oclass->get_clock)
- return oclass->get_clock (element);
+ GST_LOCK (element);
+ if ((result = element->clock))
+ gst_object_ref (result);
+ GST_UNLOCK (element);
- return NULL;
+ return result;
}
/**
gst_element_commit_state (GstElement * element)
{
GstState pending;
- GstMessage *message;
g_return_if_fail (GST_IS_ELEMENT (element));
if (pending != GST_STATE_VOID_PENDING) {
GstState old_state = GST_STATE (element);
+ GstMessage *message;
GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
"committing state from %s to %s",
GST_STATE_PENDING (element) = GST_STATE_VOID_PENDING;
GST_STATE_ERROR (element) = FALSE;
- g_signal_emit (G_OBJECT (element), gst_element_signals[STATE_CHANGE],
- 0, old_state, pending);
message = gst_message_new_state_changed (GST_OBJECT (element),
old_state, pending);
gst_element_post_message (element, message);
if (GST_STATE_PENDING (element) == GST_STATE_VOID_PENDING &&
!GST_STATE_ERROR (element)) {
GstState current_state = GST_STATE (element);
+ GstMessage *message;
GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
"lost state of %s", gst_element_state_get_name (current_state));
GST_STATE_PENDING (element) = current_state;
GST_STATE_ERROR (element) = FALSE;
+
+ message = gst_message_new_state_changed (GST_OBJECT (element),
+ current_state, current_state);
+ gst_element_post_message (element, message);
}
}
void (*set_bus) (GstElement * element, GstBus * bus);
/* set/get clocks */
- GstClock* (*get_clock) (GstElement *element);
+ GstClock* (*provide_clock) (GstElement *element);
void (*set_clock) (GstElement *element, GstClock *clock);
/* index */
/* clocking */
gboolean gst_element_requires_clock (GstElement *element);
gboolean gst_element_provides_clock (GstElement *element);
+GstClock* gst_element_provide_clock (GstElement *element);
GstClock* gst_element_get_clock (GstElement *element);
void gst_element_set_clock (GstElement *element, GstClock *clock);
void gst_element_set_base_time (GstElement *element, GstClockTime time);
static gboolean gst_pipeline_send_event (GstElement * element,
GstEvent * event);
-static GstClock *gst_pipeline_get_clock_func (GstElement * element);
+static GstClock *gst_pipeline_provide_clock_func (GstElement * element);
static GstStateChangeReturn gst_pipeline_change_state (GstElement * element,
GstStateChange transition);
gstelement_class->send_event = GST_DEBUG_FUNCPTR (gst_pipeline_send_event);
gstelement_class->change_state =
GST_DEBUG_FUNCPTR (gst_pipeline_change_state);
- gstelement_class->get_clock = GST_DEBUG_FUNCPTR (gst_pipeline_get_clock_func);
+ gstelement_class->provide_clock =
+ GST_DEBUG_FUNCPTR (gst_pipeline_provide_clock_func);
}
static void
break;
case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
/* when going to playing, select a clock */
- if ((clock = gst_element_get_clock (element))) {
+ if ((clock = gst_element_provide_clock (element))) {
GstClockTime start_time;
/* distribute the clock */
}
static GstClock *
-gst_pipeline_get_clock_func (GstElement * element)
+gst_pipeline_provide_clock_func (GstElement * element)
{
GstClock *clock = NULL;
GstPipeline *pipeline = GST_PIPELINE (element);
} else {
GST_UNLOCK (pipeline);
clock =
- GST_ELEMENT_CLASS (parent_class)->get_clock (GST_ELEMENT (pipeline));
+ GST_ELEMENT_CLASS (parent_class)->
+ provide_clock (GST_ELEMENT (pipeline));
/* no clock, use a system clock */
if (!clock) {
clock = gst_system_clock_obtain ();
{
g_return_val_if_fail (GST_IS_PIPELINE (pipeline), NULL);
- return gst_pipeline_get_clock_func (GST_ELEMENT (pipeline));
+ return gst_pipeline_provide_clock_func (GST_ELEMENT (pipeline));
}