/* Element signals and args */
enum
{
- NEW_PAD,
+ PAD_ADDED,
PAD_REMOVED,
NO_MORE_PADS,
/* add more above */
*
* a new #GstPad has been added to the element.
*/
- gst_element_signals[NEW_PAD] =
+ gst_element_signals[PAD_ADDED] =
g_signal_new ("pad-added", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstElementClass, pad_added), NULL, NULL,
gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1, G_TYPE_OBJECT);
oclass = GST_ELEMENT_GET_CLASS (element);
+ /* if the element implements a custom release function we call that, else we
+ * simply remove the pad from the element */
if (oclass->release_pad)
(oclass->release_pad) (element, pad);
else
*
* Query if the element requires a clock.
*
- * Returns: TRUE if the element requires a clock
+ * Returns: %TRUE if the element requires a clock
*
* MT safe.
*/
*
* Query if the element provides a clock. A #GstClock provided by an
* element can be used as the global #GstClock for the pipeline.
+ * An element that can provide a clock is only required to do so in the PAUSED
+ * state, this means when it is fully negotiated and has allocated the resources
+ * to operate the clock.
*
- * Returns: TRUE if the element provides a clock
+ * Returns: %TRUE if the element provides a clock
*
* MT safe.
*/
* gst_element_provide_clock:
* @element: a #GstElement to query
*
- * Get the clock provided by the given element.
+ * Get the clock provided by the given element.
+ * <note>An element is only required to provide a clock in the PAUSED
+ * state. Some elements can provide a clock in other states.</note>
*
* Returns: the GstClock provided by the element or NULL
- * if no clock could be provided. Unref after usage.
+ * if no clock could be provided. Unref after usage.
*
* MT safe.
*/
* refcount on the clock. Any previously set clock on the object
* is unreffed.
*
- * Returns: TRUE if the element accepted the clock.
+ * Returns: %TRUE if the element accepted the clock. An element can refuse a
+ * clock when it, for example, is not able to slave its internal clock to the
+ * @clock or when it requires a specific clock to operate.
*
* MT safe.
*/
res = oclass->set_clock (element, clock);
if (res) {
+ /* only update the clock pointer if the element accepted the clock */
GST_OBJECT_LOCK (element);
clock_p = &element->clock;
gst_object_replace ((GstObject **) clock_p, (GstObject *) clock);
* gst_element_get_clock:
* @element: a #GstElement to get the clock of.
*
- * Gets the currently configured clock of the element.
+ * Gets the currently configured clock of the element. This is the clock as was
+ * last set with gst_element_set_clock().
*
* Returns: the #GstClock of the element. unref after usage.
*
gst_element_get_index (GstElement * element)
{
GstElementClass *oclass;
+ GstIndex *result = NULL;
g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
oclass = GST_ELEMENT_GET_CLASS (element);
if (oclass->get_index)
- return oclass->get_index (element);
+ result = oclass->get_index (element);
- return NULL;
+ return result;
}
#endif
*
* Pads are not automatically activated so elements should perform the needed
* steps to activate the pad in case this pad is added in the PAUSED or PLAYING
- * state.
+ * state. See gst_pad_set_active() for more information about activating pads.
*
* The pad and the element should be unlocked when calling this function.
*
- * Returns: TRUE if the pad could be added. This function can fail when
+ * This function will emit the #GstElement::pad-added signal on the element.
+ *
+ * Returns: %TRUE if the pad could be added. This function can fail when
* a pad with the same name already existed or the pad already had another
* parent.
*
element->pads_cookie++;
GST_OBJECT_UNLOCK (element);
- /* emit the NEW_PAD signal */
- g_signal_emit (G_OBJECT (element), gst_element_signals[NEW_PAD], 0, pad);
+ /* emit the PAD_ADDED signal */
+ g_signal_emit (element, gst_element_signals[PAD_ADDED], 0, pad);
return TRUE;
* @pad: the #GstPad to remove from the element.
*
* Removes @pad from @element. @pad will be destroyed if it has not been
- * referenced elsewhere.
+ * referenced elsewhere using gst_object_unparent().
*
* This function is used by plugin developers and should not be used
* by applications. Pads that were dynamically requested from elements
* with gst_element_get_request_pad() should be released with the
* gst_element_release_request_pad() function instead.
*
- * Returns: TRUE if the pad could be removed. Can return FALSE if the
- * pad is not belonging to the provided element.
+ * Pads are not automatically deactivated so elements should perform the needed
+ * steps to deactivate the pad in case this pad is removed in the PAUSED or PLAYING
+ * state. See gst_pad_set_active() for more information about deactivating pads.
+ *
+ * The pad and the element should be unlocked when calling this function.
+ *
+ * This function will emit the #GstElement::pad-removed signal on the element.
+ *
+ * Returns: %TRUE if the pad could be removed. Can return %FALSE if the
+ * pad does not belong to the provided element.
*
* MT safe.
*/
element->pads_cookie++;
GST_OBJECT_UNLOCK (element);
- g_signal_emit (G_OBJECT (element), gst_element_signals[PAD_REMOVED], 0, pad);
+ /* emit the PAD_REMOVED signal before unparenting and losing the last ref. */
+ g_signal_emit (element, gst_element_signals[PAD_REMOVED], 0, pad);
- gst_object_unparent (GST_OBJECT (pad));
+ gst_object_unparent (GST_OBJECT_CAST (pad));
return TRUE;
+ /* ERRORS */
not_our_pad:
{
/* FIXME, locking order? */
* pad templates use this in combination with autopluggers to figure out that
* the element is done initializing its pads.
*
+ * This function emits the #GstElement::no-more-pads signal.
+ *
* MT safe.
*/
void
* request pads. The pad should be released with
* gst_element_release_request_pad().
*
- * Returns: requested #GstPad if found, otherwise NULL. Unref after usage.
+ * Returns: requested #GstPad if found, otherwise NULL. Release after usage.
*/
GstPad *
gst_element_get_request_pad (GstElement * element, const gchar * name)
* Retrieves a pad from @element by name. Tries gst_element_get_static_pad()
* first, then gst_element_get_request_pad().
*
- * Returns: the #GstPad if found, otherwise %NULL. Unref after usage.
+ * <note>Usage of this function is not recommended as it is unclear if the reference
+ * to the result pad should be released with gst_object_unref() in case of a static pad
+ * or gst_element_release_request_pad() in case of a request pad.</note>
+ *
+ * Returns: the #GstPad if found, otherwise %NULL. Unref or Release after usage,
+ * depending on the type of the pad.
*/
GstPad *
gst_element_get_pad (GstElement * element, const gchar * name)
return NULL;
}
+/* get a random pad on element of the given direction.
+ * The pad is random in a sense that it is the first pad that is (optionaly) linked.
+ */
static GstPad *
-gst_element_get_random_pad (GstElement * element, GstPadDirection dir)
+gst_element_get_random_pad (GstElement * element, gboolean need_linked,
+ GstPadDirection dir)
{
GstPad *result = NULL;
GList *pads;
goto wrong_direction;
}
for (; pads; pads = g_list_next (pads)) {
- GstPad *pad = GST_PAD (pads->data);
+ GstPad *pad = GST_PAD_CAST (pads->data);
GST_OBJECT_LOCK (pad);
GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "checking pad %s:%s",
GST_DEBUG_PAD_NAME (pad));
- if (GST_PAD_IS_LINKED (pad)) {
+ if (need_linked && !GST_PAD_IS_LINKED (pad)) {
+ /* if we require a linked pad, and it is not linked, continue the
+ * search */
+ GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s is not linked",
+ GST_DEBUG_PAD_NAME (pad));
GST_OBJECT_UNLOCK (pad);
- result = pad;
- break;
+ continue;
} else {
- GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s is not linked",
+ /* found a pad, stop search */
+ GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "found pad %s:%s",
GST_DEBUG_PAD_NAME (pad));
+ GST_OBJECT_UNLOCK (pad);
+ result = pad;
+ break;
}
- GST_OBJECT_UNLOCK (pad);
}
if (result)
gst_object_ref (result);
* @element: a #GstElement to send the event to.
* @event: the #GstEvent to send to the element.
*
- * Sends an event to an element. If the element doesn't
- * implement an event handler, the event will be forwarded
- * to a random sink pad. This function takes owership of the
- * provided event so you should gst_event_ref() it if you want to reuse
- * the event after this call.
+ * Sends an event to an element. If the element doesn't implement an
+ * event handler, the event will be pushed on a random linked sink pad for
+ * upstream events or a random linked source pad for downstream events.
+ *
+ * This function takes owership of the provided event so you should
+ * gst_event_ref() it if you want to reuse the event after this call.
*
- * Returns: TRUE if the event was handled.
+ * Returns: %TRUE if the event was handled.
*
* MT safe.
*/
result = oclass->send_event (element, event);
} else {
GstPad *pad = GST_EVENT_IS_DOWNSTREAM (event) ?
- gst_element_get_random_pad (element, GST_PAD_SRC) :
- gst_element_get_random_pad (element, GST_PAD_SINK);
+ gst_element_get_random_pad (element, TRUE, GST_PAD_SRC) :
+ gst_element_get_random_pad (element, TRUE, GST_PAD_SINK);
if (pad) {
GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,
* @stop_type: The type and flags for the new stop position
* @stop: The value of the new stop position
*
- * Sends a seek event to an element.
+ * Sends a seek event to an element. See gst_event_new_seek() for the details of
+ * the parameters. The seek event is sent to the element using
+ * gst_element_send_event().
*
* Returns: %TRUE if the event was handled.
*
*
* Get an array of query types from the element.
* If the element doesn't implement a query types function,
- * the query will be forwarded to a random sink pad.
+ * the query will be forwarded to the peer of a random linked sink pad.
*
* Returns: An array of #GstQueryType elements that should not
* be freed or modified.
if (oclass->get_query_types) {
result = oclass->get_query_types (element);
} else {
- GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SINK);
+ GstPad *pad = gst_element_get_random_pad (element, TRUE, GST_PAD_SINK);
if (pad) {
GstPad *peer = gst_pad_get_peer (pad);
* @element: a #GstElement to perform the query on.
* @query: the #GstQuery.
*
- * Performs a query on the given element. If the format is set
- * to #GST_FORMAT_DEFAULT and this function returns TRUE, the
- * format pointer will hold the default format.
- * For element that don't implement a query handler, this function
- * forwards the query to a random usable sinkpad of this element.
+ * Performs a query on the given element.
+ *
+ * For elements that don't implement a query handler, this function
+ * forwards the query to a random srcpad or to the peer of a
+ * random linked sinkpad of this element.
*
* Returns: TRUE if the query could be performed.
*
GST_ELEMENT_NAME (element));
result = oclass->query (element, query);
} else {
- GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SRC);
+ GstPad *pad = gst_element_get_random_pad (element, FALSE, GST_PAD_SRC);
if (pad) {
result = gst_pad_query (pad, query);
gst_object_unref (pad);
} else {
- pad = gst_element_get_random_pad (element, GST_PAD_SINK);
+ pad = gst_element_get_random_pad (element, TRUE, GST_PAD_SINK);
if (pad) {
GstPad *peer = gst_pad_get_peer (pad);
* message; if you want to access the message after this call, you should add an
* additional reference before calling.
*
- * Returns: TRUE if the message was successfully posted.
+ * Returns: %TRUE if the message was successfully posted. The function returns
+ * %FALSE if the element did not have a bus.
*
* MT safe.
*/
gst_object_ref (bus);
GST_OBJECT_UNLOCK (element);
+ /* we release the element lock when posting the message so that any
+ * (synchronous) message handlers can operate on the element */
result = gst_bus_post (bus, message);
gst_object_unref (bus);
return result;
+ /* ERRORS */
no_bus:
{
GST_DEBUG ("not posting message %p: no bus", message);
has_debug = FALSE;
}
- name = gst_object_get_path_string (GST_OBJECT (element));
+ name = gst_object_get_path_string (GST_OBJECT_CAST (element));
if (has_debug)
sent_debug = g_strdup_printf ("%s(%d): %s (): %s:\n%s",
file, line, function, name, debug);
gerror = g_error_new_literal (domain, code, sent_text);
if (type == GST_MESSAGE_ERROR) {
- message = gst_message_new_error (GST_OBJECT (element), gerror, sent_debug);
+ message =
+ gst_message_new_error (GST_OBJECT_CAST (element), gerror, sent_debug);
} else if (type == GST_MESSAGE_WARNING) {
- message = gst_message_new_warning (GST_OBJECT (element), gerror,
+ message = gst_message_new_warning (GST_OBJECT_CAST (element), gerror,
sent_debug);
} else {
g_assert_not_reached ();
gst_element_state_get_name (old_next),
gst_element_state_get_name (pending));
- message = gst_message_new_state_changed (GST_OBJECT (element),
+ message = gst_message_new_state_changed (GST_OBJECT_CAST (element),
old_state, old_next, pending);
gst_element_post_message (element, message);
* We do signal the cond though as a _get_state() might be blocking
* on it. */
if (old_state != old_next || old_ret == GST_STATE_CHANGE_ASYNC) {
- message = gst_message_new_state_changed (GST_OBJECT (element),
+ message = gst_message_new_state_changed (GST_OBJECT_CAST (element),
old_state, old_next, GST_STATE_VOID_PENDING);
gst_element_post_message (element, message);
}
GST_STATE_RETURN (element) = GST_STATE_CHANGE_ASYNC;
GST_OBJECT_UNLOCK (element);
- message = gst_message_new_state_changed (GST_OBJECT (element),
+ message = gst_message_new_state_changed (GST_OBJECT_CAST (element),
current_state, current_state, current_state);
gst_element_post_message (element, message);
/* and mark us dirty */
- message = gst_message_new_state_dirty (GST_OBJECT (element));
+ message = gst_message_new_state_dirty (GST_OBJECT_CAST (element));
gst_element_post_message (element, message);
return;
pads = GST_ELEMENT_PADS (element);
while (pads) {
- GstPad *pad = GST_PAD (pads->data);
+ GstPad *pad = GST_PAD_CAST (pads->data);
/* figure out if it's a direct pad or a ghostpad */
if (GST_ELEMENT (GST_OBJECT_PARENT (pad)) == element) {
xmlNodePtr padtag = xmlNewChild (parent, NULL, (xmlChar *) "pad", NULL);
- gst_object_save_thyself (GST_OBJECT (pad), padtag);
+ gst_object_save_thyself (GST_OBJECT_CAST (pad), padtag);
}
pads = g_list_next (pads);
}
children = self->xmlChildrenNode;
while (children) {
if (!strcmp ((char *) children->name, "pad")) {
- gst_pad_load_and_link (children, GST_OBJECT (element));
+ gst_pad_load_and_link (children, GST_OBJECT_CAST (element));
}
children = children->next;
}
* </programlisting>
* </example>
*
- * Last reviewed on 2006-08-11 (0.10.10)
+ * Last reviewed on 2006-09-6 (0.10.10)
*/
*
* Allocate a new flush start event. The flush start event can be send
* upstream and downstream and travels out-of-bounds with the dataflow.
- * It marks pads as being in a WRONG_STATE to process more data.
+ *
+ * It marks pads as being flushing and will make them return
+ * #GST_FLOW_WRONG_STATE when used for data flow with gst_pad_push(),
+ * gst_pad_chain(), gst_pad_alloc_buffer(), gst_pad_get_range() and
+ * gst_pad_pull_range(). Any event (except a #GST_EVENT_FLUSH_STOP) received
+ * on a flushing pad will return %FALSE immediatly.
*
* Elements unlock and blocking functions and exit their streaming functions
* as fast as possible.
*
* Create a new EOS event. The eos event can only travel downstream
* synchronized with the buffer flow. Elements that receive the EOS
- * event on a pad can return UNEXPECTED as a GstFlowReturn when data
- * after the EOS event arrives.
+ * event on a pad can return #GST_FLOW_UNEXPECTED as a #GstFlowReturn
+ * when data after the EOS event arrives.
*
* The EOS event will travel down to the sink elements in the pipeline
- * which will then post the GST_MESSAGE_EOS on the bus after they have
+ * which will then post the #GST_MESSAGE_EOS on the bus after they have
* finished playing any buffered data.
*
* When all sinks have posted an EOS message, the EOS message is
* Create a new buffersize event. The event is sent downstream and notifies
* elements that they should provide a buffer of the specified dimensions.
*
- * When the async flag is set, a thread boundary is prefered.
+ * When the @async flag is set, a thread boundary is prefered.
*
* Returns: a new #GstEvent
*/
* Allocate a new seek event with the given parameters.
*
* The seek event configures playback of the pipeline from
- * @cur to @stop at the speed given in @rate, also called a segment.
+ * @cur to @stop at the speed given in @rate, also called a playback segment.
* The @cur and @stop values are expressed in format @format.
*
* A @rate of 1.0 means normal playback rate, 2.0 means double speed.
* Negatives values means backwards playback. A value of 0.0 for the
- * rate is not allowed.
+ * rate is not allowed and should be accomplished instead by PAUSING the
+ * pipeline.
+ *
+ * A pipeline has a default playback segment configured with a current
+ * position of 0, a stop position of the total duration of the stream(s) and
+ * a rate of 1.0. The currently configured playback segment can be queried
+ * with #GST_QUERY_SEGMENT.
*
* @cur_type and @stop_type specify how to adjust the current and stop
- * time, relative or absolute to the last configured positions. A type
+ * time, relative or absolute to the last configured playback segment. A type
* of #GST_SEEK_TYPE_NONE means that the position should not be updated.
- * The currently configured playback segment can be queried with
- * #GST_QUERY_SEGMENT.
- *
- * Note that updating the @cur position will actually move the current
- * playback pointer to that new position. It is not possible to seek
- * relative to the current playing position, to do this, pause the pipeline,
- * get the current position and perform a GST_SEEK_TYPE_SET to the desired
- * position.
+ *
+ * Updating the @cur position will actually move the current playback position
+ * to that new position.
+ *
+ * It is not possible to seek relative to the current playback position, to do
+ * this, PAUSE the pipeline, query the current playback position with
+ * #GST_QUERY_POSITION and update the playback segment current position with a
+ * #GST_SEEK_TYPE_SET to the desired position.
*
* Returns: A new seek event.
*/