aggregator: Use standard upstream latency querying logic

The same functionality is duplicated in the default latency querying
now.
This commit is contained in:
Arun Raghavan 2015-02-27 00:26:00 +05:30 committed by Tim-Philipp Müller
parent 5ac166a5d9
commit b7155695f8

View file

@ -1110,133 +1110,58 @@ gst_aggregator_request_new_pad (GstElement * element,
return GST_PAD (agg_pad); return GST_PAD (agg_pad);
} }
typedef struct
{
GstClockTime min, max;
gboolean live;
} LatencyData;
static gboolean
query_upstream_latency_fold (const GValue * item, GValue * ret,
gpointer user_data)
{
GstPad *pad = g_value_get_object (item);
LatencyData *data = user_data;
GstClockTime min, max;
GstQuery *query;
gboolean live, res;
query = gst_query_new_latency ();
res = gst_pad_peer_query (GST_PAD_CAST (pad), query);
if (res) {
gst_query_parse_latency (query, &live, &min, &max);
GST_LOG_OBJECT (pad, "got latency live:%s min:%" G_GINT64_FORMAT
" max:%" G_GINT64_FORMAT, live ? "true" : "false", min, max);
if (live) {
if (min > data->min)
data->min = min;
if (data->max == GST_CLOCK_TIME_NONE)
data->max = max;
else if (max < data->max)
data->max = max;
data->live = TRUE;
}
} else {
GST_LOG_OBJECT (pad, "latency query failed");
g_value_set_boolean (ret, FALSE);
}
gst_query_unref (query);
return TRUE;
}
static gboolean static gboolean
gst_aggregator_query_latency (GstAggregator * self, GstQuery * query) gst_aggregator_query_latency (GstAggregator * self, GstQuery * query)
{ {
GstIterator *it; gboolean query_ret, live;
GstIteratorResult res; GstClockTime our_latency, min, max;
GValue ret = G_VALUE_INIT;
gboolean query_ret;
LatencyData data;
GstClockTime our_latency;
it = gst_element_iterate_sink_pads (GST_ELEMENT_CAST (self)); query_ret = gst_pad_query_default (self->srcpad, GST_OBJECT (self), query);
g_value_init (&ret, G_TYPE_BOOLEAN);
retry:
data.min = 0;
data.max = GST_CLOCK_TIME_NONE;
data.live = FALSE;
g_value_set_boolean (&ret, TRUE);
/* query upstream's latency */
res = gst_iterator_fold (it, query_upstream_latency_fold, &ret, &data);
switch (res) {
case GST_ITERATOR_OK:
g_assert_not_reached ();
break;
case GST_ITERATOR_DONE:
break;
case GST_ITERATOR_ERROR:
g_value_set_boolean (&ret, FALSE);
break;
case GST_ITERATOR_RESYNC:
gst_iterator_resync (it);
goto retry;
default:
g_assert_not_reached ();
break;
}
gst_iterator_free (it);
query_ret = g_value_get_boolean (&ret);
if (!query_ret) { if (!query_ret) {
GST_WARNING_OBJECT (self, "Latency query failed"); GST_WARNING_OBJECT (self, "Latency query failed");
return FALSE; return FALSE;
} }
gst_query_parse_latency (query, &live, &min, &max);
SRC_LOCK (self); SRC_LOCK (self);
our_latency = self->priv->latency; our_latency = self->priv->latency;
if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (data.min))) { if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (min))) {
GST_WARNING_OBJECT (self, "Invalid minimum latency, using 0"); GST_WARNING_OBJECT (self, "Invalid minimum latency, using 0");
data.min = 0; min = 0;
} }
if (G_UNLIKELY (data.min > data.max)) { if (G_UNLIKELY (min > max)) {
GST_WARNING_OBJECT (self, "Minimum latency is greater than maximum latency " GST_WARNING_OBJECT (self, "Minimum latency is greater than maximum latency "
"(%" G_GINT64_FORMAT " > %" G_GINT64_FORMAT "). " "(%" G_GINT64_FORMAT " > %" G_GINT64_FORMAT "). "
"Clamping it at the maximum latency", data.min, data.max); "Clamping it at the maximum latency", min, max);
data.min = data.max; min = max;
} }
self->priv->latency_live = data.live; self->priv->latency_live = live;
self->priv->latency_min = data.min; self->priv->latency_min = min;
self->priv->latency_max = data.max; self->priv->latency_max = max;
/* add our own */ /* add our own */
data.min += our_latency; min += our_latency;
data.min += self->priv->sub_latency_min; min += self->priv->sub_latency_min;
if (GST_CLOCK_TIME_IS_VALID (self->priv->sub_latency_max) if (GST_CLOCK_TIME_IS_VALID (self->priv->sub_latency_max)
&& GST_CLOCK_TIME_IS_VALID (data.max)) && GST_CLOCK_TIME_IS_VALID (max))
data.max += self->priv->sub_latency_max; max += self->priv->sub_latency_max;
else else
data.max = GST_CLOCK_TIME_NONE; max = GST_CLOCK_TIME_NONE;
if (data.live && data.min > data.max) { if (live && min > max) {
GST_ELEMENT_WARNING (self, CORE, NEGOTIATION, GST_ELEMENT_WARNING (self, CORE, NEGOTIATION,
("%s", "Latency too big"), ("%s", "Latency too big"),
("The requested latency value is too big for the current pipeline. " ("The requested latency value is too big for the current pipeline. "
"Limiting to %" G_GINT64_FORMAT, data.max)); "Limiting to %" G_GINT64_FORMAT, max));
data.min = data.max; min = max;
/* FIXME: This could in theory become negative, but in /* FIXME: This could in theory become negative, but in
* that case all is lost anyway */ * that case all is lost anyway */
self->priv->latency -= data.min - data.max; self->priv->latency -= min - max;
/* FIXME: shouldn't we g_object_notify() the change here? */ /* FIXME: shouldn't we g_object_notify() the change here? */
} }
@ -1244,10 +1169,9 @@ retry:
SRC_UNLOCK (self); SRC_UNLOCK (self);
GST_DEBUG_OBJECT (self, "configured latency live:%s min:%" G_GINT64_FORMAT GST_DEBUG_OBJECT (self, "configured latency live:%s min:%" G_GINT64_FORMAT
" max:%" G_GINT64_FORMAT, data.live ? "true" : "false", data.min, " max:%" G_GINT64_FORMAT, live ? "true" : "false", min, max);
data.max);
gst_query_set_latency (query, data.live, data.min, data.max); gst_query_set_latency (query, live, min, max);
return query_ret; return query_ret;
} }