*/
/**
* SECTION:gstpad
+ * @title: GstPad
* @short_description: Object contained by elements that allows links to
* other elements
* @see_also: #GstPadTemplate, #GstElement, #GstEvent, #GstQuery, #GstBuffer
{
gint64 offset;
- GST_DEBUG_OBJECT (pad, "apply pad offset %" GST_TIME_FORMAT,
- GST_TIME_ARGS (pad->offset));
+ GST_DEBUG_OBJECT (pad, "apply pad offset %" GST_STIME_FORMAT,
+ GST_STIME_ARGS (pad->offset));
if (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT) {
GstSegment segment;
GstPad *pad = GST_PAD_CAST (object);
GstPad *peer;
- GST_CAT_DEBUG_OBJECT (GST_CAT_REFCOUNTING, pad, "dispose");
+ GST_CAT_DEBUG_OBJECT (GST_CAT_REFCOUNTING, pad, "%p dispose", pad);
/* unlink the peer pad */
if ((peer = gst_pad_get_peer (pad))) {
if (G_UNLIKELY (!activate_mode_internal (pad, parent, old, FALSE)))
goto deactivate_failed;
+ old = GST_PAD_MODE_NONE;
}
switch (mode) {
g_return_val_if_fail (GST_PAD_IS_SINK (sinkpad),
GST_PAD_LINK_WRONG_DIRECTION);
+ GST_TRACER_PAD_LINK_PRE (srcpad, sinkpad);
+
/* Notify the parent early. See gst_pad_unlink for details. */
if (G_LIKELY ((parent = GST_ELEMENT_CAST (gst_pad_get_parent (srcpad))))) {
if (G_LIKELY (GST_IS_ELEMENT (parent))) {
GST_CAT_INFO (GST_CAT_PADS, "linked %s:%s and %s:%s, successful",
GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad));
- gst_pad_send_event (srcpad, gst_event_new_reconfigure ());
+ if (!(flags & GST_PAD_LINK_CHECK_NO_RECONFIGURE))
+ gst_pad_send_event (srcpad, gst_event_new_reconfigure ());
done:
if (G_LIKELY (parent)) {
gst_object_unref (parent);
}
+ GST_TRACER_PAD_LINK_POST (srcpad, sinkpad, result);
return result;
/* ERRORS */
GstPadLinkReturn
gst_pad_link (GstPad * srcpad, GstPad * sinkpad)
{
- GstPadLinkReturn ret;
-
- GST_TRACER_PAD_LINK_PRE (srcpad, sinkpad);
- ret = gst_pad_link_full (srcpad, sinkpad, GST_PAD_LINK_CHECK_DEFAULT);
- GST_TRACER_PAD_LINK_POST (srcpad, sinkpad, ret);
-
- return ret;
+ return gst_pad_link_full (srcpad, sinkpad, GST_PAD_LINK_CHECK_DEFAULT);
}
static void
/* Query peer caps */
query = gst_query_new_caps (mycaps);
- gst_pad_peer_query (pad, query);
+ if (!gst_pad_peer_query (pad, query)) {
+ GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad, "Caps query failed");
+ goto end;
+ }
+
gst_query_parse_caps_result (query, &caps);
+ if (caps == NULL) {
+ g_warn_if_fail (caps != NULL);
+ goto end;
+ }
gst_caps_ref (caps);
- gst_query_unref (query);
-
- gst_caps_unref (mycaps);
GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad, "allowed caps %" GST_PTR_FORMAT,
caps);
+end:
+ gst_query_unref (query);
+ gst_caps_unref (mycaps);
+
return caps;
no_peer:
gst_query_parse_accept_caps (query, &caps);
if (!allowed) {
- GST_CAT_DEBUG_OBJECT (GST_CAT_PERFORMANCE, pad,
- "fallback ACCEPT_CAPS query, consider implementing a specialized version");
- if (GST_PAD_IS_ACCEPT_TEMPLATE (pad))
+ if (GST_PAD_IS_ACCEPT_TEMPLATE (pad)) {
allowed = gst_pad_get_pad_template_caps (pad);
- else
+ } else {
+ GST_CAT_DEBUG_OBJECT (GST_CAT_PERFORMANCE, pad,
+ "fallback ACCEPT_CAPS query, consider implementing a specialized version");
allowed = gst_pad_query_caps (pad, caps);
+ }
}
if (allowed) {
/* Default latency implementation */
typedef struct
{
+ guint count;
gboolean live;
GstClockTime min, max;
} LatencyFoldData;
GST_LOG_OBJECT (pad, "got latency live:%s min:%" G_GINT64_FORMAT
" max:%" G_GINT64_FORMAT, live ? "true" : "false", min, max);
- if (live) {
+ /* FIXME : Why do we only take values into account if it's live ? */
+ if (live || fold_data->count == 0) {
if (min > fold_data->min)
fold_data->min = min;
else if (max < fold_data->max)
fold_data->max = max;
- fold_data->live = TRUE;
+ fold_data->live = live;
}
+ fold_data->count += 1;
} else if (peer) {
GST_DEBUG_OBJECT (pad, "latency query failed");
g_value_set_boolean (ret, FALSE);
g_value_init (&ret, G_TYPE_BOOLEAN);
retry:
+ fold_data.count = 0;
fold_data.live = FALSE;
fold_data.min = 0;
fold_data.max = GST_CLOCK_TIME_NONE;
type = info->type;
original_data = info->data;
- /* one of the data types for non-idle probes */
- if ((type & GST_PAD_PROBE_TYPE_IDLE) == 0
- && (flags & _PAD_PROBE_TYPE_ALL_BOTH_AND_FLUSH & type) == 0)
- goto no_match;
/* one of the scheduling types */
if ((flags & GST_PAD_PROBE_TYPE_SCHEDULING & type) == 0)
goto no_match;
+
+ if (type & GST_PAD_PROBE_TYPE_PUSH) {
+ /* one of the data types for non-idle probes */
+ if ((type & GST_PAD_PROBE_TYPE_IDLE) == 0
+ && (flags & _PAD_PROBE_TYPE_ALL_BOTH_AND_FLUSH & type) == 0)
+ goto no_match;
+ } else if (type & GST_PAD_PROBE_TYPE_PULL) {
+ /* one of the data types for non-idle probes */
+ if ((type & GST_PAD_PROBE_TYPE_BLOCKING) == 0
+ && (flags & _PAD_PROBE_TYPE_ALL_BOTH_AND_FLUSH & type) == 0)
+ goto no_match;
+ } else {
+ /* Type must have PULL or PUSH probe types */
+ g_assert_not_reached ();
+ }
+
/* one of the blocking types must match */
if ((type & GST_PAD_PROBE_TYPE_BLOCKING) &&
(flags & GST_PAD_PROBE_TYPE_BLOCKING & type) == 0)
goto done;
pad->offset = offset;
- GST_DEBUG_OBJECT (pad, "changed offset to %" G_GINT64_FORMAT, offset);
+ GST_DEBUG_OBJECT (pad, "changed offset to %" GST_STIME_FORMAT,
+ GST_STIME_ARGS (offset));
/* resend all sticky events with updated offset on next buffer push */
events_foreach (pad, mark_event_not_received, NULL);
/* Unset the EOS flag when received STREAM_START event, so pad can
* store sticky event and then push it later */
if (type == GST_EVENT_STREAM_START) {
- GST_LOG_OBJECT (pad, "Removing pending EOS events");
+ GST_LOG_OBJECT (pad, "Removing pending EOS and StreamGroupDone events");
remove_event_by_type (pad, GST_EVENT_EOS);
+ remove_event_by_type (pad, GST_EVENT_STREAM_GROUP_DONE);
GST_OBJECT_FLAG_UNSET (pad, GST_PAD_FLAG_EOS);
}
/**
* gst_pad_store_sticky_event:
* @pad: a #GstPad
- * @event: a #GstEvent
+ * @event: (transfer none): a #GstEvent
*
* Store the sticky @event on @pad
*
/* Remove sticky EOS events */
GST_LOG_OBJECT (pad, "Removing pending EOS events");
remove_event_by_type (pad, GST_EVENT_EOS);
+ remove_event_by_type (pad, GST_EVENT_STREAM_GROUP_DONE);
remove_event_by_type (pad, GST_EVENT_SEGMENT);
GST_OBJECT_FLAG_UNSET (pad, GST_PAD_FLAG_EOS);
pad->ABI.abi.last_flowret = GST_FLOW_OK;
/* Remove pending EOS events */
GST_LOG_OBJECT (pad, "Removing pending EOS and SEGMENT events");
remove_event_by_type (pad, GST_EVENT_EOS);
+ remove_event_by_type (pad, GST_EVENT_STREAM_GROUP_DONE);
remove_event_by_type (pad, GST_EVENT_SEGMENT);
GST_OBJECT_FLAG_UNSET (pad, GST_PAD_FLAG_EOS);
pad->ABI.abi.last_flowret = GST_FLOW_OK;
/* Remove sticky EOS events */
GST_LOG_OBJECT (pad, "Removing pending EOS events");
remove_event_by_type (pad, GST_EVENT_EOS);
+ remove_event_by_type (pad, GST_EVENT_STREAM_GROUP_DONE);
GST_OBJECT_FLAG_UNSET (pad, GST_PAD_FLAG_EOS);
break;
default:
}
/**
+ * gst_pad_get_task_state:
+ * @pad: the #GstPad to get task state from
+ *
+ * Get @pad task state. If no task is currently
+ * set, #GST_TASK_STOPPED is returned.
+ *
+ * Returns: The current state of @pad's task.
+ *
+ * Since: 1.12
+ */
+GstTaskState
+gst_pad_get_task_state (GstPad * pad)
+{
+ GstTask *task;
+ GstTaskState res;
+
+ g_return_val_if_fail (GST_IS_PAD (pad), GST_TASK_STOPPED);
+
+ GST_OBJECT_LOCK (pad);
+ task = GST_PAD_TASK (pad);
+ if (task == NULL)
+ goto no_task;
+ res = gst_task_get_state (task);
+ GST_OBJECT_UNLOCK (pad);
+
+ return res;
+
+no_task:
+ {
+ GST_DEBUG_OBJECT (pad, "pad has no task");
+ GST_OBJECT_UNLOCK (pad);
+ return GST_TASK_STOPPED;
+ }
+}
+
+/**
* gst_pad_stop_task:
* @pad: the #GstPad to stop the task of
*